美文网首页
provide / inject

provide / inject

作者: 如果俞天阳会飞 | 来源:发表于2019-11-18 20:44 被阅读0次

    类型:

    provide:Object | () => Object
    inject:Array<string> | { [key: string]: string | Symbol | Object }

    provide 和 inject 主要为高阶插件/组件库提供用例。并不推荐直接用于应用程序代码中。

    这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。
    provide 选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的属性。在该对象中你可以使用 ES2015 Symbols 作为 key,但是只在原生支持 Symbol 和 Reflect.ownKeys 的环境下可工作。
    inject 选项应该是:

    一个字符串数组,或一个对象,

    提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。

    // 父级组件提供 'foo'
    var Provider = {
      provide: {
        foo: 'bar'
      },
      // ...
    }
    
    // 子组件注入 'foo'
    var Child = {
      inject: ['foo'],
      created () {
        console.log(this.foo) // => "bar"
      }
      // ...
    }
    

    实现provide 和 inject 响应

    官网上说provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。

    要实现父子组件响应,父组件传递的数据类型必须是对象Object,子组件接收的数据类型必须是对象Object,其他数据类型都是不好使的

    案例
    父组件
    <template>
    <div>
        <inject></inject>
    </div>
    </template>
    <script>
    import Inject from '../components/inject'
    export default {
      name: 'Provide',
      data () {
        return {
          response: {
            a: 1
          }
        }
      },
      components: { Inject },
      provide () {
        return {
          response: this.response
        }
      }
    }
    </script>
    
    子组件
    <template>
        <div>
            {{response.a}}
        </div>
    </template>
    
    <script>
    export default {
      name: 'inject',
      inject: {
        response: {
          default () {
            return {}
          }
        }
      }
    }
    </script>
    
    使用场景:由于vue有$parent属性可以让子组件访问父组件。但孙组件想要访问祖先组件就比较困难。通过provide/inject可以轻松实现跨级访问祖先组件的数据

    一种最常见的用法是刷新vue组件
    app.vue

    <template>
      <div
        id="app"
      >
        <router-view
          v-if="isRouterAlive"
        />
      </div>
    </template>
    
    <script>
    export default {
      name: 'App',
      components: {
        MergeTipDialog,
        BreakNetTip
      },
      data () {
        return {
          isShow: false,
          isRouterAlive: true
      },
    
    // 父组件中返回要传给下级的数据
      provide () {
        return {
          reload: this.reload
        }
      },
      methods: {
        reload () {
          this.isRouterAlive = false
          this.$nextTick(() => {
            this.isRouterAlive = true
          })
        }
      }
    }
    </script>
    
    <template>
      <popup-assign
        :id="id"
        @success="successHandle"
      >
        <div class="confirm-d-tit"><span class="gray-small-btn">{{ name }}</span></div>
        <strong>将被分配给</strong>
        <a
          slot="reference"
          class="unite-btn"
        >
          指派
        </a>
      </popup-assign>
    </template>
    <script>
    import PopupAssign from '../PopupAssign'
    export default {
    //引用vue reload方法
      inject: ['reload'],
      components: {
        PopupAssign
      },
    methods: {
        // ...mapActions(['freshList']),
        async successHandle () {
          this.reload()
        }
      }
    }
    </script>
    

    这样就实现了子组件调取reload方法就实现了刷新vue组件的功能,个人认为它实现了组件跨越组件传递数据方法。

    相关文章

      网友评论

          本文标题:provide / inject

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