# vue2动态更新响应式对应实现方法
# $set方法
如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。
Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
</head>
<body>
<div id="app">
<div v-for="item in arr">{{item}}</div>
<button @click="go">go</button>
</div>
</body>
</html>
<script src="vue.js"></script>
<script type="text/javascript">
var app= new Vue({
el:"#app",
data:{
arr:[1,2,3,4]
},
methods:{
go(){
Vue.set(this.arr,2,'2009')
}
}
});
</script>
# 延伸解决vue2对象新增属性的解决办法
- $set方法修改数据
- this.$forceUpdate():强制页面更新,这样修改后的如this.arr[3]=1000把新增的值更新到页面
- this.someObject = Object.assign({},this.someObject,{newProperty1:1,newProperty2:2 ...})
# vue.delete删除
Vue.delete( target, propertyName/index )
删除对象的 property。如果对象是响应式的,确保删除能触发更新视图。这个方法主要用于避开 Vue 不能检测到 property 被删除的限制,但是应该很少会使用它。
- 调用$set和$delete修改会更改dep的数量,更方便去notify,如果直接$delete删除了data里的test的f1属性,[删除了一个dep]直接再添加f1,如果是对象类型,则无法监控。(如f1改成了数组,push了会没反应),而使用$set[添加回一个dep]添加的则是有响应式的。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="../../dist/vue.js"></script>
</head>
<style>
*{
margin:0;
padding:0
}
.red{
width:300px;
border:1px solid red;
}
</style>
<body>
<div id='app'></div>
</body>
</html>
<script type="text/javascript">
let app =new Vue({
el:'#app',
data:{
t1:1000,
arr:[1,2,3,5,6],
test:{
f1:11
}
},
template:`
<div class='red'>
<div>{{t1}}</div>
<button @click='add'>add</button>
<div>{{arr}}</div>
<button @click='addarr'>changearr</button>
<button @click='del'>delete</button>
<button @click='f1again'>again</button>
<button @click='f1arr'>f1arr</button>
{{test.f1}}
</div>
`,
methods:{
add(){
this.t1++;
this.test.f1++;
// console.log(this.$data,'$data')
},
addarr(){
let tem =this.arr.length+1
this.arr.push(tem)
},
del(){
// console.log(this.$data,'$data')
this.$delete(this.test,'f1')
this.test.f1=[-1,2,3]
setTimeout(()=>{
this.test.f1.push('666')
},2000)
// this.$set(this.test,'f1',10)
},
f1again(){
this.$set(this.test,'f1',10)
this.test.f1=[1,2,3]
setTimeout(()=>{
this.test.f1.push('999')
},2000)
},
f1arr(){
if(this.test.f1 instanceof Array){
this.test.f1.push(20000)
}
}
}
})
</script>