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 77 78 79 80
| ### Proxy 相比于 defineProperty 的优势
1 Object.defineProperty 缺陷
◆ 只能对属性进行数据劫持,所以需要深度遍历整个对象 ◆ 对于数组不能监听到数据的变化
const arrayProto = Array.prototype export const arrayMethods = Object.create(arrayProto) // hack 以下几个函数 const methodsToPatch = [ 'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse' ] methodsToPatch.forEach(function (method) { // 获得原生函数 const original = arrayProto[method] def(arrayMethods, method, function mutator (...args) { // 调用原生函数 const result = original.apply(this, args) const ob = this.__ob__ let inserted switch (method) { case 'push': case 'unshift': inserted = args break case 'splice': inserted = args.slice(2) break } if (inserted) ob.observeArray(inserted) // 触发更新 ob.dep.notify() return result }) })
2 Proxy ◆ 原生支持监听数组变化, ◆ 并且可以直接对整个对象进行拦截(不只是属性)
let onWatch = (obj, setBind, getLogger) => { let handler = { get(target, property, receiver) { getLogger(target, property) return Reflect.get(target, property, receiver); }, set(target, property, value, receiver) { setBind(value); return Reflect.set(target, property, value); } }; return new Proxy(obj, handler); };
let obj = { a: 1 } let value let p = onWatch(obj, (v) => { value = v }, (target, property) => { console.log(`Get '${property}' = ${target[property]}`); }) p.a = 2 // bind `value` to `2` p.a // -> Get 'a' = 2
### v-model原理 v:model 在模板编译的时候转换代码 v-model 本质是 :value 和 v-on,但是略微有点区别。在输入控件下,有两个事件监听,输入中文时只有当输出中文才触发数据赋值 v-model 和:bind 同时使用,前者优先级更高,如果 :value 会出现冲突 v-model 因为语法糖的原因,还可以用于父子通信
|