美文网首页
vue源码 (2.响应式原理)

vue源码 (2.响应式原理)

作者: 奇怪的双子座 | 来源:发表于2021-10-22 22:38 被阅读0次

    1.props[keyname]优先级为什么高于methods[keyname]

    function initMethods (vm: Component, methods: Object) {
      const props = vm.$options.props
      //判重处理 props上key 优先 methods
      for (const key in methods) {
        if (process.env.NODE_ENV !== 'production') {
          if (typeof methods[key] !== 'function') {
            warn(
              `Method "${key}" has type "${typeof methods[key]}" in the component definition. ` +
              `Did you reference the function correctly?`,
              vm
            )
          }
          //**********************************主要是在此处**********************************
          if (props && hasOwn(props, key)) {
            warn(
              `Method "${key}" has already been defined as a prop.`,
              vm
            )
          }
          if ((key in vm) && isReserved(key)) {
            warn(
              `Method "${key}" conflicts with an existing Vue instance method. ` +
              `Avoid defining component methods that start with _ or $.`
            )
          }
        }
        vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm)
      }
    }
    

    2.vue中是如何实现props的代理的或者说为什么实用this[propsKey]可以访问到this._props.propsKey

     //initProps方法中调用
    if (!(key in vm)) {
        proxy(vm, `_props`, key)
    }
    
    const sharedPropertyDefinition = {
      enumerable: true,
      configurable: true,
      get: noop,
      set: noop
    }
    
    export function proxy (target: Object, sourceKey: string, key: string) {
      sharedPropertyDefinition.get = function proxyGetter () {
        return this[sourceKey][key]
      }
      sharedPropertyDefinition.set = function proxySetter (val) {
        this[sourceKey][key] = val
      }
      Object.defineProperty(target, key, sharedPropertyDefinition)
    }
    

    3.computed实现缓存的原理

      //computed中 initComputed中,本质是通过watcher实现的,每一个computed对象访问的时候相当于是watcher[key]。
     // const computedWatcherOptions = { lazy: true }
    function initComputed (vm: Component, computed: Object) {
      // $flow-disable-line
      const watchers = vm._computedWatchers = Object.create(null)
      // computed properties are just getters during SSR
      const isSSR = isServerRendering()
      //便利computed中的对象 
      for (const key in computed) {
        const userDef = computed[key]
        const getter = typeof userDef === 'function' ? userDef : userDef.get
        if (process.env.NODE_ENV !== 'production' && getter == null) {
          warn(
            `Getter is missing for computed property "${key}".`,
            vm
          )
        }
    
        if (!isSSR) {
          // create internal watcher for the computed property.
          
           // ****************//实例化一个watch 所以 computed 时通过watch实现的*****************
          watchers[key] = new Watcher(
            vm,
            getter || noop,
            noop,
            computedWatcherOptions
          )
        }
    
        // component-defined computed properties are already defined on the
        // component prototype. We only need to define computed properties defined
        // at instantiation here.
        if (!(key in vm)) {
          defineComputed(vm, key, userDef)
        } else if (process.env.NODE_ENV !== 'production') {
          if (key in vm.$data) {
            warn(`The computed property "${key}" is already defined in data.`, vm)
          } else if (vm.$options.props && key in vm.$options.props) {
            warn(`The computed property "${key}" is already defined as a prop.`, vm)
          }
        }
      }
    }
    
    function createComputedGetter (key) {
      return function computedGetter () {
        const watcher = this._computedWatchers && this._computedWatchers[key]
        if (watcher) {
          //**************************执行watcher.evaluate 执行computed.key 得倒执行结果赋值给watch,value**************************
          //一次渲染中指执行一次,在下一次更新时才会执行 参考watcher.update()
          if (watcher.dirty) {
            watcher.evaluate()
            //里边执行的是watch.get() watch.dirty=false ==>watch.getter()==>computed.key==>func
          }
          if (Dep.target) {
            watcher.depend()
          }
          return watcher.value
        }
      }
    }
    

    3.computed和watch有什么区别

      computed默认懒执行,不可更改,watch可配置
      使用场景不同(watch常用来异步处理)
    

    相关文章

      网友评论

          本文标题:vue源码 (2.响应式原理)

          本文链接:https://www.haomeiwen.com/subject/zbifaltx.html