[vue3] provide 与 inject

312 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

组合API-provide和inject(依赖注入)

目标:掌握使用provide函数和inject函数完成后代组件数据通讯

provide和inject在Vue 2中已经被广泛应用,不是新鲜API,3.0重新认识一下它们两个。

一句话介绍:provide可以向所有子孙组件提供数据以及提供修改数据的方法,子孙组件用inject使用数据。

父级组件使用provide向下进行传递数据;
子级组件使用inject来获取上级组件传递过来的数据;

使用场景:

有一个父组件,里头有子组件,有孙组件,有很多后代组件,共享父组件数据。


作用:实现祖与后代组件间通信

  • 套路:父组件有一个 provide 选项来提供数据,后代组件有一个 inject 选项来开始使用这些数据
  • 具体写法:
//祖组件
setup(){
		......
	    let car = reactive({name:'奔驰',price:'40万'})
	    provide('car',car)
	    ......
	}
//后代组件
setup(props,context){
	......
    const car = inject('car')
    return {car}
	......
}

举个例子

<template>
  <div>
    <div>父子组件的交互</div>
    <button @click='money=200'>修改</button>
    <hr>
    <Child :money='money' @send-money='getMoney' />
  </div>
</template>

<script>
import Child from './Child.vue'
import { ref, provide } from 'vue'

export default {
  name: 'App',
  components: { Child },
  setup () {
     // 直接把数据传递出去
     provide('moneyInfo', 1000)
    const money = ref(100)
    const getMoney = (value) => {
      // value就是子组件传递回来的钱
      money.value = money.value - value
    }
    return { money, getMoney }
  }
}
</script>

后代组件

<template>
  <div>
     孙子组件:{{moneyInfo}}
  </div>
</template>
<script>
  import { inject } from 'vue'

export default {
  name: 'GrandSon',
  setup () {
     const moneyInfo = inject('moneyInfo')
     return { moneyInfo }
  }
}
</script>

子组件

<template>
  <div>
     子组件 {{money}} --- {{moneyInfo}}
  </div>
  <button @click='getMoney'>点击</button>
  <GrandSon />
</template>
<script>
import GrandSon from '@/GrandSon'
import { inject } from 'vue'
export default {
  name: 'Child',
  components: { GrandSon },
  // 子组件触发的自定义事件需要在emits选项中进行声明(直观的看到本组件触发了那些自定义事件)
  emits: ['send-money'],
  props: {
    money: {
      type: Number,
      default: 0
    }
  },
  setup (props, context) {
     const moneyInfo = inject('moneyInfo')
    // Vue3中,使用形参props获取所有父组件传递的数据
    // props的数据是只读的,不可以在子组件直接修改
    const getMoney = () => {
      console.log(props.money)
      // this.$emit('send-money', 50)
      // 向父组件传递数据50
      context.emit('send-money', 50)
    }
     return { getMoney, moneyInfo }
  }
}
</script>