Vue 1.0到2.0的变化:
1、在每个组件的模板中,不再支持片段代码
组件中的模板:
之前:
<template>
<h3我是组件<strong>我是加粗模板</strong></h3>
</template>
现在:必须有根元素包裹住所有代码
2、关于组件定义
Vue.extend 这种方式,在2.0里有一些改动,这种写法即使能用也不用
Vue.component(组件名称,{
data(){},
methods:{},
template:
}) 这种方式继续使用
2.0推出一个组件简介方式:
<template id="aaa"> <div> <h4>这是组件</h4> <strong>加粗模板</strong> </div> </template> <script src="./bower_components/vue/dist/vue.js"></script> <script> var Home = { template:'#aaa' };//定义一个json列表 Vue.component('my-aaa',Home);//引入这个json用来定义组件 window.onload = function () { new Vue({ el: '#app', data: { msg: 'welcome vue2.0 ' } }) } </script>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <my-aaa></my-aaa> {{msg}} </div> <template id="aaa"> <div> <h4>这是组件</h4> <strong>加粗模板</strong> </div> </template> <script src="./bower_components/vue/dist/vue.js"></script> <script> var Home = { template:'#aaa' };//定义一个json列表 window.onload = function () { new Vue({ el: '#app', data: { msg: 'welcome vue2.0 ' }, components:{ 'my-aaa':Home } }) } </script> </body> </html>
3、生命周期:
之前:
init
created
beforeCompile
compiled
ready 平时用的最多
beforeDestroy
destroyed
现在:
beforeCreate 组件实例刚被创建,属性都没有
created 实例已经创建完成,属性已经绑定
beforeMount 模板编译之前
mounted 对应之前的compiled和ready两个状态,模板编译之后
beforeUpdate 组件更新之前
updated 组件更新完毕
beforeDestroy 组件销毁前
destroyed 组件销毁后
4、2.0循环
2.0里默认就能添加重复的数据
去掉了隐式的变量
$index $key
之前:
v-for='(index, value) in arrary'
现在:
v-for='(valune, index) in arrary'
track-by=‘index’:
之前:
track-by=‘index’
现在:
:key=‘index’
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <input type="button" value="添加" @click="add"> <ul> <li v-for="(val, index) in arr" :key="index">{{index}} -> {{val}}</li> </ul> </div> <script src="./vue.js"></script> <script> window.onload=function () { new Vue({ el:'#app', data:{ arr:['banana','apple','pear'] }, methods:{ add:function () { this.arr.push('新加') console.log(this.arr) } } }) } </script> </body> </html>
4、自定义键盘指令
之前:
Vue.directive('on').keyCodes.f1=112;
现在:
Vue.configkeyCodes.ctrl=17;
5、过滤器
之前:
系统自带很多过滤器:
{{msg|currency}}
{{msg|json}}#到了2.0 json格式直接转换,不需要过滤器
现在:内置过滤器全部删除
lodash 工具库 .debounce(fn,200)
自定义过滤器:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> {{msg|toDou}} </div> <script src="./vue.js"></script> <script> Vue.filter('toDou',function (e) { return e<10?'0'+e:e; }); window.onload=function () { new Vue({ el:'#app', data:{ msg: 9 }, }) } </script> </body> </html>
自定义过滤器的传参发生变化:
{{msg|toDou(2,3)}}
6、组件通信:
vm.$emit()
vm.$on()
父组件和子组件:
子组件想要拿到父组件的数据:
props:['a']
之前,子组件可以更改父组件信息而且是同步的
现在,不允许直接修改父组件
如果想更改:
1、父组件每次传一个对象给子组件,对象之间是引用关系
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <template id="child"> <div> <h3>我是子组件</h3> <input type="button" value="按钮" @click="change"> {{msg.a}} </div> </template> <div id="app"> {{giveData.a}} <child-com :msg="giveData"></child-com> </div> <script src="./vue.js"></script> <script> window.onload = function () { new Vue({ el: '#app', data: { giveData: { a: '我是父组件的数据' } }, components: { 'child-com': { props: ['msg'], template: '#child', methods: { change() { this.msg.a = '被更改了' } } } } }) } </script> </body> </html>
7、单一事件管理组件通信:
var vm = new Vue();
vm.$emit(事件名称,数据)
vm.$on(事件名称,function(){}.bind(this));
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <com-a></com-a> <com-b></com-b> <com-c></com-c> </div> <script src="./vue.js"></script> <script> //准备一个空的实例对象 var vm = new Vue() var A = { data() { return { a: 'A组件数据' } }, template: '<div><h3>我是A组件</h3>->{{a}}' + '<br>' + '<input type=\'button\' value=\'A组件传递给C组件\' @click="send">' + '</div>', methods: { send: function () { vm.$emit('a-msg', this.a); } } }; var B = { data() { return { a: 'B组件数据' } }, template: '<div><h3>我是B组件</h3>->{{a}}<br><input type=\'button\' value=\'B组件传递给C组件\' @click="send"></div>', methods: { send: function () { vm.$emit('b-msg', this.a); } } }; var C = { data(){ return{ a:'', b:'' }; }, template: '<div>' + '<h3>我是C组件</h3>' + '<span>接收过来的a的数据:{{a}}</span>' + '<br>'+ '<span>接收过来的a的数据:{{b}}</span>'+ '</div>', mounted() { //接收a组件数据 vm.$on('a-msg',function (a) { this.a=a; }.bind(this)); //接收b组件数据 vm.$on('b-msg',function (a) { this.b=a; }.bind(this)); } }; window.onload = function () { new Vue({ el: '#app', components: { 'com-a': A, 'com-b': B, 'com-c': C } }) } </script> </body> </html>
8、动画
transition之前属性
2.0后transition以组件形式存在
<transition>
运动的东西(元素、属性、路由....)
</transition>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="animate.css"> <!--引入animate类--> <style> p{ width:100px; height:100px; background:red; margin:0 auto; } </style> </head> <body> <div id="app"> <input type="button" value="点击显示隐藏" @click="change"> <!--在transition标签上定义动作--> <transition enter-active-class="bounceInLeft" leave-active-class="bounceOutRight"> <!--在具体实现的标签上定义animated类型--> <p v-show="show" class="animated"></p> </transition> <!--<transition >--> <!--<p v-show="show"></p>--> <!--</transition>--> </div> <script src="./vue.js"></script> <script> window.onload = function () { new Vue({ el: '#app', data:{ show:false }, methods:{ change(){ this.show=this.show?false:true } } }) } </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="animate.css"> <!--引入animate类--> <style> p{ width:100px; height:100px; background:red; margin:10px auto; } </style> </head> <body> <div id="app"> <input type="button" value="点击显示隐藏" @click="change"> <!--如果多个元素运动,需要使用transition-group,同时在里面必须使用key--> <transition-group enter-active-class="bounceInLeft" leave-active-class="bounceOutRight"> <!--在具体实现的标签上定义animated类型--> <p v-show="show" class="animated" :key="1"></p> <p v-show="show" class="animated" :key="2"></p> </transition-group> </div> <script src="./vue.js"></script> <script> window.onload = function () { new Vue({ el: '#app', data:{ show:false; list:['apple','banana','orange','pear'] }, methods:{ change(){ this.show=this.show?false:true } } }) } </script> </body> </html>
9、vue-router
<div> <router-link to="/home">主页</router-link> <router-link to="/news">新闻</router-link> </div> <div> <router-view></router-view> </div>
<script> //组件 var Home={ template:'<h3>我是主页</h3>' }; var News = { template:'<h3>我是新闻页</h3>' }; //配置路由 const routes = [ {path:'/home',component:Home}, {path:'/news',component:News} ]; //生成路由实例 const router = new VueRouter({ routes }); //挂载vue上 new Vue({ el:'#app', router }) </script>
如果需要重定向:
const routes = [
{path:'/home',component:Home},
{path:'/news',component:News},
{path:'/',redirect:'/home'}
];
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="../vue.js"></script> <script src="../bower_components/vue-router/dist/vue-router.js"></script> </head> <body> <div id="app"> <div> <router-link to="/home">主页</router-link> <router-link to="/user">用户</router-link> </div> <div> <router-view></router-view> </div> </div> <script> //组件 var Home={ template:'<h3>我是主页</h3>' }; var User = { template: '<div>' + '<ul>' + '<li><router-link to="/user/gavin/age/10">gavin</router-link></li>' + '<li><router-link to="/user/blue/age/70">blue</router-link></li>' + '<li><router-link to="/user/eric/age/50">eric</router-link></li>' + '</ul>' + '<div><router-view></router-view></div>' + '</div>' }; var UserDetail={ template:'<div>{{$route.params}}</div>' } //配置路由 const routes = [ {path:'/home',component:Home}, { path:'/user', component:User, children:[ {path:':username/age/:age',component:UserDetail} ] }, {path:'/',redirect:'/home'} ]; //生成路由实例 const router = new VueRouter({ routes }); //挂载vue上 new Vue({ el:'#app', router }) </script> </body> </html>
路由实例方法:
router.push({path:'home'})//直接添加一个路由,表现为切换路由,本质是添加一个历史记录,history
router.replace({path:'user'}) //替换路由,可以在不刷新的情况进行切换,不会往历史记录里添加
路由配合动画:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="../animate.css"> <script src="../vue.js"></script> <script src="../bower_components/vue-router/dist/vue-router.js"></script> </head> <body> <div id="app"> <div> <router-link to="/home">主页</router-link> <router-link to="/user">用户</router-link> </div> <div> <transition enter-active-class="bounceInLeft" leave-active-class="bounceOutRight"> <router-view class="animated"></router-view> </transition> </div> </div> <script> //组件 var Home={ template:'<h3>我是主页</h3>' }; var User = { template: '<div>' + '<ul>' + '<li><router-link to="/user/gavin/age/10">gavin</router-link></li>' + '<li><router-link to="/user/blue/age/70">blue</router-link></li>' + '<li><router-link to="/user/eric/age/50">eric</router-link></li>' + '</ul>' + '<div><router-view></router-view></div>' + '</div>' }; var UserDetail={ template:'<div>{{$route.params}}</div>' } //配置路由 const routes = [ {path:'/home',component:Home}, { path:'/user', component:User, children:[ {path:':username/age/:age',component:UserDetail} ] }, {path:'/',redirect:'/home'} ]; //生成路由实例 const router = new VueRouter({ routes }); //挂载vue上 new Vue({ el:'#app', router }) </script> </body> </html>
10、2.0脚手架
vue-cli提供一个基本的项目结构
本身集成的项目模板:
1、webpack
2、webpack-simple
3、browserify
4、browserify-simple
5、simple
基本使用流程:
1、cnpm install vue-cli -g 安装vue命令环境
验证安装ok? vue --version
2、生成项目模板:
vue init <模板名> <本地文件夹名称>
例子: vue init simple#1.0 vue-simple-demo #simple是简单模板,1.0表示vue 1.0版本
3、进入到生成目录里面
cnpm install
4、npm run dev
在src/main.js中
new Vue({
el: '#app',
render: h => h(App)
})
vue2.0
vue-loader和vue-router配合
11、UI组件
包管理工具:
bower 前端包管理工具 可以自行解决依赖
webpack 后端包管理工具
使用UI:
目的:提高开发效率
原则:拿过来直接用
饿了么团队开源一个基于Vue组件库
elementUi PC端
MintUI 移动端
安装:
npm i element-ui -S
引入:
#App.vue文件中引入
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
修改配置:
#webpack.config.js文件中
{
test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
按需引入:
1、安装:
npm install babel-plugin-component -D
2、修改babelrc文件:
{
"presets": [
["es2015", { "modules": false }]
],
"plugins": [["component", [
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]]]
}
引入希望引入的组件:
import { Button, Select } from 'element-ui'
Vue.use(Button)
Vue.use(Select)
14、axios:
官方推荐的交互组件
安装:
cnpm i axios -D
备注:
自己定义的组件需要加事件,需要:
<my-buuton @click.native="get"></my-button> //my-button是自己定义的组件,这个组件如果想绑定事件,需要加native才可以
//方法等同于vue.resource
methods:{
get(){
axios.get('a.txt').then(function(res){
this.myMessage=res.data;
},bind(this)).catch(){function(err){
console.log(err);
}}
}
}
Mint:
http://mint-ui.github.io/docs/#/zh-cn2
15、自定义全局Vue组件:
使用:
例子:定义<Loading></Loading>
如何需要引入,需要在main.js里引入:
import Loading from './components/loading'
Vue.use(Loading)
新建一个组件:文件夹loading包含两个文件,一个loading.vue一个index.js
loading.vue中:
<template>
<div class="loading-box">
Loading........
</div>
</template>
index.js中:
import LoadingComponent from './loading.vue'
const Loading={
install:function(Vue){
Vue.component('Loading',LoadingComponent)
}
};
export default Loading
16、vuex
集中式管理数据
官网:http://vuex.vuejs.ort
vuex提供两个非常靠谱方法:
mapActions:管理所有事件(行为)
mapGetters:获取数据
1、安装:
cnpm i vuex -D