vue2核心原理(简易) - $set和$del笔记

前言

  • 主讲$set
  • vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时, 不会更新视图 这个时候可使用$set(删除能够用$del)
  • 其实每一个对象或者数组, 都加了个dep, 在数据劫持时, 对数据的值也要进行劫持(递归劫持数据), 若是是对象或者数据 将返回自己的Observer实例 再在getter中, 若是返回有数据, 让对象或   者数组dep收集watcher
  • 若是添加了数据 就会通知target.__ob__.dep.notify更新视图
  • 数组的添加和删除用的都是splice方法
  • $set和$del源码

示例

<div id="app">{{obj}} - {{arr}}</div><script>
  var vm = new Vue({      data: {          obj: {n: 1},          arr: [0]
      },
  })

  vm.$mount('#app')  setTimeout(() => {
      vm.$set(vm.obj, 'xxxx', 123456)
      vm.$set(vm.arr, 1, 100)
  }, 2000)</script>复制代码

正题

$set和$del方法

import { set, del } from './observer/index'Vue.prototype.$set = set
Vue.prototype.$del = del复制代码
/**
 * @description set
 */export function set(target, key, value) {// 数组采用splice方法if (Array.isArray(target)) {
        target.length = Math.max(target.length, key)
        target.splice(key, 1, value)return value
    }// 若是对象自己上已有 返回if (target.hasOwnProperty(key)) {
        target[key] = valuereturn value
    }const ob = target.__ob__// 若是数据没有劫持 就是个普通对象 直接赋值 返回if (!ob) {
        target[key] = valuereturn value
    }// 数据进行劫持defineReactive(ob.value, key, value)// 发布ob.dep.notify()return value
}/**
 * @description del
 */export function del (target, key) {if (Array.isArray(target)) {
        target.splice(key, 1)return}const ob = target.__ob__if (!target.hasOwnProperty(key)) returndelete target[key]if (!ob) returnob.dep.notify()
}复制代码

observe

class Observer {constructor(data) {this.value = data// 看这里this.dep = new Dep()Object.defineProperty(data, '__ob__', {          value: this,          enumerable: false})// 其余 ....}/**
 * @description 劫持对象数据
 */function defineReactive(data, key, value) {// 看这里 这里能够获取实例let childOb = observe(value)let dep = new Dep()Object.defineProperty(data, key, {enumerable: true,configurable: true,get() {if (Dep.target) {
                dep.depend()// 看这里 数组或者对象收集watcherif (childOb) {
                    childOb.dep.depend()// 多层数组[[[]]] if (Array.isArray(value)) { dependArray(value) }

                }

            }return value
        },set(newValue) {if (newValue !== value) {
                observe(newValue)
                value = newValue
                dep.notify()
            }
        }
    })
}export function observe(data) {if (!isObject(data)) returnif (data.__ob__) return data.__ob__	// 对象和数组均可返回实例return new Observer(data)
}复制代码

相关文章
相关标签/搜索