1.Vue的深入响应式原理
vue是通过数据劫持和订阅发布来进行深入响应的,数据劫持指的是,vue通过es5的Object.defineProperty属性对data选项中的数据进行getter和setter设置,订阅发布指的是vue通过定义自定义事件将data的变化反映到视图上去,vue通过observer观察者对象反应数据的变化,然后通知vue生成新的Virtual DOM ,进而渲染视图。
2.Vue列表渲染的非响应式情况
(1)清空列表中的数据
响应式要达到的要求是,数据改变,视图改变,视图改变,数据也应该发生改变。
但在列表渲染时,会出现非响应式的情况。
例:如果我先定义了一个列表,然后清除列表内的数据。
<body>
<div id="app">
<button @click="remove">点击删除</button>
<ul>
<li v-for="item in list1" :key="item.id">
<p>{{item.name}}</p>
</li>
</ul>
</div>
</body>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
list1:[
{
id:1,
name:'张三'
},{
id:2,
name:'李四'
}
]
},
methods:{
remove(){
// this.list1.splice(0)
this.list1.length=0
}
}
})
</script>
清除列表内容,常见的方法有,
方法一:
this.list1.length=0
方法二:
this.list1.splice(0)
当使用上面两种方式时,可以发现此种操作时响应式的,但是改用下面的方式清空列表时,可以发现
this.list1.length=0
此种方法虽然清空了new Vue()中的列表数据,但是视图却没有发生变化,出现了非响应式的情况。
如下:
(2)利用索引设置列表中的数组项
例:先定义一个数组数据,然后修改该数组中的某一项的数据
<div id="app">
<button @click="modifyName">点击修改</button>
<ul>
<li v-for="item in list2">
<p>{{item}}</p>
</li>
</ul>
</div>
</body>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
<script>
new Vue({
el: '#app',
data:{
list2:[1,2,3]
},
methods:{
modifyName(){
// this.list1[0].name='尼古拉斯 涵哥'
this.list2[0]='尼古拉斯 强哥'
// Vue.set(this.list2,'0','尼古拉斯 仇总')
}
}
})
修改列表中的某一项的值通常有三种方法
this.list2[0]='尼古拉斯 强哥'
使用上面的方法修改时,只是单纯的修改了new Vue()中的列表数据,但是页面视图却没有发生改变,出现了非响应式的情况。如下
Vue中提供了两种方法,来进行列表数据的修改,格式如下
Vue.set(列表名,'索引','需要修改成的内容')
使用以下这两种方法,可以发现,均是响应式的。
方法一:
Vue.set(this.list2,'0','尼古拉斯 仇总')
方法二:
this.$set(this.list2,'0','尼古拉斯 仇总')