当前位置:   article > 正文

vue2.0源码 Object.defineProperty实现数据响应_vue 使用object.defineproperty来实现响应式数组

vue 使用object.defineproperty来实现响应式数组

vue设计的初衷:
1.将视图view的状态和行为抽象化,使得UI和业务逻辑分开
2.mvvm:model=>view=>viewmodel

数据响应式原理
数据变更能够在视图中,就是数据响应式。vue2中利用Object.defineProperty()实现实时变化检测
1、数据响应式:监听数据变化并在视图中更新

// 实现defineReactive数据响应式
function defineReactive(obj, key, val) {
    // 如果当前的值是obj那么继续递归
    // 解决多层嵌套问题
    observe(val)

    Object.defineProperty(obj, key, {
        get() {
            console.log('get', key)
            return val
        },
        set(newVal) {
            if (newVal !== val) {
                console.log('set', key, newVal)
                // 为了防止重新对已经绑定的值再次重新赋值
                observe(val)
                // 赋值
                val = newVal
            }
        }
    })
}

// 遍历obj所有的key 对所有属性绑定响应式
function observe(obj) {
    if (typeof obj !== 'object' || obj === null) {
        return
    }

    // 遍历所有的key,做响应式处理
    Object.keys(obj).forEach(key => {
        defineReactive(obj, key, obj[key])
    })
}

// $set方法转发defineReactive
function set(obj, key, val) {
    defineReactive(obj, key, val)
}

// 绑定数据
const obj = {
    foo: 'foo',
    bar: 'bar',
    data: {
        a: 1,
        c: {
            h: 19999
        }
    }
}
observe(obj)


// 以下是修改值和赋值一些操作测试
// 有了以上封装好的方法后 下面修改对象obj就可以实现数据响应效果
obj.foo = '牛逼绑定1'
obj.bar = '牛逼绑定2'
obj.data.a = '哈哈哈哈哈'
obj.data.c.h = '多层递归监听到了没'

// 重新赋值对象
// defineReactive方法中重新调用observe方法递归实现绑定响应式
obj.data = {
    k: '重新赋值'
}

// 无法拦截直接添加新的属性
// 需要重新调用defineReactive设置值解决
// vue中使用的$set的方法其实就是调用defineReactive再次设置响应式值
obj.foo1 = '动态值1'
console.log(obj.foo1)

// 这种是可以实现响应式绑定的
set(obj, 'foo2', '动态值2')
console.log(obj.foo2)
  • 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
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76

defineReactive实现数据响应式在html的应用实例
xx.html

<div id="app"></div>
<script>
    function defineReactive(obj, key, val) {
        Object.defineProperty(obj, key, {
            get() {
                console.log('get', key)
                return val
            },
            set(newVal) {
                if (newVal !== val) {
                    console.log('set', key, newVal)
                    val = newVal

                    updated()
                }
            }
        })
    }

    // 测试
    const obj = {}
    defineReactive(obj, 'foo', '')

    setInterval(() => {
        obj.foo = new Date().toLocaleTimeString()
    }, 1000)

    // 更新函数
    function updated() {
        app.innerHTML = obj.foo
    }
</script>
  • 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

最终可以看到时间视图不断在更新
在这里插入图片描述
在这里插入图片描述

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号