数据响应式,即响应式的数据,数据一旦发生改变,视图就会做出相对应的变化。
       说到数据响应式,首先要知道ES6的getter/setter。
       vue的数据打印出来正是个有get和set属性的对象,vue的data不是直接获取数值,而是get/set方法,来对数据进行读写操作。
let obj={
fistName:'张',
secondName:'三',
get fullName(){
return this.firstName+this.secondName;
},
set fullName(name){
this.firstName=name[0]
this.secondName=name.substring(1)
}
}
//可以直接以属性方式调用,不加括号
obj.fullName
obj.fullName='李四'
       对于已经声明好的对象,我们不能直接去写入get/set,于是需要使用Object.defineProperty()来添加
let data={}
data._n=0
Object.defineProperty(data,'n',{
get(){
return this._n
},
set(value){
if(value<0)return
this._n=value
}
})
      但是这样可以直接偷偷篡改data._n来使data.n的值发生变化,不会去走set的逻辑,为了避免原数据直接被篡改,试着使用代理
let data=proxy({data:{n:0}})//传入无法访问的匿名对象
function proxy({data}){
const obj={}
Object.defineProperty(obj,'n',{
get(){
return data.n
},
set(value){
if(value<0)return
data.n=value
}
})
return obj
//obj就是data的代理
}
但是如果需要采用
let data1={n:0}
let data2=proxy({data:data1})
      这种形式,n的值依然可以通过data1偷偷被改,依然是为了避免数据在不知情的情况下被修改,需要能够获取到“原数据”的修改过程
let myData={n:0}
let data=proxy2({data:myData})
function proxy2({data}){
//监听逻辑
let value=data.n
//拷贝原数据后删除,再添加一个n,可以不加这句,因为定义了相同属性名,会直接覆盖
delete data.n
Object.defineProperty(data,'n',{
get(){
return value
},
set(newValue){
if(newValue<0)return
value=newValue
}
})
//代理逻辑
const obj={}
Object.defineProperty(obj,'n',{
get(){
return data.n
},
set(value){
if(value<0)return
data.n=value
}
})
return obj
}
myData.n=-1
console.log(data.n)//结果依然是0
类似于vm=new Vue({data:myData})
这会让vm成为myData的代理
会对myData的所有属性进行监控
防止myData的属性变了,vm不知道。vm监听了myData的属性变化就可以在每次数据被修改时直接调用render(data),实现响应式的数据变化。