美文网首页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 引用的作用

相关文章