Vue中改变数据的原理
使用Object.defineProperty,将data对象中的每个属性重新定义给另一个对象obj,然后将obj赋给Vue实例的_data属性。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>数据代理</title>
</head>
<body>
<script>
let data = {
name:"jack",
age:23,
sex:"male",
}
// 创建代理对象
function Agent(obj){//构造函数,首字母大写
// obj为要被代理的对象
// 其所有的key组成数组
const arr = Object.keys(obj)
// 遍历每一个属性,定义给this
arr.forEach(k=>{
Object.defineProperty(this, k, { //this 为构造函数的实例对象
get(){//获取obj的值
return obj[k]
},
set(value){//设置obj的值
obj[k] = value
}
})
})
}
// 创建代理对象
let agent = new Agent(data)
console.log("代理对象:",agent)
</script>
</body>
</html>
以上代理就可以通过agent来代理data的数据
监测对象
Vue.set
为data内部的对象添加属性,并具有对应的getter/setter(因为这样Vue才可以监测到数据变化,这样添加的属性才是响应式的)
Vue.set(vm._data.student, ‘hobby’, ‘pingpong’) //改对象
Vue.set(vm._data.personsArr, 0, ‘改数组’) //改数组
或者
vm.$set(vm._data.student, ‘hobby’, ‘pingpong’)
或者
vm.$set(vm.student, ‘hobby’, ‘pingpong’)
不能给vm实例、_data、data添加属性
属性的值必须具有getter&setter,Vue才能监测到数据的变化,才能重新渲染页面
监测数组
data内部属性为数组的,对数组的数据操作应该使用如下方法,Vue才能监测到。
push/pop/unshift/shift/splice/sort/reverse
这几个方法是Vue封装的,不是Array.prototype.push…
vm._data.personsArr.push === Array.prototype.push //false
arr.split(start, deleteCount, ...["a","b", ]) //删除替换
数组不能通过索引直接赋值