最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • vue2核心原理(简易) - $set和$del笔记

    正文概述 掘金(小桂summer)   2021-01-14   419

    前言

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

    示例

    <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>
    

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

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

    正题

    $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] = value
            return value
        }
    
        const ob = target.__ob__
    
        // 如果数据没有劫持 就是个普通对象 直接赋值 返回
        if (!ob) {
            target[key] = value
            return 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)) return
    
        delete target[key]
    
        if (!ob) return
    
        ob.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()
    
                    // 看这里 数组或者对象收集watcher
                    if (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)) return
        
        if (data.__ob__) return data.__ob__
    	// 对象和数组都可返回实例
        return new Observer(data)
    }
    


    起源地下载网 » vue2核心原理(简易) - $set和$del笔记

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元