前言
这篇文章主要为了分析Vue监视数据的原理,希望自己理清思路,也希望对还在学习Vue的小伙伴有所帮助。
一、Vue监视数据的原理
底层逻辑:Vue通过
Object.defineproperty()方法
中的get()函数
实现对数据的读取,通过set()函数
实现对数据的监控
特点:Vue会监视data中所有的层级的数据
二、如何监视对象中的数据
通过
set()函数
实现监视
特点:要监视的数据一定要在data中写入,即在new Vue时就要想好data中的第一层数据
大致底层原理代码:
<script>
//准备一组数据对象
let data = {
star: '周杰伦',
sex: '男',
};
//利用Observe构造函数观察数据
function Observe(obj) {
//用方法Object.keys()得到数据对象的属性名,并将属性名汇总为一个数组
const keys = Object.keys(obj);
//遍历属性名数组
keys.forEach((k) => {
//利用Object.definePropert方法实现对数据的I监视和修改
Object.defineProperty(this, k, {
get() {
return obj[k]
},
set(val) {
obj[k] = val
}
})
})
}
new Observe(data)
</script>
1.后期追加属性有何影响
后期为对象追加的属性(既不能直接在_data或data上添加属性),Vue默认不做响应式处理(后期追加的属性,Vue没有为其添加getter和setter)
2.如何后期为对象追加属性
如果需要后期为对象追加属性,那么Vue提供如下API可以实现追加属性的数据响应式
Vue.set(target,propertyName/index,value)
vm.$set(target,propertyName/index,value)
三、如何监视数组中的数据
通过
包裹数组更新元素的方法
实现监视
特点:数组中的对象没有getter和setter,但数组中对象中的属性有getter和setter
通过包裹数组更新元素的方法实现数据监视,本质就是做了两件事:
(1). 调用原生对应的方法对数组进行更新。
(2). 重新解析模板,进而更新页面。
Vue中修改数组中数据的方法
(1). 使用这些API:
push()
、pop()
、shift()
、unshift()
、splice()
、sort()
、reverse()
(2).Vue.set()
或vm.$set()
总结
文章可能写的有点乱,会不定期更改
来一个小案例汇总以上知识点,案例中都有解释,练习案例应该会更明白一下
<body>
<div id="app">
<h2>宠物信息</h2>
<button @click="cat.age ++">年龄+1</button><br/><br/>
<button @click="addSex">添加性别属性,默认值为:男</button><br/><br/>
<button @click="addFriend">在列表首位添加一个朋友</button><br/><br/>
<button @click="changeFriend">修改第一个朋友的名字为大黄</button><br/><br/>
<button @click="addHobby">添加一个爱好</button><br/><br/>
<button @click="changeHobby">修改第一个爱好为开车</button>
<h3>姓名:{{cat.name}}</h3>
<h3>年龄:{{cat.age}}岁</h3>
<h3 v-show="cat.sex">性别:{{cat.sex}}</h3>
<h3>爱好</h3>
<ul>
<li v-for="(h,index) in hobbys" :key="index">{{h}}</li>
</ul>
<h3>朋友</h3>
<ol>
<li v-for="(f,index) in friends">{{f.name}} - {{f.age}} - {{f.sex}}</li>
</ol>
</div>
<script>
const vm = new Vue({
el: "#app",
data: {
cat: {
name: "憨瓜",
age: 3,
},
hobbys: ['猫条', '吸薄荷', '咬人'],
friends: [{
name: "波妞",
age: '2岁',
sex: '母'
}, {
name: "妲己",
age: '2岁',
sex: '女'
}]
},
methods: {
//添加性别属性
addSex() {
// this.cat.sex = "男"; //这种方法为对象添加属性,Vue没办法做响应式
//Vue修改对象类型的数据可以通过Vue.set方法和vm.$set方法实现
Vue.set(this.cat, 'sex', '男')
},
//添加朋友
addFriend() {
//Vue中修改数组类型的数据可以直接用原生修改数组的方法,有push,pop,unshift,shift,splice,sort,reverse
this.friends.unshift({
name: '小白',
age: '3岁',
sex: '女'
})
},
//修改第一个朋友的名字
changeFriend() {
//第1种方法:通过对象的方法改变数据
// this.friends[0].name = "大黄";
//第2种方法:通过数据的方法修改数据
this.friends.splice(0, 1, {
name: "大黄",
age: '3岁',
sex: '女'
})
},
//添加一个爱好
addHobby() {
//Vue中修改数组类型的数据可以直接用原生方法
this.hobbys.push('跑酷')
},
//修改第一个爱好
changeHobby() {
this.hobbys.splice(0, 1, '猫粮')
}
},
})
</script>
</body>
运行结果