首页 > 代码库 > vue.js 常用语法总结(一)

vue.js 常用语法总结(一)

作者:曾萍,目前就职于京东商城。

概述
2016年已经结束了。你是否会思考一下,自己在过去的一年里是否错过一些重要的东西?不用担心,我们正在回顾那些流行的趋势。
通过比较过去12个月里Github所增加的star数,我们利用bestof.js.org分析所涉及的项目技术,发现2016最流行项目有以下这些:
图片
通过比较去年最火的10个项目,你可以总览2016的web前端技术发展,会发现:
Vue.js在去年获得了超过25000个star,这意味着每天有72个star,超过了包含React以及Angular在内的其它任何框架。
但是,相信大多数开始接触Vue.js的学习者和笔者一样,面对Vue.js如此多的API方法头晕目,所以笔者为大家整理了一下Vue.js的属性与方法,
方便大家回顾(目前是第一部分的內容,下篇會將后継的補充完善)!

一、起步
1、v-model(绑定数据)
2、v-for(循环)
3、v-on(绑定事件)
4、data(数据)
5、methods(方法)
6、$index(索引)

二、概述
1、data(绑定 DOM 文本到数据)
2、v-if(不满足条件的话则不会出现在dom中)
3、v-show(不满足条件,则样式会设置成隐藏 display:none;)
4、组件
eg:
<div id="app3">
<app-nav></app-nav> <!--导航-->
<app-view>
<app-sidebar></app-sidebar> <!--侧边栏-->
<app-content></app-content> <!--展示内容-->
</app-view>
</div>
<script type="text/javascript">
var vm2=new Vue({
el:"#app2",
data:data2
});
</script>

三、Vue实例
1、构造器:Vue.extend
2、数据属性:vm.a
3、实例属性和方法:
1)vm.$el
2)vm.$data
3)vm.$watch
4)实例生命周期
eg:
var vm4 = new Vue({
data: {
a: 1
},
beforeCreate:function(){
//创建前
},
created: function(){
console.log(‘a is: ‘ + this.a); // `this` 指向 vm 实例
},
beforeMount:function(){
//加载前
},
mounted:function(){
//加载后
},
beforeUpdate:function(){
//更新前
},
updated:function(){
//更新后
},
beforeDestroy:function(){
//销毁前
},
destroyed:function() {
//销毁后
}
});

四、数据绑定语法
1、文本插值:
{{msg}}
2、单次绑定:
v-once {{msg}}
3、纯HTML:
v-html
4、绑定表达式:
{{number+1}}
5、过滤器:
{{ message | filterA | filterB }}、{{ message | filterA ‘arg1‘ arg2 }}
6、指令:
<p v-if="greeting">Hello!</p>
带参数的指令:
<a v-bind:href="http://www.mamicode.com/url"></a>
<a v-on:click="doSomething"></a>
带修饰符的指令:
<a v-bind:href.literal="/a/b/c"></a>
指令缩写:
<a v-bind:href="http://www.mamicode.com/url"></a> -> <a :href="http://www.mamicode.com/url"></a>
<button v-bind:disabled="someDynamicCondition">Button</button> -> <button :disabled="someDynamicCondition">Button</button>
<a v-on:click="doSomething"></a> -> <a @click="doSomething"></a>

五、Vue实例
1、构造器:
var data = http://www.mamicode.com/{ a: 1 };
var vm6 = new Vue({ //每个 Vue.js 应用的起步都是通过构造函数 Vue 创建一个 Vue 的根实例
el: ‘#example‘,
data: data,

beforeCreate:function(){}, //创建前
created: function(){ //创建后
console.log(‘a is: ‘ + this.a); //`this` 指向 vm 实例
},

beforeMount:function(){}, //加载前
mounted:function(){}, //加载后

beforeUpdate:function(){}, //更新前
updated:function(){}, //更新后

beforeDestroy:function(){}, //销毁前
destroyed:function() {} //销毁后
});

2、扩展Vue构造器,从而用预定义选项创建可复用的组件构造器:
var MyComponent = Vue.extend({
//扩展选项
});
var myComponentInstance = new MyComponent(); //所有的 `MyComponent` 实例都将以预定义的扩展选项被创建

3、属性和方法
console.log( vm6.a === data.a ); //true
//设置属性也会影响到原始数据
vm6.a = 2;
console.log( data.a ); //2
//反之亦然
data.a = 3;
console.log( vm6.a ); //3
vm6.b=5; //注意:只有这些被代理的属性是响应的。如果在实例创建之后添加新的属性到实例上,它不会触发视图更新
console.log(data.b); //undefined

4、实例属性与方法:这些属性与方法都有前缀$,以便与代理的数据属性区分
vm6.$data =http://www.mamicode.com/== data //true
vm6.$el === document.getElementById(‘example‘); //true
vm6.$watch(‘a‘, function (newVal, oldVal) {}); //$watch 是一个实例方法,这个回调将在 `vm.a` 改变后调用

六、数据绑定语法
1、文本插值:
<span>Message:{{ msg }}</span> //每当这个属性变化时它也会更新
<span v-once>This will never change:{{ msg }}</span> //一次性绑定
2、纯 HTML:
<div v-html="rawHtml"></div> //大括号会将数据解释为纯文本,为了输出真正的 HTML ,需使用 v-html 指令,你不能使用 v-html 来复合局部模板,组件更适合担任 UI 重用与复合的基本单元
3、属性:
<div v-bind:id="dynamicId"></div>
4、绑定表达式:
{{ number + 1 }}
{{ ok ? ‘YES‘ : ‘NO‘ }}
{{ message.split(‘‘).reverse().join(‘‘) }}
一个限制是每个绑定只能包含单个表达式,因此下面的语句是无效的:
{{ var a = 1 }} //这是一个语句,不是一个表达式
{{ if (ok) { return message } }} //流程控制也不可以,可改用三元表达式
5、过滤器:
{{ message | capitalize }} //这个过滤器其实只是一个 JavaScript 函数,返回大写化的值
{{ message | filterA | filterB }} //过滤器可以串联
{{ message | filterA ‘arg1‘ arg2 }} //过滤器也可以接受参数:第一个参数—为过滤器函数,带引号的参数—为字符串,不带引号的参数—按表达式计算
6、指令: 职责是—当其表达式的值改变时把某些特殊的行为应用到 DOM 上
<p v-if="greeting">Hello!</p> //v-if 指令将根据表达式 greeting 值的真假删除/插入 <p> 元素
7、参数:
<a v-bind:href="http://www.mamicode.com/url"></a> //v-bind 指令,用于响应地更新 HTML 特性,用特性插值 href="http://www.mamicode.com/{{url}}" 可获得同样的结果,但实际上它也是在内部特性插值,转为 v-bind 绑定
<a v-on:click="doSomething"></a> //v-on 指令,用于监听 DOM 事件,参数是被监听的事件的名字
8、修饰符:以半角句号 . 开始的特殊后缀,表示指令应当以特殊方式绑定
<a v-bind:href.literal="/a/b/c"></a>
9、缩写:
<a v-bind:href="http://www.mamicode.com/url"></a> //完整语法
<a :href="http://www.mamicode.com/url"></a> //缩写
<a v-on:click="doSomething"></a> //完整语法
<a @click="doSomething"></a> //缩写

七、计算属性 $watch、computed、计算属性的getter、setter属性
1、计算属性:
var vm = new Vue({
el: ‘#example‘,
data: {
a: 1
},
computed: {
b: function () { //一个计算属性的 getter
return this.a + 1; //`this` 指向 vm 实例
}
}
});
console.log(vm.b); //2
vm.a = 2;
console.log(vm.b); //3
2、计算属性 $watch与computed对比:
var vm2=new Vue({
el:"#example2",
data:{
firstName:‘Foo‘,
lastName:‘Bar‘,
fullName:‘Foo Bar‘
}
});
vm2.$watch(‘firstName‘,function(val){
this.fullName=val+‘ ‘+this.lastName;
});
vm2.$watch(‘lastName‘,function(val){
this.fullName=this.firstName+‘ ‘+val;
});
var vm3=new Vue({
el:‘#example2‘,
data:{
firstName:‘Foo‘,
lastName:‘Bar‘
},
computed:{
fullName:function(){
return this.firstName+‘ ‘+this.lastName;
}
}
});
3、计算 setter:
var vm = new Vue({
el: ‘#demo‘,
data: {
firstName: ‘Foo‘,
lastName: ‘Bar‘
},
computed: {
fullName: {
get: function () { //getter
return this.firstName + ‘ ‘ + this.lastName;
},
set: function (newValue) { //setter
var names = newValue.split(‘ ‘);

this.firstName = names[0];
this.lastName = names[names.length - 1];
}
}
}
});
//现在在调用 vm.fullName = ‘John Doe‘ 时,setter 会被调用,vm.firstName 和 vm.lastName 也会有相应更新

八、class与style绑定(数据绑定在data上)
1、绑定class
1)对象语法
<div id="box" v-bind:class="{ ‘class-a‘: isA, ‘class-b‘: isB }"></div>
<div id="box2" v-bind:class="classObject"></div>

2)数组语法
<div id="box3" v-bind:class="[classA,classB]"></div>
<div id="box4" v-bind:class="[classA,isB?classB:‘‘]"></div>
<div id="box5" v-bind:class="[classA,{classB:isB,classC:isC}]"></div> <!--当有多个条件 class 时,在 1.0.19+ 中,可以在数组语法中使用对象语法-->

2、 绑定内联样式style
1)对象语法
<div id="box6" v-bind:style="{color:activeColor,fontSize:fontSize+‘px‘}"></div>
<div id="box7" v-bind:style="styleObject"></div>

2)数组语法
<div id="box8" v-bind:style="[styleObjectA,styleObjectB]">text</div> <!-- v-bind:style 的数组语法可以将多个样式对象应用到一个元素上-->

九、条件渲染 v-if、v-show、v-else(条件指令不能在实例元素上使用)
1、在字符串模板中,如 Handlebars,我们得像这样写一个条件块:
{{#if ok}}
<h1>Yes</h1>
{{/if}}

* 注意,以下所有的条件指令,都不能在实例根元素上使用
1)v-if,v-else
HTML:
<div id="box1">
<h1 v-if="greeting">Yes</h1>
</div>
<div id="box2">
<h1 v-else="greeting2">No</h1>
</div>
JS:
var vm=new Vue({
el:"#box1",
data:{
greeting:false
}
});
var vm2=new Vue({
el:"#box2",
data:{
greeting2:false
}
});
2)多个元素v-if,需要将v-if添加到包装元素template上,最终的渲染结果不会包含它
HTML:
<div id="box3">
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
</div>
JS:
var vm3=new Vue({
el:‘#box3‘,
data:{
ok:false
}
});
3)v-show 指令: 也是根据条件展示元素的选项,但它只是切换display属性。注意,v-show 不支持 <template> 语法
HTML:
<div id="box4">
<h1 v-show="ok">Hello!</h1>
</div>
JS:
var vm4=new Vue({
el:"#box4",
data:{
ok:false
}
});
4)v-else 指令:必须立即跟在v-if/v-show的后面,否则它不能被识别
HTML:
<div id="box5">
<div v-if="greeting">Sorry</div>
<div v-else>Not sorry</div>
</div>
JS:
var vm5=new Vue({
el:"#box5",
data:{
greeting:Math.random()>0.5
}
});
5)v-if、v-show与组件组合使用
HTML:
<div id="box6">
<custom-component v-show="condition">1</custom-component>
<p v-else>这可能也是一个组件1</p>
</div>
<div id="box7">
<custom-component v-show="condition">2</custom-component>
<p v-show="!condition">这可能也是一个组件2</p>
</div>
JS:
var vm6=new Vue({
el:"#box6",
data:{
condition:true
}
});
var vm7=new Vue({
el:"#box7",
data:{
condition:false
}
});
6)v-if、v-show对比
在切换 v-if 块时,Vue.js 有一个局部编译/卸载过程,因为 v-if 之中的模板也可能包括数据绑定或子组件。v-if 是真实的条件渲染,因为它会确保条件块在切换当中合适地销毁与重建条件块内的事件监听器和子组件。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——在条件第一次变为真时才开始局部编译(编译会被缓存起来)。
相比之下,v-show 简单得多——元素始终被编译并保留,只是简单地基于 CSS 切换。
一般来说,v-if 有更高的切换消耗,而 v-show 有更高的初始渲染消耗。
因此,如果需要频繁切换 v-show 较好,如果在运行时条件不大可能改变 v-if 较好。

十、列表渲染 v-for
1、v-for: $index、template v-for(items是data中的一个数组)
HTML:
<li v-for="(index,item) in items">{{ index }}-{{ item.message }}</li>
<li v-for="item of items">{{ $index }}-{{ item.message }}</li> <!--从 1.0.17 开始可以使用 of 分隔符,更接近 JavaScript 遍历器语法-->
HTML:
<ul id="example1">
<template v-for="item in items">
{{ parentMessage }} - {{ $index+1 }}
<li>{{ item.msg }}</li>
<li class="divider">--------------</li>
</template>
</ul>
JS:
var vm1=new Vue({
el:‘#example1‘,
data:{
parentMessage:‘标题‘,
items:[
{ msg:‘Foo‘ },
{ msg:‘Bar‘ }
]
}
});

2、数组变动检测: 变异方法、非变异方法、track-by、$set、$remove
1)数组方法
a、变异方法:会修改原始数组
? push() ? pop() ? shift() ? unshift()
? splice() ? sort() ? reverse()
b、非变异方法(替换数):不修改原始数组,而返回新数组,可直接用新数组替换旧数组
? filter() ? concat() ? slice()
这并不会导致 Vue弃用已有DOM,重新渲染整个列表,Vue实现了一些启发算法,最大化复用 DOM 元素,会用新数组替换原始数组
HTML:
<ul id="example2">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
JS:
var vm2=new Vue({
el:‘#example2‘,
data:{
items:[
{ message:‘Foo1‘ },
{ message:‘Bar1‘ }
]
}
});
vm2.items.push({ message:‘test1‘ });
vm2.items = vm2.items.filter(function (item) {
return item.message.match(/Foo/);
});

2)track-by:追踪元素,避免无用的重新渲染DOM元素
HTML:
<ul id="example3">
<li v-for="item in items" track-by="_uid">
{{item._uid}}
</li>
</ul>
JS:
var vm3=new Vue({
el:‘#example3‘,
data:{
items:[
{ _uid:‘88f869d‘ },
{ _uid:‘7496c10‘ }
]
}
});
/*
在替换数组 items 时,如遇到包含 _uid: ‘88f869d‘ 的新对象,Vue可复用这个已有对象的作用域与 DOM 元素,
如没有唯一的键供追踪,可以使用 track-by="$index",它强制让 v-for 进入原位更新模式:
-> 片断不会被移动,只是刷新对应索引的新值,这种模式也可处理数据数组中重复的值
-> 数据替换高效,但也会付出一定的代价
-> DOM 节点不再映射数组元素顺序的改变,不能同步临时状态(eg: <input> 元素的值)以及组件的私有状态
-> 如果 v-for 块包含 <input> 元素或子组件,要小心使用 track-by="$index"
*/

3)问题: .$set(); .items=[];
因为 JavaScript 的限制,Vue.js 不能检测到下面数组变化:
a.直接用索引设置元素,如 example3.items[0] = {}
b.修改数据的长度,如 example3.items.length = 0
为了解决问题1,Vue.js 扩展了观察数组,为它添加了一个 $set() 方法:
HTML:
<ul id="example4">
<li v-for="item in items">
{{ $index+1 }}—{{ item.childMsg }}
</li>
</ul>
JS:
var vm4 = new Vue({
el: ‘#example4‘,
data: {
items: [
{ childMsg: ‘Foo3‘ },
{ childMsg: ‘Bar3‘ }
]
}
});

vm4.items.$set(0, { childMsg: ‘Changed!‘}); //为了解决问题a,Vue.js 扩展了观察数组,为它添加了一个 $set() 方法
vm4.items=[]; //至于问题b,只需用一个空数组替换 items

4)$remove:用于从目标数组中查找并删除元素
HTML:
<ul id="example5">
<li v-for="item in items">
{{ $index }}—{{ item.msg }}
</li>
</ul>
JS:
var vm5 = new Vue({
el: ‘#example5‘,
data: {
items: [
{ msg: ‘Foo4‘ },
{ msg: ‘Bar4‘ }
]
}
});
/*
在内部它调用 splice(),因此,不必这样:
var index = this.items.indexOf(item);
if (index !== -1) {
this.items.splice(index, 1);
}
只用这样:
this.items.$remove(item);
*/
vm5.items.filter(function (item) {
if(item.msg==‘Foo4‘){
vm5.items.$remove(item);
}
});

3、对象json v-for: $key、value
<li v-for="value in object">{{ $key }} : {{ value }}</li>
<li v-for="(key,val) in object">{{ key }} {{ val }}</li> <!--也可以给对象的键提供一个别名-->
对象json的遍历,在内部是用的Object.keys遍历,但不同的JS引擎下不是一致的

4、值域: v-for="n in 10"
<div id="example6"><span v-for="n in 10">{{ n }} </span></div>

5、显示过滤排序的结果:
想显示过滤/排序过的数组,同时不实际修改或重置原始数据,有2个办法:
a、使用内置的过滤器 filterBy 和 orderBy,过滤器更方便
b、创建一个计算属性,返回过滤/排序过的数组,计算属性有更好的控制力,更灵活,因为它是全功能JS

1)filterBy : 限制—指令的值须是数组,eg:v-for
a、只显示包含字符串 "hello" 的元素 : <div v-for="item in items | filterBy ‘hello‘"></div>
b、只在用户对象的 name 属性中搜索 "Jack": <div v-for="user in users | filterBy ‘Jack‘ in ‘name‘"></div>
c、使用动态参数作为搜索目标或搜索字段,配合 v-model 我们可以轻松实现输入提示效果:
HTML:
<div id="example6">
<input v-model="searchText" />
<ul>
<li v-for="user in users | filterBy searchText in ‘name‘">
{{ user.name }}
</li>
</ul>
</div>
JS:
var vm6=new Vue({
el:‘#example6‘,
data:{
searchText:‘‘,
users:[
{ name:‘Bruce‘ },
{ name:‘Chuck‘ },
{ name:‘Jackid‘ }
]
}
});

d、多搜索字段:
HTML:
<div id="example7">
<input v-model="searchText">
<ul>
<li v-for="user in users | filterBy searchText in ‘name‘ ‘phone‘">
{{ user.name }}-{{ user.phone }}
</li>
</ul>
</div>
JS:
var vm7=new Vue({
el: ‘#example7‘,
data: {
searchText: ‘‘,
users: [
{ name: ‘Bruce‘, phone:‘18701039633‘ },
{ name: ‘Chuck‘, phone:‘18700000000‘ },
{ name: ‘Jackie‘, phone:‘15811119619‘ }
]
}
});

2)orderBy:限制—指令的值须是数组,eg v-for, 1为升序,-1为降序
a、升序: <li v-for="user in users | orderBy ‘phone‘">{{ user.name }}-{{ user.phone }}</li>
b、降序: <li v-for="user in users | orderBy ‘phone‘ -1">{{ user.name }}-{{ user.phone }}</li>
c、原始类型数组: <li v-for="n in 10 | orderBy -1">{{ n }}</li>
d、动态排序:
HTML:
<div id="example8">
<button @click="order = order * -1">Reverse Sort Order</button>
<ul>
<li v-for="user in users | orderBy ‘name‘ order">
{{ user.name }}
</li>
</ul>
</div>
JS:
var vm8=new Vue({
el: ‘#example8‘,
data: {
order: 1,
users: [
{ name: ‘Bruce‘ },
{ name: ‘Chuck‘ },
{ name: ‘Jackie‘ }
]
}
});
e、使用两个键名排序:
HTML:
<div id="example9">
<ul>
<li v-for="user in users | orderBy ‘name‘ ‘phone‘ order">
{{ user.name }}-{{ user.phone }}
</li>
</ul>
</div>
JS:
var vm9=new Vue({
el: ‘#example9‘,
data: {
users: [
{ name: ‘Bruce‘, phone:‘18701039633‘ },
{ name: ‘Chuck‘, phone:‘18700000000‘ },
{ name: ‘Jackie‘, phone:‘15811119619‘ }
]
}
});


vue.js 常用语法总结(一)