Vue2 响应式原理存在问题及解决办法

实现原理

对象类型:通过Object.defineProperty()对属性的读取、修改进行拦截(数据劫持)。

数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)。

大致原理:

let person = {
		name:'张三',
		age:18
			}

		let p = {}
		Object.	(p,'name',{
            //一些配置项
			// enumerable:true,
			// // enumerable:true, //控制属性是否可以枚举,默认值是false
			// writable:true, //控制属性是否可以被修改,默认值是false
			// configurable:true,//控制属性是否可以被删除,默认值是false
			get(){ 
				return person.name
			},
			set(value){ 
				console.log('有人修改了name属性,我要去更新界面!')
				person.name = value
			}
		})
		Object.defineProperty(p,'age',{
			get(){ 
				return person.age
			},
			set(value){ 
				console.log('有人修改了age属性,我要去更新界面!')
				person.age = value
			}
		}) 

存在问题

新增属性或者删除属性 通过Object.defineProperty()方法 页面不会自动更新

直接通过下标修改数组,界面不会自动更新

示例

<template>
  <div id="app">
    <h3>姓名:{{ person.name }}</h3>
    <h3>性别:{{ person.sex || "-" }}</h3>
    <h3>年龄:{{ person.age }}</h3>
    <el-button type="primary" size="small" @click="updateAge">更新年龄</el-button>
    <el-button type="primary" size="small" @click="addSex">新增性别属性</el-button>
    <el-button type="primary" size="small" @click="deleteName">删除年龄属性</el-button>
    <el-button type="primary" size="small" @click="updateArray">修改爱好数组值</el-button>
  </div>
</template>

<script>
export default {
  name: "App",
  components: {},
  data() {
    return {
      person: {
        name: "张三",
        age: 18,
        hobby: ['吃饭','睡觉','打游戏'],
      },
    };
  },

  mounted() {
    console.log(this.person);
  },

  methods: {
    updateAge() {
      this.person.age++;
      console.log(this.person.age);
    },
    addSex() {
      this.person.sex = "男";
      console.log(this.person.sex);
    },

    deleteName() {
      delete this.person.name;
      console.log(this.person.name);
    },
    updateArray() {
      this.person.hobby[0] = '吃零食';
      console.log(this.person.hobby[0]);
    },
  },
};
</script>

当我们点击更新年龄的时候:数据会变  页面会发生更新

当我们点击新增性别属性 删除年龄属性的时候: 数据会变页面不会发生更新

当我们点击修改爱好数组的时候 :数据会变页面不会发生更新

依次点击 结果如下

 

 

 Vue2 如何解决这一问题?

新增对象属性 修改数组 我们使用 Vue.set()或 this.$set()方法  

删除 我们使用 Vue.delete或 this.$delete()方法 

方法修改如下

methods: {
    updateAge() {
      this.person.age++;
      console.log(this.person.age);
    },
    addSex() {
      // this.person.sex = "男";
      this.$set(this.person,'sex','男')
      console.log(this.person.sex);
    },

    deleteName() {
      // delete this.person.name;
      this.$delete(this.person,'name',)
      console.log(this.person.name);
    },
    updateArray() {
      // this.person.hobby[0] = '吃零食';
      this.$set(this.person.hobby,0,'吃零食')
      console.log(this.person.hobby[0]);
    },
  },

结果如下:

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值