属性(或指令)
v-show
根据条件的 boolean
值来切换元素的 CSS display
属性。
相对 v-if
来说
v-show
只是针对 display
属性,即该元素会始终被渲染,只是不一定会显示出来。
而 v-if
不同,它会根据条件决定是否会被创建-渲染或者销毁
v-html
官方说是只能按照普通 html
内容去插入,不会作为模版来编译。如果需要用v-html
结合模版来使用,最好通过自定义组件形式来实现。
v-text
更新元素的 textContent
属性, 这种更新属于更新标签的整个文本内容。如果要局部更新需要用到插值
其实就是元素的文本节点内容。
v-once
数据只会在加载时更新,后面不会随数据变化而变化
用法:
<div id="example"><h1 v-once>{{a}}</h1></div>
对标签使用了 v-once
之后,在控制台改变 vm.a
的值,会发现 DOM 中显示的还是 vm.a
的初始值
v-model="attr"
数据模型,即双向绑定,和 v-bind
单向绑定不同,它不仅可以读取值还可以通过输入来修改属性值。
v-bind="value"
或 v-bind:attr="value"
或 :attr="value"
单向绑定,一般可以绑定标签的一个内置属性(比如:title,鼠标放上去会出现被绑定的值,即双引号中的 value),不能直接修改绑定的属性值。
v-on:eventHandler
为元素绑定事件,比如 v-on:click="clickHandler"
,为元素绑定了个点击事件,事件处理函数为:clickHandler
v-if
条件属性,通过判断条件值来决定是否显示标签。
示例:点击按钮显示隐藏 div
tags:
// tags
<h1>条件属性:v-if</h1>
<button v-on:click="toggle">Show Message ?</button>
<p v-if="isToggle">I am showed !</p>
datas:
var data = {
isToggle: false,
};
methods:
// 方法
methods: {
toggle: function () {
this.isToggle = !this.isToggle;
},
}
通过点击按钮,调用 toggle
改变 isToggle
的值,然后 p
标签内使用 v-if
属性绑定 isToggle
属性。
v-else
和 v-else-if
和 if ... else ...
条件语句一样,承接 v-if
之后的 v-else
;
即:v-if
不满足然后执行 v-else
如:(如果 num 大于 10 就显示红色背景div,否则显示蓝色背景div)
<h1>条件属性:v-if</h1>
<button v-on:click="toggle">Show Message ?</button>
<p v-if="isToggle">I am showed !</p><br/><br/>
<button v-on:click="changeBgNum">点我 {{bgNum}}</button><br/><br/>
<span v-if="bgNum === 1" style="background-color:red;color:white;">我是红色</span>
<span v-else-if="bgNum === 2" style="background-color:green;color:white;">我是绿色</span>
<span v-else style="background-color:blue;color:white;">我是蓝色</span><br/><br/>
数据:
var data = {
bgNum: 1,
}
方法:
// 方法
methods: {
changeBgNum: function () {
if ( this.bgNum++ === 3 ) {
this.bgNum = 1;
return;
}
},
}
该例子是通过判断 this.bgNum
的值来决定显示哪种颜色的 div
1: 红色(默认)
2: 绿色
3: 蓝色
通过点击按钮来切换div
效果如图:
PS: 使用v-else-if
和 v-else
的标签必须是紧跟的兄弟关系,即中间不能想跟其他标签。
v-for
遍历数据,来动态生成元素
数据类型可以是:数组,对象或基本类型数据。
使用方式:
数组元素是普通类型,这个时候单独改变数组成员的值不会引发
render
,修改整个数组的时候会比如:人物列表一
<h1>循环属性:v-for</h1> <label>数组数据列表:</label> <ul><li v-for="person in persons">{{person}}</li></ul>
数据:
data: { persons: ['Som', 'Bob', 'Coco'], }
这样的话,控制台修改
vm.persons[0] = 'lizc'
的值,并不会触发render
。但是整体修改数组会:
vm.persons = ['a', 'b', 'c']
数组元素是对象类型,然后标签内引用对象的成员,单独改变这个成员的值的时候会触发
render
比如:人物列表二
<h1>循环属性:v-for</h1> <label>对象数据列表:</label> <ul><li v-for="people in peoples">{{people.name}}</li></ul>
数据:
var data = { peoples: [ {name: 'Tom'}, {name: 'Lily'}, {name: 'Simon'} ], };
控制台修改成员值:
vm.peoples[0].name = 'lizc' beforeUpdate updated "lizc"
从控制输出可知,单独修改成员值可以触发
render
,如上的beforeUpdate
和updated
就是更新了数据。自定义组件形式
// 自定义组件 Vue.component('people-list', { props: ['people'], // 组件接收到的属性 template: '<li>{{people.name}}</li>' // 组件模版 });
标签:
<h1>循环属性:v-for</h1> <label>自定义组件列表:</label> <ol><people-list v-for="people in peoples" v-bind:people="people"></people-list></ol>
数据依旧使用 2 中的
peoples
v-bind:people="people"
组件中的这个,是将组件props
属性中的people
成员绑定到了前面v-for
中遍历用的people
数据。v-bind:people
这个里面的people
可以任意定义,只要跟组件内部的props
属性中对应即可。
结论: 在使用 v-for
循环的时候,如果需要根据单个元素去重新render
,要用对象数组形式,如果不需要只要普通类型元素的数组即可。
在遍历数组的时候,还可以在遍历的时候指定索引值,比如:
// 指定索引遍历 <label>数组数据列表(指定索引):</label> <ul><li v-for="(person, index) in persons">{{person + ', ' + index}}</li></ul>
结果:
名字后面的数字就是其在数组中对应的索引
遍历对象,可以指定属性key, 值value, 以及索引index
比如:(汽车的宽高和速度信息列表)
<label>对象数据列表(指定键,值,索引):</label> <ul><li v-for="(value, key, index) in car">{{ '汽车参数' + key + ': ' + value + ', ' + index}}</li></ul>
汽车参数:
data: { car: { width: '180cm', height: '200cm', speed: '200km/h', }, }
结果:
需要注意的是:(value, key, index),第一个是值不是键。
唯一
key
,排序
在使用 v-for
列表式数据的时候,如果需要排序,则需要主动指定一个 key
告诉 vue
需要根据这个属性去排序列表
比如:
有如下数据:
data: {
students: [
{name: 'Tom', id: '002'},
{name: 'Dog', id: '004'},
{name: 'Cat', id: '003'},
{name: 'Tiger', id: '001'},
]
}
<ul><li v-for="stu in students" :key="stu.id"></li></ul>
然后会发现
过滤器
使用场景:(Vue 2.1.0 以上支持)
- 插值
{{ firstValue | secondValue }}
v-bind
值中
v-bind:id="name | age"
计算属性
计算属性
new Vue({
data: {
message: 'hello vue.js !'
},
computed: {
reverseMessage: function () {
return this.reverseMessage.split('').reverse().join('');
}
}
});
标签使用:
<span>Reversed Message: {{ reverseMessage }}</span>
结果: Reversed Message: ! sj.euv olleh
计算属性的使用是为了避免插值中使用复杂的计算而导致难以维护。
使用计算属性可以将最终的结果值放入到插值中去显示
还可以通过 vm.reverseMessage
来直接调用获取其值,由于 compted:{}
中 reverseMessage
的结果是与 vm.message
绑定的,因此只要message
发生变化其值也会立即发生变化。
计算缓存 vs Methods
组件中有个属性专门用来定义组件内所使用到的方法,即:methods
,对象类型。
比如上面的例子:
new Vue({
data: {
message: 'hello vue.js !'
},
computed: {
reverseMessage: function () {
return this.reverseMessage.split('').reverse().join('');
}
},
methods: {
reverseMessage: function () {
return this.reverseMessage.split('').reverse().join('');
}
},
});
然后通过直接调用函数方式:
<span>Reversed Message: {{ reverseMessage() }}</span>
同样可以达到与使用计算属性同样的效果。
计算属性和 methods
最大的区别就在于缓存机制
计算属性:会在每次调用 vm.reverseMessage
取值的时候,只要 vm.message
没有发生改变,就会立即返回之前计算过的值。
methods
:每次调用函数都会返回实时的计算结果。
该区别在使用 Date
更新时间的时候最为明显:
比如:
computed: {
reverseMessage: function () {
return this.message.split('').reverse().join('');
},
cnow: function () {
this.currTime = new Date(Date.now())
return this.currTime;
}
},
methods: {
reverseMessage: function () {
return this.message.split('').reverse().join('');
},
now: function () {
return new Date(Date.now());
}
},
标签:
<h1>计算属性 vs Methods</h1>
<label>计算属性:</label><span>{{ cnow }}</span><br/>
<label>Methods: </label><span>{{ now() }}</span><br/>
输出:
计算属性:"2017-05-04T03:24:19.991Z"
Methods: "2017-05-04T03:24:19.991Z"
这里输出都是一样的,可以到控制台验证下,在获取计算属性值和调用 methods
函数结果:
从结果图中可以知道在每次获取计算属性的时候都是之前计算过的值,而 methods
每次都会实时计算出最新的值返回。
其实这也好理解,计算属性毕竟是作为属性来使用,只要其依赖的数据没发生变化它也不应该会有所变化(虽然其实现还是以函数形式),而对于 methods
其实是以函数形式定义并以函数形式调用,既然每次都是函数调用形式去获取值,那肯定会每次调用都会重新计算得出最新值返回。
两者使用场景:
- 计算属性:可以应对大型数据计算并且一般不会发生变动的数据,这样就避免了每次想要获取需要经过大量计算而又不会经常发生变化的值导致的每次都需要重新计算,消耗性能;
methods
:适用于数据变化性比较大,经常变动的内容,也可替代计算属性来使用。
Computed
属性 vs Watched
属性
计算属性和观察属性区别在于,观察属性一次只能观察一个属性然后针对该属性的变化做出响应,而计算属性却不一样,它可以同时检测几个属性,通过这几个属性的值返回计算的结果。
比如:(分别通过观察属性和计算属性来实现:更新人物姓名)
观察属性:
// 数据 var data = { firstName: 'li', lastName: 'zc', fullName: 'lizc', };
观察:
// 观察属性,观察的属性发生变化,会做出响应(比如:改变其他属性的值) watch: { firstName: function (newValue) { console.log('firstName ---------- new: ' + newValue); this.fullName = newValue + ' ' + this.lastName; }, lastName: function (newValue) { console.log('lastName ---------- new: ' + newValue); this.fullName = this.firstName + ' ' + newValue; }, },
这里对
firstName
和lastName
分别进行了观察,一旦有改变发生,就会去更新全名:fullName
值;计算属性
通过计算属性的特性:只要被绑定的属性值不发生变化计算结果就不会变,被绑定的属性发生变化计算结果会根据变化后的最新值去计算最新的结果。
可以更方便的去实现上面通过
watch
属性来刷新全名的功能。// 数据 var data = { firstName: 'li', lastName: 'zc', // fullName: 'lizc', 这里就不需要设置这个属性了,直接从计算属性结果中获取 };
计算属性:
// 计算属性,只要绑定的属性不变,会先使用缓存的值 computed: { fullName: function () { return this.firstName + ' ' + this.lastName; }, },
最后两者通用的标签书写方式:
<h1>Compted 属性 vs Watched 属性</h1>
<label>Fist Name: </label><input type="text" v-model="firstName"><br/>
<label>Last Name: </label><input type="text" v-model="lastName"><br/>
<label>计算属性:</label><span>{{ fullName }}</span><br/>
<label>观察属性:</label><span>{{ fullName }}</span><br/>
上面的计算和观察属性中的 fullName
有所不同
前者标签内的 fullName
插值使用的是 compted
属性中的 fullName
;
后者标签内的 fullName
插值使用的是 data
数据中的 fullName
属性;
最终结果其实都是一样的,见效果图:
计算属性的 setter
默认情况下计算属性是只有 getter
的,但是我们可以自己添加 setter
比如:
需要注意的是,这里 fullName
不能再是函数声明形式了,而需要采用对象方式
// 为计算属性添加 setter
fullName: { // fullName: function (){} => fullName: {}
get: function () {
return this.firstName + ' ' + this.lastName;
},
set: function (newValue) {
var name = newValue.split(' ');
this.firstName = name[0];
this.lastName = name[name.length - 1];
}
// return this.firstName + ' ' + this.lastName;
},
这样我们也可以通过 vm.fullName = 'li zc
方式去修改绑定的属性了。
setter
里面可以做一些自定义的需求等等。
总结
本篇主要涉及 Vue.js
中的一些主要属性(比如:v-bind
, v-model
, v-if
, v-for
, v-on
等等),以及计算属性与观察属性的概念和用法。
回顾:
计算属性
会缓存结果,只要被绑定的属性值没变,多次调用计算属性获取值得到的结果都是被绑定的属性最后发生改变的那个值。
默认没有
setter
,可以自定义,注意自定义的时候需要以对象形式出现,比如:var vm = new Vue({ data: { name: 'lizc' }, computed: { // 这是只有 getter 的情况 myName: function () { return this.name; }, // 自定义 setter 情况 youName: { get: function () { return this.name; }, // 有了这个之后就可以通过 vm.youName = 'Tom' // 去改变计算属性的值,而这个 set 里面又是绑定了 this.name, // 因此在修改这个计算属性的时候也会触发绑定了 this.name 的组件刷新 UI set: function (newVaule) { this.name = newVaule; } } } });
计算属性有个好处就是,可以同时检测多个属性并且可以根据这多个属性通过一定方式计算得出结果。
观察属性
观察属性,是针对单个属性进行观察,一旦有值变化会做出相应的响应。
使用方式:
new Vue({ data: { name: 'lizc', age: '30', }, watch: { name: function () { // do sth }, age: function () { // do sth }, } });