Vue监测数据的原理
1.原理
1.vue会监视data中所有层次的数据
2.如何监测对象中的数据?
? 通过setter事件监视,且要在newVue时就传入要监测的数据
? (1).在对象后追加的属性,Vue默认不做响应式处理
? (2).如需给后添加的属性做响应式,需要使用以下API:
? Vue.set(target,propertyName/index,value)
? vm.$ser(target,propertyName/index,value)
3.如何监测数组中的数据?
? 通过包裹数组更新元素的方法实现,本质就是做了两件事:
? (1).调用原生对应的方法对数组进行更新
? (2).重新解析模板,进而更新页面
4.在Vue修改数组中的某个元素需要用到以下方法:
? 1.使用这些API:push(),pop(),shift(),unshift(),splice(),sort(),erverse()
? 2.Vue.set()或vm.$set
2.举例
我们现在提出这么一个需求:修改persons数组中的第一条数据
<div id="app">
<button @click="updateData">更新数据</button>
<ul>
<li v-for='(item,index) in persons'>
{{item.name}}--{{item.sex}}--{{item.old}}
</li>
</ul>
</div>
const vm = new Vue({
el:'#app',
data:{
persons:[
{id:001,name:'马冬梅',sex:'女',old:14},
{id:002,name:'周冬雨',sex:'女',old:45},
{id:003,name:'周杰伦',sex:'男',old:30},
{id:004,name:'张立伦',sex:'男',old:50}
],
},
methods:{
updateData(){ss
this.persons[0] = {id:001,name:'张振明',sex:'男',old:14}
}
}
})
我们直接对persons[0]进行修改
点击按钮 发现列表的数据并没有改变
我们在控制台输出persons[0]
会发现我们persons中的数据实际上已经改变了
那为什么没有渲染到页面呢?
我们查看vm中persons
会发现我们修改的数据并没有被Vue监测
但是我们定位到数组中对象的属性进行操作
this.persons[0].name = '张振明'
页面能成功渲染
我们查看vm中的persons
会发现每一个对象的属性都有对应的getter和setter,说明数据被Vue监测到了
Vue通过什么监测数据?
通过Object.defineProperty方法,运用get和set函数来对数据进行修改和解析
封装obeserver方法遍历data中的每一个属性,并对属性添加getter和setter,从而实现对数据的监控
通过以上例子我们可以知道,直接修改数组中的元素,Vue是不会监测的,因为Vue并没有对其进行数据监控,Vue只会监测数组中对象元素的属性
persons[0].name是对象中的属性,在创建实例对象中,Vue就对其添加了数据监测,所以当我们修改persons[0].name时,Vue会监听其修改的内容并将页面重新渲染
3.Vue.set方法
从上面的问题我们知道,直接修改没有被Vue监控的内容是不会引起页面重新渲染的,那我们如何解决这个问题呢?Vue提供给了我们set方法
1.set监视对象
通过Vue.set或者vm.$set我们可以给对象加入监视属性,从而达到修改数据重新渲染页面的效果
<div id="app">
<h1>学校信息</h1>
<h2>学校名称:{{name}}</h2>
<h2>学校地址{{address}}</h2>
<hr/>
<h1>学生信息</h1>
<h2>姓名{{student.name}}</h2>
<button @click="addSex">添加一个性别</button>
<h2>性别:{{student.sex}}</h2>
<h2>年龄:真实{{student.age.rAge}},对外{{student.age.sAge}}</h2>
<h2>朋友们</h2>
<ul>
<li v-for="(item,index) in student.friends">{{item.name}}--{{item.age}}</li>
</ul>
</div>
const vm = new Vue({
el:'#app',
data:{
name:'北京大学',
address:'北京',
student:{
name:'tom',
age:{
rAge:40,
sAge:18
},
friends:[
{name:'jerry',age:35},
{name:'tony',age:18}
]
}
},
methods: {
addSex(){
Vue.set(this.student,'sex','男')
}
},
})
页面效果是这样的
我们点击按钮,会发现列表成功渲染
原理是:点击按钮触发函数,在函数中使用vue.set对student添加‘sex‘属性,此时Vue会为其添加监视属性,并通过setter重新渲染页面
2.set监视数组
要对数组进行操作,Vue对原生的操纵数组的方法进行了重新封装,我们使用这些 API:push(),pop(),shift(),unshift(),splice(),sort(),erverse(),Vue会为数组配置监听属性,从而达到页面的重新渲染,我们也可以使用Vue.set方法来实现对数组的操作
<div id="app">
<h1>学校信息</h1>
<h2>学校名称:{{name}}</h2>
<h2>学校地址{{address}}</h2>
<hr/>
<h1>学生信息</h1>
<h2>姓名{{student.name}}</h2>
<button @click="addSex">添加一个性别</button>
<h2>性别:{{student.sex}}</h2>
<h2>年龄:真实{{student.age.rAge}},对外{{student.age.sAge}}</h2>
<button @click="addFriend()">修改第一个朋友的姓名</button>
<h2>朋友们</h2>
<ul>
<li v-for="(item,index) in student.friends">{{item.name}}--{{item.age}}</li>
</ul>
</div>
const vm = new Vue({
el:'#app',
data:{
name:'北京大学',
address:'北京',
student:{
name:'tom',
age:{
rAge:40,
sAge:18
},
friends:[
{name:'jerry',age:35},
{name:'tony',age:18}
]
}
},
methods: {
addSex(){
Vue.set(this.student,'sex','男')
},
addFriend(){
Vue.set(this.student.friends,0,{name:'zzm',age:35})
}
},
})
当我们点击添加修改朋友姓名的按钮
页面成功渲染
原理是:我们点击按钮执行函数,函数中使用vue.set或者splice对数组进行修改,从而达到我们想要的效果
|