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)
}複製代碼

相關文章
相關標籤/搜索