计算属性
需求1:两个文本框,输入内容后再合并显示在元素中;
插值语法实现:
<div id="root">
姓:<input type="text" v-model:value="firstName"><br>
名:<input type="text" v-model:value="lastName"><br>
全名:<span>{{firstName.slice(0,3)}}-{{lastName}}</span>
</div>
提示:用 v-model:value
实现双向绑定,在插值中用 slice() 取 firstName 的一部分;
new Vue({
el: "#root",
data: {
firstName: "三",
lastName: "毛"
}
});
效果:
用 methods 中的方法实现:
<div id="root">
姓:<input type="text" v-model="firstName"><br>
名:<input type="text" v-model="lastName"><br>
全名:<span>{{fullName()}}</span>
</div>
提示:v-model:value
简写成了 v-model
;
提示:模板里面调用方法,要加(),不加() 会输出方法的函数体;
注意:Vue 里面,当data中的数据发生改变,模板也会重新解析,保持联动;
new Vue({
el: "#root",
data: {
firstName: "三",
lastName: "毛"
},
methods: {
fullName() {
return this.firstName + '-' + this.lastName
}
}
});
效果:
计算属性实现:
Vue中说的属性,指的是 data
中的数据;方法都在 methods
中,计算属性会放在 computed
里;
<div id="root">
姓:<input type="text" v-model="firstName"><br>
名:<input type="text" v-model="lastName"><br>
全名:<span>{{fullName}}</span>
</div>
提示:计算属性,也是 vm 的属性,插件调用的时候,直接写属性名;
const vm = new Vue({
el: "#root",
data: {
firstName: "三",
lastName: "毛"
},
computed: {
fullName: {
get() {
return this.firstName + "-" + this.lastName
console.log("get 被调用了!");
},
set(value) {
//console.log("set",value);
const arr = value.split('-');
this.firstName = arr[0];
this.lastName = arr[1]
}
}
}
});
提示1:计算属性本身不存在,是计算得来的;
提示2:计算属性中也有 getter 和 setter ,成对出现的,看着很眼熟;
提示3:set 不是必须的,一般计算属性只需要读取计算结果,很少会写入;
提示4:get 中的 this 指向,Vue已经调试成 vm 了,所以 this.firstName 会调用 data 中的数据;
看下效果:
当修改姓和名时:改成余华;
全名,也跟着变成余华,而且 get 被调用了两次;说明计算属性计算了两次;
当修改 vm.fullName
时:为了匹配,修改成:矛-盾
修改也实现计算,姓和名被拆分赋值;get 也被调用了,说明把计算后的属性重新定义给 fullName;
看下插件:
插件也是一目了然,把 computed
单独提出来与 data
并列,同是属性;
计算属性简化实现:
当不需要 set 时,代码可以简化为:
const vm = new Vue({
el: "#root",
data: {
firstName: "三",
lastName: "毛"
},
// 简化写法:
computed: {
fullName() {
console.log("get被调用了!")
return this.firstName + "-" + this.lastName
}
},
// 完整写法:
// computed: {
// fullName: {
// get() {
// console.log("get 被调用了!");
// return this.firstName + "-" + this.lastName;
// },
// set(value) {
// const arr = value.split('-');
// this.firstName = arr[0];
// this.lastName = arr[1];
// }
// }
// }
});
fullName 不用写成配置对象形式了,直接用一个普通函数的形式就行;
【计算属性】总结:
1)定义:要用的属性不存在,要通过已有属性计算得来;
2)原理:底层借助了 Object.defineProperty() 方法提供的 getter 和 setter;
3)get 函数什么时候执行?
1、初次读取时会执行一次,再调用会读缓存;
2、当依赖的数据发生改变会被再次调用,再刷新缓存;
4)优势:与 methods 实现相比,计算属性有缓存机制(复用),避免重复计算,效率更高,调试更方便;
5)备注:
1、计算属性最终会出现在 vm 上,直接读取使用即可;
2、如果计算属性要被修改,那必须写 set 函数去响应修改,且 set 中要引起计算时依赖的数据发生改变。