Vue高级API - Provide/Inject

作者: 果汁凉茶丶 | 来源:发表于2019-04-19 11:51 被阅读6次

    官网传送门:inject  Vue2.2.0+

    # 背景

      关于Vue组件的通讯方式相信大家能倒背如流

    • 父子组件:通过prop$emit,【$parent$children
    • 非父子组件:Vuex实现,父子层层传递、中央事务总线Bus(建议在created钩子上开启监听)

    子实例可以用 this.$parent 访问父实例,子实例被推入父实例的 $children 数组中。应当节制地使用它们,其只是作为访问组件的应急方法。更推荐用 props 和 events 实现父子组件通信.

    Vue官网建议,在正常情况下,这两种方式已经能满足绝大多数甚至所有的业务需求,对于应用程序代码应优先使用它们处理。然而,还有一种主要为高阶插件/组件库提供的用例办法,即provide/inject,这对选项需要一起使用。

    # 功能

      通常情况下,组件向组件传递数据,可以采用父子props层层传递,也可以使用busVuex直接交互。在Vue2.2.0之后,Vue还提供了provide/inject选项

    这对选项允许一个祖先组件向其所有子孙后代组件注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。

      也就是说,在父组件只要声明了provide,在其子组件,孙组件,曾孙组件等能形成上下游关系的组件中交互,无论多深都能通过inject来访问provider中的数据。而不是局限于只能从当前父组件的prop属性来获取。注意他只做祖先通后代的单向传递的一个办法。有人这么形容:

    provide就相当于加强版父组件prop,可以跨越中间组件inject就相当于加强版子组件的props

    # 缺点

      官网不建议在应用中直接使用该办法,理由很直接:他怕你"管不好"

      设计项目,通常追求有清晰的数据流向和合理的组件层级关系便于调试和维护,然而这对选项支持任意层级都能访问,导致数据追踪比较困难。不知道那一层级声明了provide又或是哪些层级使用了inject。造成比较大的维护成本。因此,除组件库或高阶插件外,Vue建议用Vuex解决或其他办法处理。

    # 使用办法

    • provide 提供变量:Object | () => Object
    • inject 注入变量: Array<string> | { [key: string]: string | Symbol | Object }

      provide 选项应该是一个对象或返回一个对象的函数。 该对象包含可注入其子孙的属性。在该对象中,它支持ES6中Symbol作为key,但只在原生支持等环境下可工作。

      inject 选项可以是

    • 一个字符串数组
    • 一个对象,key为本地绑定名,value为:
      • 在可用的注入内容中搜索用的key,或
      • 一个对象,其 from 属性是在可用的注入内容中搜索用的keydefault属性是降级情况下使用的value

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

    # 案例展示

    在父组件中provide提供变量

    <template>
      <div>
        <p>{{ title }}</p>
        <son></son>
      </div>
    </template>
    <script>
      import Son from "./son"
      export default {
        name: 'Father',
        components: { Son },
        // provide选项提供变量
        provide: {
          message: 'provided by father'
        },
        data () {
          return {
            title: '父组件'
          }
        },
        methods: { ... }
      }
    </script>
    

    在子组件中,我们故意不使用任何父组件的信息

    <template>
      <div>
        <p>{{ title }}</p>
        <grand-son></grand-son>
      </div>
    </template>
    <script>
    import grandSon from "./grandSon "
    export default {
      name: "Son",
      components: { grandSon },
      data () {
        return {
          title: '子组件'
        }
      },
    };
    </script>
    

    在孙组件中,使用inject来注入

    <template>
      <div>
        <p>message:{{ message }}</p>
      </div>
    </template>
    <script>
    export default {
      name: "GrandSon",
      inject: [ "message" ],
      data () {
        return {
          title: '孙组件'
        }
      },
      methods: { ... }
    };
    </script>
    

    结果孙组件页面显示:
    message: provided by father
     

    # 结束语

      Vue官网虽说不建议使用,但只要用的合理,个人觉得还是能用的,毕竟他提供的便利。如果担心维护困难,为何不加点注释来解决呢,程序代码本身应该具备自解释能力,当其无法做到时,合理添加注释能简化大量理解困难,何乐而不为。坚持好的编程习惯,受益的不仅仅是一点点。

    相关文章

      网友评论

        本文标题:Vue高级API - Provide/Inject

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