一、想让后来添加的属性也能做到响应式VUE.set(vm._data.某个对象,添加的属性,给定的值)
注意:Vue.set()和vm.set() 不能给vm或者vm的根数据对象添加属性,也就是不能给vm本身添加属性。
div id="root">
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<h2>学生姓名:{{student.name}}</h2>
<h2>学生年龄:{{student.age.rAge}} -- {{student.age.sAge}}</h2>
<h2>学生朋友:朋友姓名--年龄</h2>
<ul>
<li v-for="(p, index) in student.friends" :key="index">
{{p.name}} - {{p.age}}
</li>
</ul>
<h2>学生爱好:</h2>
<ul>
<li v-for="(h, index) in student.hobby" :key="index">
{{h}}
</li>
</ul>
</div>
const vm = new Vue({
el:'#root',
data:{
name:'尚硅谷',
address:'北京',
student:{
name:'tom',
age:{
rAge:40,
sAge:29,
},
friends:[
{name:'jerry',age:35},
{name:'ccc',age:23},
{name:'coco',age:25}
],
hobby:["学习","唱歌"]
}
}
})
让后来添加的属性也能做到响应式:
Vue.set(target, propertyName/index, value)
//如想在student中添加一个sex属性 Vue.set(vm.student,'sex','男')
或
vm.$set(target, propertyName/index, value)
二,监测这些对象类型数据的原理
[ 因为vue之所以能进行监控到data的改变就是利用data中属性的get和set,就比如上面的friends我修改name,为name服务的set就调用,set里面的封装就重新解析模板,后面就开始解析模板然后对比差异 ]
在Vue的设计中对对象的数据进行了一个递归,查找对象中的每一个属性,并且对其进行数据代理,给每一个属性设有get
和set
方法,这样子当对象中的数据发生改变,那么Vue就会察觉并修改页面中的数据。
三,监测数组的原理
const vm = new Vue({
el:'#root',
data:{
name:'尚硅谷',
address:'北京',
student:{
name:'tom',
age:{
rAge:40,
sAge:29,
},
friends:[
{name:'jerry',age:35},
{name:'ccc',age:23},
{name:'coco',age:25}
],
hobby:["学习","唱歌"]
}
}
})
这里和上面监控对象不同在于:
对于friends来说,虽然friedns是一个数组,但是数组内部是对象,一共有三个对象,每一个对象都有内部属性的get和set方法,
而hobby是数组,数组内部是字符串元素,元素是没有get和set方法的
student: Object
age: Object【折叠起来了】
friends: Array(3)
0:
age: (...)
name: (...)
__ob__: Observer {value: {…}, dep: Dep, vmCount: 0}
get age: ƒ reactiveGetter()
set age: ƒ reactiveSetter(newVal)
get name: ƒ reactiveGetter()
set name: ƒ reactiveSetter(newVal)
[[Prototype]]: Object
1: {__ob__: Observer}
2: {__ob__: Observer}
length: 3
__ob__: Observer {value: Array(3), dep: Dep, vmCount: 0}
[[Prototype]]: Array
hobby: Array(2)
0: "学习"
1: "唱歌"
length: 2
__ob__: Observer {value: Array(2), dep: Dep, vmCount: 0}
[[Prototype]]: Array
name: "tom"
没有为数据进行设定get和set方法,这样即使我们是可以使用下标进行修改vm中hoddy的值,data中的hoddy的只进行改变了,但是vue是监控不到的,所以页面并不能进行实时监控更改数据。
[ 因为vue之所以能进行监控到data的改变就是利用data中属性的get和set,就比如上面的friends我修改name,为name服务的set就调用,set里面的封装就重新解析模板,后面就开始解析模板然后对比差异 ]
注意:这里有一个特殊的地方就是
vm._data.student.hobby[0]='上班'
'上班' =====》 这里页面并没有进行同步更改
vm._data.student.friends[0].name='lucky'
'lucky' =====》 这里更改后 hobby和 friends 都进行了同步更改【【这里还必须是friends真的有差异】】
!!!“这就说明了了在有set的方法的属性进行了更改后,会重新解析模板,同时也将hobby进行了更改”
!!:在修改数组的时候,我们只有通过数组的修改方法才能,修改方法有push、pop、shift、unshift、splice、sort、reverse
通过包裹数组更新元素的方式实现,本质就是做了两件事:
- 调整原生对应的方法对数组进行更新
- 重新解构模型,进而更新页面
如;
vm._data.student.hobby.push('升班')
3
==》
学生爱好:
xuexi
唱歌
升班
vm._data.student.hobby.push === Array.prototype.push
false
是vue自己写的push :
调用push方法
重新解析模板对比差异。。。