Vue3响应式原理

vue2.x的响应式

  • 实现原理

    • 对象类型:通过Object.defineProperty()对属性的读取、修改进行拦截(数据劫持)
    • 数组类型:通过重写更新数组的一系列方法来实现拦截(对数组的变更方法进行了包裹)
  • 存在的问题

    • 新增属性、删除属性 界面不会更新
    • 直接通过下标修改数组 界面不会自动更新
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    // 源数据
    let person = {
    name: '张三',
    age: 22
    }
    let p = {}
    Object.defineProperty(p, 'name', {
    configurable: true,
    // 读取name时调用
    get() {
    console.log('有人读取了name属性,我发现了,我要去更新界面!')
    return person.name
    },
    // 修改name时调用
    set(value) {
    console.log('有人修改了name属性,我发现了,我要去更新界面!')
    person.name = value
    }
    })

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

vue3.x的响应式

  • 实现原理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // 源数据
    let person = {
    name: '张三',
    age: 22
    }
    const p = new Proxy(person, {
    // 有人读取p的某个属性时调用
    get(target, propName) {
    console.log(`有人读取了p身上的${propName}属性`)
    return Reflect.get(target, propName)
    },
    // 有人修改p的某个属性 或给p追加某个属性时调用
    set(target, propName, value) {
    console.log(`有人修改了p身上的${propName}属性,我要去更新界面了!`)
    Reflect.set(target, propName, value);
    },
    // 有人删除p的某个属性时调用
    deleteProperty(target, propName) {
    console.log(`有人删除了p身上的${propName}属性,我要去更新界面了!`)
    return Reflect.deleteProperty(target, propName)
    }
    })
坚持原创技术分享,您的支持将鼓励我继续创作!