Vue2.x响应式原理

vue中的双向绑定是通过数据代理实现的,利用了Object.defindPropety()这个方法实现的(Vue2.x),这个方法重新定义了对象获取属性值(get)和设置属性值(set)

1.Object.defindProperty()

defindProperty(obj,prop,descriptor),这个方法有三个参数,第一个参数obj就是要定义的对象,第二个参数prop是对象的某个属性值,用字符串表示,第三个参数descriptor是用来控制prop的,先重点介绍第三个参数,它传入一个对象,对象包括以下的属性值:

value:给prop属性赋值

enumerable:控制属性是否可枚举,默认是false(控制该属性可否被遍历)

writeable:控制属性是否可以被修改,默认是false

configurable:控制属性是否可以被删除,默认是false

get():当程序读取prop属性的时候,get函数(getter)就会被调用

set():当程序修改prop属性的时候,set函数(setter)就会被调用

let number = 18
let person = {
    name: '张三',
    gender: '男'
}

Object.defineProperty(person, 'age', {
    get() {
        console.log('有人读取了age属性')
        return number
    },

    set(value) {
        console.log(`有人修改了age,值是${value}`)
        number = value
    }
})


console.log(person.age)
person.age = 20
console.log(person.age)

运行结果:

有人读取了age属性
18
有人修改了age,值是20
有人读取了age属性
20

2.数据代理

数据代理就是通过一个对象去代理另外一个对象中属性的操作(读/写),下面通过defineProperty方法实现一下数据代理:

let obj = {
    x:100,
    y:200
}

let obj2 = {}

Object.defineProperty(obj2, 'x', {
    get() {
        return obj.x
    },

    set(value) {
        obj.x = value
    }
})

Object.defineProperty(obj2, 'y', {
    get() {
        return obj.y
    },

    set(value) {
        obj.y = value
    }
})

console.log(`修改前obj2.x-->${obj2.x}`)
console.log(`修改前obj2.y-->${obj2.y}`)
obj2.x = 150
obj2.y = 120
console.log(`修改后obj.x-->${obj.x}`)
console.log(`修改后obj.y-->${obj.y}`)

通过obj2去代理obj属性的读取/修改,运行结果如下:

修改前obj2.x-->100
修改前obj2.y-->200
修改后obj.x-->150
修改后obj.y-->120

3.Vue中的数据代理

vue中的数据代理是通过vm实例对象来代理data对象中属性的读取和修改,这样的好处就是更加方便的操作data中的数据,基本的原理如下:

通过Object.defindProprerty()方法把data所有属性都添加到vm实例对象上,为添加到vm实例对象的每一个属性都指定一个getter/setter,在getter和setter内部去读写data中对应的属性。

<template>
  <div id="app">
    <h1>姓名:{{name}}---年龄:{{age}}</h1>
  </div>
</template>

<script>

export default {
  data() {
    return {
      name: '张三',
      age:18
    }
  }
}
</script>

435b6178ff9a4e618efc817cc06d71e5.png

模拟Vue2.x响应式过程

let data = {
    name:'张三',
    age:18
}
Object.defineProperty(data,'name',{
    get(){ //有人读取name时调用
        return data.name
    },

    set(value){ //有人修改name时调用
        console.log('有人修改了name属性,我发现了,我要去更新界面!')
        data.name = value
    }
})
Object.defineProperty(data,'age',{
    get(){ //有人读取age时调用
        return data.age
    },

    set(value){ //有人修改age时调用
        console.log('有人修改了age属性,我发现了,我要去更新界面!')
        data.age = value
    }
}) 

 每当要修改的Vue中data对应的属性值,就会触发vm中对应属性的set方法,同时去更新View层视图的值,这就是Vue中的响应式原理,但是defindProperty()方法中没有定义属性值添加/删除的方法,当要往data中添加或者删除的时候,defindProerty()无法完成响应式,在Vue3会完善改进这个问题。但在Vue2也提供了完整的解决方案,可通过Vue.set()/this.$set()添加属性,Vue.delete()/this.$delete()删除属性

 

总结:通过本文学习,我们知道了vue2.x数据的响应式是通过数据代理完成的,而数据代理主要核心就是Object.defindProperty()这个方法

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值