# 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>

最后更新: 10/29/2021, 5:38:12 PM