Vue3中的依赖注入与Vue2.x的其实差不多,就是需要写在setup()函数中。

依赖注入其实解决的就是一个传值的问题,通常传值是通过父组件props传递给子组件,一层的话其实还挺方便,但是当有多层结构,就需要一层传递给一层,这样组件的状态将变得很复杂.

Provide/Inject

  • 父组件通过provide将值/方法,传递给下级
  • 子组件通过inject来接收,可以做到越组件接收,解决了层层传递的麻烦
# Vue 3 beta
// 组父组件 GF.vue
<template>
  <Father />
  <button @click="changeTheme">更改主题</button>
</template>

<script>
import { provide, reactive, ref, readonly } from 'vue'
import Father from './Father'
export default {
  components: { Father },
  setup() {
    const name = reactive({
      title: '张三'
    })
    const changeName= () => {
      name.title = '李四'
    }
    provide('name', readonly(name))
//注:这里是传递name,因为这里的name才是响应式,不能单单只传name下的title的
    provide('changeName', changeName)
    return { name, changeName}
  }
}
</script>
  • 父组件中我引入了readonly,确保在子组件中无法改变name的值
// 父组件省略
// 父组间中有子组件 Child.vue
<template>
  Child: {{ name.title }}
   <div>
      <button @click="changeName">changename</button>
      <button @click="changeRead">子组件改值</button>
    </div>

</template>

<script>
import { inject } from 'vue'
export default {
  setup() {
 
    const name = inject('name', '这里第二个参数为默认值'),
          changeName = inject('changeName')
    const changeRead = () => {
      name.title = '改值成功'
    }
    return {
      name,
      changeName,
      changeRead
    }
  }
}
</script>

注:

  1. provider提供的数据可以用readonly来包一层响应式数据,ref/reactive,来确保无法在子组件中通过方法来改变值(不建议直接在子组件修改值,数据流动...)
  2. provider也可以传递方法给inject,这时候可以在子组件接收该方法,改变值,因为是父组件传递的方法,所以这里readonly不起作用

爬。