Vue
数据代理
通过一个对象代理另一个对象的属性操作(借助Object.defineProperty方法)
let obj1 = {x:100}
let obj2 = {y:200}
Object.defineProperty(obj2,'x',{
get(){
return obj1.x
}, // 读取obj2.x时调用getter
set(value){
obj1.x = value
} // 修改obj2.x时调用setter
}
)
修改obj2.x的值时obj1.x的值同步变化。
计算属性
要用的属性不存在,通过已有的属性计算得来。
原理:借助Object.defineProperty方法提供的getter()和setter()。
姓:<span>{{firstName}}</span>
名:<span>{{LastName}}</span>
全名:<span>{{fullName}}</span>
new Vue(
{
data(){
return {
firstName: '张',
lastName: '三'
}
},
computed: {
fullName: {
getter() {
return firstName + '-' + LastName // firstName和lastName是计算属性所依赖的数据
},
setter(val) {
// val是修改后的fullName值
const arr = val.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
},
}
}
}
)
getter什么时候执行?
- 初次读取(fullName)时会执行一次;
- getter调用后缓存当前fullName,所依赖的数据发生改变会再次调用。
setter什么时候执行?当fullName被修改时。
计算属性最终会出现在vm实例,如果要被修改,必须写set函数去响应修改,且set中要引起所依赖的数据变化。
计算属性简写
// 只考虑读取不修改时,计算属性可简写为:
computed: {
fullName() {
return firstName + '-' + lastName
}
}
计算属性vs侦听属性
- computed能完成的功能,watch都可以完成
- watch能完成的功能,computed不一定能完成(如watch可以进行异步操作)
watch: {
firstName(newVal){
setTimeout(()=>{return newVal + '-' + lastName},1000) //1s后返回fullName
},
lastName(newVal){
setTimeout(()=>{return firstName + '-' + newVal},1000)
}
}
Tips:
- 所有被Vue管理的函数最好写成普通函数,
this指向vm或组件实例对象 - 所有不被Vue管理的函数(如定时器回调函数,ajax回调函数,Promise回调函数),最好写成箭头函数,(js引擎调用函数,但箭头函数没有自己的
this,就会向外找,即firstName函数的this),这样this才会指向vm或组件实例对象