美文网首页vue 组件
Vue组件通信—provide/inject

Vue组件通信—provide/inject

作者: 生爱_存在 | 来源:发表于2021-08-28 11:38 被阅读0次

    vue 开发中组件通信可谓是非常常见的操作的,而组件通信最常用的肯定是 props,但是props 使用于父子组件通信还比较方便,但是组件层级较多就时,props 操作起来就显得十分繁琐,也不便于书写;
    注:为了方便,我就直接把 inject 放在子组件中

    provide/inject 基本格式

    1. 父组件中 provide 格式
        <template>
          <div>
            {{a}}
            <test />
          </div>
        </template>
        <script>
        import test from './compoent/test.vue'
        export default {
          components: { test },
          name: 'showExcel',
            data () {
              return {
                // 定义一个对象,这里有一个小技巧,后面会讲到
                a: { b: 123 },
              }
            },
            provide () {
              return { a: this.a }
            },
        }
        </script>
      
    2. 子组件或孙子组件中 inject 基本格式
        <template>
          <div @click="changeA">{{a}}</div>
        </template>
      
        <script>
        export default {
          name: 'test',
          inject: ['a']
        }
        </script>
      
    3. 此时效果图: 效果图1

    provide/inject inject 接收不到 provide 实时数据情况

    1. 真实开发中数据往往会从后端获取,此时直接在 provide 中声明该值后就会发现在孙子组件中是获取不到实时更新的值的,此时就需要借助方法来获取;
        // 父组件
        provide () {
          return { a: this.a, getA: this.getA }
        },
        mounted () {
          setTimeout(() => {
            this.a.b = '77';
          }, 2000);
        },
        methods: {
          getA () { return this.a }
        }
      
        // 子组件
        inject: ['a', 'getA'],
        mounted () {
          this.$nextTick(() => {
            console.log(this.getA()); // {b:123,c:77}
          }, 2000);
        },
      
    2. 这里使用 setTimeout 来模拟网络请求,在改变父组件 cc 的值后,子组件中接收到的 cc 的依然是最初我们赋予的初始值 123456,并没有改变;但是 通过方法 getCC
      返回的值是我们请求到的最新值,并且在视图中也是同样的效果;
        // 父组件
        data () {
          return {
            // 定义一个对象,这里有一个小技巧,后面会讲到
            a: { b: 123 },
            cc: 123456,
          }
        },
        provide () {
          return { a: this.a, cc: this.cc, getCC: this.getCC }
        },
        mounted () {
          setTimeout(() => {
            this.cc = '456'
          }, 2000);
        },
        methods: {
          getCC () { return this.cc },
        }
      
        // 子组件
        inject: ['getCC', 'cc'],
        mounted () {
          setTimeout(() => {
            console.log('cc', this.cc); // cc 123456
            console.log('getCC', this.getCC()); // getCC 456
          }, 3000);
        },
      
    3. 效果图 效果图
    4. 我们再在 父组件的 getCC 方法中增加一个辅助参数看看打印效果
        // 父组件
        <template>
          <div>
            父组件中 cc:{{cc}}== getCC:{{getCC()}}
            <test />
          </div>
        </template>
        <script>
        import test from './compoent/test.vue'
        export default {
          components: { test },
          name: 'showExcel',
          data () {
            return {
              // 定义一个对象,这里有一个小技巧,后面会讲到
              a: { b: 123 },
              cc: 123456,
            }
          },
          provide () {
            return { cc: this.cc, getCC: this.getCC }
          },
          mounted () {
            setTimeout(() => {
              this.cc = '456'
            }, 2000);
          },
          methods: {
            getCC (a) { console.log('99999', a); return this.cc },
          }
        }
        </script>
      
        // 子组件
        <template>
          <div>
            子组件中 cc:{{cc}}== getCC:{{getCC('888')}}
          </div>
        </template>
      
        <script>
        export default {
          name: 'test',
          inject: [ 'getCC', 'cc'],
          mounted () {
            setTimeout(() => {
              console.log('cc', this.cc); // cc 123456
              console.log('getCC', this.getCC('000')); // getCC 456
            }, 3000);
          },
        </script>
      
    5. 我们再来看看控制台打印效果 控制台效果图
    6. 从控制台效果图可以看出,父组件和子组件视图模板中 getCC 方法各自执行了两次,因为初始渲染视图时执行一次,在更新 cc 时又各自执行了一次,所以视图中的数据会有变化;
      vue 中父子组件通信 js 引用的作用

    相关文章

      网友评论

        本文标题:Vue组件通信—provide/inject

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