Vue更新原理
一、模拟数据监测
let data = {
name: 'aaa',
address: 'bbb'
}
function Observer(obj) {
const keys = Object.keys(obj);
// 创建一个监视的实例对象,用于监视data中属性的变化
const obs = new Observer(data);
// 准备一个vm实例
let vm = {};
vm._data = data = obs;
keys.forEach(key => {
Object.defineProperty(this, key, {
get() {
return obj[key];
},
set(newValue) {
console.log(`${key}被修改了,此时应该解析模板,生成虚拟DOM,进行diff算法比较,。。。`);
obj[key] = newValue;
}
})
});
}
二、VUE中响应式方法练习
<div id="root">
<button @click="student.age++">年龄+1岁</button><br>
<button @click="addSex">添加性别属性,默认值: 男</button><br>
<button @click="addFriend">在列表首位添加一个朋友</button><br>
<button @click="editFriend">修改第一个朋友的名字为:张三</button><br>
<button @click="addHobby">添加一个爱好</button><br>
<button @click="editHobby">修改第一个爱好为: 开车</button><br>
<h2>学生姓名: {{ student.name }}</h2>
<h2>学生年龄: {{ student.age }}</h2>
<h2 v-if="student.sex">学生性别: {{ student.sex }}</h2>
<h2>爱好:</h2>
<ul>
<li v-for="(h, index) in student.hobbies" :key="index">
{{ h }}
</li>
</ul>
<h2>朋友们</h2>
<ul>
<li v-for="(f, index) in student.friends" :key="index">
{{ f.name }} -- {{ f.age }}
</li>
</ul>
</div>
<script>
const vm = new Vue({
el: '#root',
data() {
return {
student: {
name: 'tom',
age: 18,
friends: [
{ name: 'jerry', age: 35 },
{ name: 'tonyt', age: 36 }
],
hobbies: ['抽烟', '喝酒', '烫头']
}
}
},
methods: {
addSex() {
this.$set(this.student, 'sex', '男');
},
addFriend() {
this.student.friends.unshift({
name: 'xz',
age: 10
});
},
editFriend() {
this.student.friends[0].name = '张三';
},
addHobby() {
this.student.hobbies.push('蹦迪');
},
editHobby() {
this.student.hobbies.splice(0, 1, '开车');
}
},
});
</script>
三、VUE监视数据原理总结
-
Vue会监视data中所有层次的数据
-
如何监测对象中的数据?
-
通过setter实现监视,且要在new Vue时就要传入监测的数据
-
对象中后追加的属性,Vue默认不做响应式处理
-
如需给后添加的属性做响应式,可以使用如下API
Vue.set(target, propertyName/index, value)或者vm.$set(target, propertyName/index, value)
-
-
如何监测数据中的数据?
-
通过包裹数据更新元素的方法实现,本质上就是做了两件事:
1、调用原生对应的方法对数据进行更新
2、重新解析模板,进而更新页面
-
-
在Vue修改数组中的某个元素可以使用如下方法
- push
- pop
- shift
- unshift
- splice
- reserve
- sort
- Vue.set()或者vm.$set()
-
特别注意:Vue.set()和vm.$set()不能给vm,或vm的跟数据对象添加属性