美文网首页
vue.js入门(七,provide / inject)

vue.js入门(七,provide / inject)

作者: 感觉不错哦 | 来源:发表于2019-10-14 11:06 被阅读0次

    组件之间的新通信,适用于分支子组件之间,比如爷爷A下面的儿子BC,B下面的儿子E跟C下面的儿子F之间的通信(EVent Bus 早期都是使用如此,之前文章有demo)

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

    写个简单的Demo(并不推荐使用,仅仅介绍使用方法,provide inject 会有一个类似冒泡的特性,数据源有可能在中间被”“打断”,甚至是有可能被组件库中的组件打断,或者打断组件库中的provide,不利于维护 )

    <template>
      <div>
      
        <hr/>
            <ChildrenA/>
            <ChildrenB/>
      </div>
    </template>
    
    <script>
    import ChildrenA from './components/ChildrenA'
    import ChildrenB from './components/ChildrenB'
    export default {
      components: {
        ChildrenA,
        ChildrenB
      }
    
    }
    </script>
    
    <style>
    
    </style>
    

    代码很简单,首先引入 A B 两个子组件,

    A B 没其他代码,仅仅是进入子组件,使其C D成为孙子组件

      provide(){
        return{
          foo:{
            name:'Vue'
          }
        }
      }
    

    在App.vue的主组件申明,接下来我在C D 孙组件中接受

    <template>
        <div>
        {{foo.name}}
        </div>
    </template>
    
    <script>
    export default {
    inject:['foo']
    }
    </script>
    
    <style>
    
    </style>
    

    使用inject接受,可以看到与props接收很类似,那么就可以直接在上方使用插值显示了

    那么inject也可以类似prop一样做一些处理

    inject:{
            foo: {
                from: 'foo',
                default: () => [1, 2, 3]
            }
        }
    

    如果是基础类型的话,default直接设置就行,并且此时没有provide的存在也可以使用(但是没有你用个啥)

    这里有个from字段,这个是为了防止属性名重复一些操作

    <template>
        <div>
        {{foos.name}}
        </div>
    </template>
    
    <script>
    export default {
            inject:{
                foos: {
                    from: 'foo',
                    default: () => [1, 2, 3]
                }
            }
    }
    </script>
    
    <style>
    
    </style>
    

    这样哪怕我这边接受的是foos,但是数据来源还是foo

    如果你的模板是函数式组件的话,就不能使用插值来获取了

    D孙子组件

        <template functional>
            <div>
                {{injections.foo.name}}
            </div>
        </template>
    
        <script>
        export default {
        inject:{
            foo:{
                default:()=>{}
            }
        }
        }
        </script>
    
        <style>
    
        </style>
    

    函数式组件这块后面可能会拎出来写一篇(主要是目前自己理解不是很好,怕误人子弟)

    <template>
      <div>
      
         <hr>
            <ChildrenA/>
            <ChildrenB/>
            <hr>
    <button @click="change">Change</button>
      </div>
    </template>
    
    <script>
    import ChildrenA from './components/ChildrenA'
    import ChildrenB from './components/ChildrenB'
    export default {
      components: {
        ChildrenA,
        ChildrenB
      },
    
      data(){
        return{
          name:'Vue'
        }
      },
      provide(){
        return{
          foo:{
            name:this.name
          }
        }
      },
      methods:{
        change(){
          this.name='newVue'
        }
      }
    
    }
    </script>
    
    <style>
    
    </style>
    

    接下来写一个方法,让他改变,那么我在data中声明一个name,此时通过change改变这个name,但是很遗憾无法改变!(当然值是改变了,但是没法更新,因为此时子组件接受的数据并不是响应式)

    直接给foo一个响应式返回(直接返回当前实例)

      provide(){
        return{
          foo:this
        }
      },
    

    此时就同时修改成功了

    有一种情况就不演示了,就是如果我在父组件B的时候也调用一个provide,那么孙子组件是在冒泡找到这个数据的时候就停止了(所以这种情况先问过老大再使用吧!)

    相关文章

      网友评论

          本文标题:vue.js入门(七,provide / inject)

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