赞
踩
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)
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>
最终可以看到时间视图不断在更新
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。