vue通信-provide&inject

发布时间 2023-06-19 22:15:45作者: Meer_zyh

刚完成一个需求,父组件开启一个任务,开启后孙组件显示一个执行按钮,在孙组件中点击执行按钮,再到父组件中执行任务并隐藏按钮;可以使用props和emit实现,因为组件层级较多,所以考虑使用provide&inject实现父组件和孙组件的通信;

以下代码记录实现过程:

父组件:Parent.vue

<template>
	<div>
    <child></child>
  	<btn @click="submitTask"></btn>
  </div>
</template>

<script>
export default {
  data() {
    return {
      btnShow: false // 传入孙组件用于显示按钮的属性
    }
  },
  provide() {
    return {
      btnShow: this.btnShow // 将data中的属性传入
      provideMethod: this.executeTask // 传入的方法,孙组件调用该方法,触发父组件中的方法执行
    }
  }
  methods: {
    submitTask() {
      this.btnShow = true; // 执行按钮,传入孙组件显示隐藏
    },
      
    // 执行任务并隐藏按钮
    executeTask() {
      this.btnShow = false;
      // 调用执行任务接口
      ...
    }
  }
}
</script>

子组件:Child.vue

<template>
	<div>
    <son></son>
  </div>
</template>

孙组件:Son.vue

<template>
	<div>
    <btn v-if="btnShow" @click="handleExecute">执行</btn>
  </div>
</template>
<script>
export default {
  inject: ['btnShow','provideMethod']
  methods: {
    handleExecute() {
      // 方法通信,父组件通过provide传入方法,执行传入的方法,触发父组件数据更新
      this.provideMethod()
      // 此处也可以通过eventBus实现
    },
  }
}
</script>

执行this.btnShow = true后发现孙组件执行按钮没有显示,查其原因发现改变了provide中的属性,不会实时传递到inject中,需要传递一个对象才能实现数据响应式,做如下修改:

父组件:Parent.vue

<script>
export default {
  data() {
    return {
      projectObj: {
        btnShow: false
      }
    }
  },
  provide() {
    return {
      projectObj: this.projectObj,
      provideMethod: this.executeTask
    }
  }
  methods: {
    submitTask() {
      this.projectObj.btnShow = true; 
    },
    // 执行任务并隐藏按钮
    executeTask() {
      this.projectObj.btnShow = false;
      // 调用执行任务接口
      ...
    }
  }
}
</script>

孙组件:Son.vue

<template>
	<div>
    <btn v-if="provideObj.btnShow" @click="handleExecute">执行</btn>
  </div>
</template>
<script>
export default {
  inject: ['btnShow','provideMethod']
  methods: {
    handleExecute() {
      // 方法通信,父组件通过provide传入方法,执行传入的方法,触发父组件数据更新
      this.provideMethod()
      // 此处也可以通过eventBus实现
    }
  }
}
</script>

实现功能,完结撒花!