计算属性
响应式的传统的实现方法:
- 赋值语法
- methods实现:
{{fullName()}}
组件模板应该只包含简单的表达式,复杂的表达式应该重构为计算属性或者方法。
Vue中已有的原始属性 => 计算属性,计算属性不在 _data
中,采用对象形式定义如下:
computed:{
// 自定义变量,采用对象形式
fullName:{
get(){
// this指向当前vm实例
return this.firstName + ':' + this.secondName;
}
// 按需要(写的需求)添加
set(){
this.firstName = 'WU';
}
}
}
计算属性的特点:
- get方法存在缓存机制(重复调用只会调用一次),永远保持数据的最新值。只有在初次读取和依赖的数据变化时才被调用。这种机制methods实现将不存在,会持续调用。
- 拿到get方法的返回值放到vm身上。
- 最终体现在vm上,直接读取使用就行,如模板中直接使用
{{fullName}}
。 - 如果要修改计算属性,要写set方法区真实修改属性值。
- 使用
this
获取data中的值。
计算属性的简写:
如果只读不写的场景,可以对计算属性进行简写,模板调用不带括号:
computed:{
fullName(){
xxxxx
}
}
// 模板调用
{{fullName}}
监视属性
采用watch监视属性或者方法的变化(必须提前在data定义好),进行相关的操作,分为表层监视和深度监视。
参数:
computed:{
// computed的简写形式
info(){
return this.xxx;
}
}
watch:{
// 要监视的属性或者方法
isHot:{
immediate:true,
// newValue:新的值,oldValue:旧的值
deep:true, //深度监视
handler(newValue, oldValue) {
}
}
}
监视的另外一种写法,按需监视:
vm.$watch('isHot', {
immediate: true,
handler(newValue, oldValue) {
xxxxx
}
});
深度监视:
使用watch时根据数据的具体结构,决定是否采用深度监视。
data(){
return {
isHot: true,
numbers:{
a: 1,
b: 2,
// 也可以继续多级结构
c:{
}
}
}
}
watch:{
numbers:{
deep:true, // 只要a和b的值改变,可以监视变化
handler(newValue, oldValue){
}
}
}
// 在模板中使用,对该属性进行修改,就会触发
{{numbers.a++}}
当只有handler函数时,可以进行简化:
watch:{
// 要监视的属性
numbers(newValue, oldValue){
xxxxxxx
}
}
计算属性 VS. 监视属性
区别:
- computed 和 watch都能完成同一个功能,但watch实现更复杂,没有返回值直接修改。
data(){
return{
firstName:'wu',
secondName:'yuhan',
// 必须预先定义
fullName:'wuyuhan'
}
},
watch:{
firstName(val){
this.fullName = val + ':' + this.secondName;
},
secondName(val){
this.fullName = this.firstName + ':' + val;
}
}
- watch 能实现异步操作,computed无法完成,如执行定时操作。
computed:{
firstName(val){
// 定时器中的箭头函数this没有任何指向,只能向上查找,找到了firstName的对象
setTimeout(()=>{
console.log(this); // 指向vue实例,如果普通函数,指向windows
this.fullName = val + ':' + this.secondName;
}, 1000);
},
}
指导原则:
- 所有被vue管理的函数,必须写成普通函数,这样
this
指向vm或者组件实例对象。 - 所有不被vue管理的函数(定时器的回调函数、ajax的回调函数、Promise的回调函数),要写成箭头函数,这样的
this
是vm或者组件实例对象,通过向上查找对象实现。 - 不是所有的箭头函数都是被vue管理的。