美文网首页
2021-10-13-🦜🦜 vue中使provide中的数据变为

2021-10-13-🦜🦜 vue中使provide中的数据变为

作者: 沐深 | 来源:发表于2021-10-13 23:56 被阅读0次

    正常使用provide的方式:

    // 父组件中:
    provide:{
      for: 'demo'
    }
    

    这样子组件中无论多深的子组件都可以使用:

    // 子组件
    inject:['for'],
    data(){
      return{
        demo: this.for
      }
    }
    

    但是上面的写法有一定的问题,
    比如父组件中for变量的值如果我们是在mounted方法中请求后台数据再更改provide中for的值,
    那么在子组件中获取不到更改后的for的值。

    这时候就需要换一种写法:

    // 父组件中:
    data () {
      return {
        for: {}
      }
    },
    provide() {
        return {
          provObj: this.for
        };
      },
     mounted() {
       setTimeout(() => {
          this.for.fp= 'demo';
       }, 2000);
    }
    
    // 子组件中:
    inject:['provObj'],
    data(){
      return{
        demo: this.provObj.fp
      }
    }
    

    provide源码
    使用defineReactive, 让provide变为响应式的, 所以根元素属性 this.for 无效,必须监听下一级属性 this.for.fp

    export function initInjections (vm: Component) {
    const result = resolveInject(vm.$options.inject, vm)
    if (result) {
      observerState.shouldConvert = false
      Object.keys(result).forEach(key => {
        `defineReactive(vm, key, result[key])` // defineReactive
      })
      observerState.shouldConvert = true
      }
    }
    
    

    inject源码


    export function resolveInject (inject: any, vm: Component): ?Object {
      if (inject) {
      // inject 是 :any 类型因为流没有智能到能够指出缓存
        const result = Object.create(null)
        // 获取 inject 选项的 key 数组
        const keys = hasSymbol
          ? Reflect.ownKeys(inject).filter(key => {
            /* istanbul ignore next */
            return Object.getOwnPropertyDescriptor(inject, key).enumerable
          })
          : Object.keys(inject)
    
        for (let i = 0; i < keys.length; i++) {
          const key = keys[i]
          const provideKey = inject[key].from
          let source = vm
          while (source) {
            if (source._provided && provideKey in source._provided) {
              result[key] = source._provided[provideKey]
              break
            }
            source = source.$parent
          }
          if (!source) {
            if ('default' in inject[key]) {
              const provideDefault = inject[key].default
              result[key] = typeof provideDefault === 'function'
                ? provideDefault.call(vm)
                : provideDefault
            } else if (process.env.NODE_ENV !== 'production') {
              warn(`Injection "${key}" not found`, vm)
            }
          }
        }
        return result
      }
    }
    

    相关文章

      网友评论

          本文标题:2021-10-13-🦜🦜 vue中使provide中的数据变为

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