依赖注入

依赖注入就是父组件向后代组件传递数据,可以向子组件传递数据,也可以向孙子组件传递数据。

在父组件中使用 provide() 函数,向后代传递数据。

在后代组件中使用 inject() 函数,获取传递过来的数据。

接下来创建父子组件。

App.vue 作为父组件,新建 ComSon 组件作为子组件,在父组件引用子组件。

App.vue 代码如下。

<template>
  <div id="nav">
    <h1>父组件</h1>
    // 3.使用子组件
    <ComSon></ComSon>
  </div>
  <router-view />
</template>

<script>
// 1.引用子组件
import ComSon from './components/ComSon.vue';

export default {
  // 2.注册子组件
  components: {
    ComSon,
  },
};
</script>

父组件使用 provide() 方法向子组件传递数据,代码如下。

<template>
  <div id="nav">
    <h1>父组件</h1>
    <ComSon></ComSon>
  </div>
  <router-view />
</template>

<script>
import ComSon from './components/ComSon.vue';
import { provide } from 'vue';

export default {
  components: {
    ComSon,
  },
  setup() {
    // 2.在 setup 中使用 provide 向后代传递数据
    provide('msg', 'hello Vue3');
  },
};
</script>

子组件 ComSon.vue 接收父组件传递的数据,代码如下。

<template>
  <div>
    <h1>子组件</h1>
    <h1>接收父组件数据:{{ msg }}</h1>
  </div>
</template>

<script>
// 1.引入 inject
import { inject } from "vue";

export default {
  setup() {
    // 2.在 setup 函数中使用 inject 接收父组件传递的数据
    var msg = inject("msg");
    return {
      msg,
    };
  },
};
</script>

代码解析如下。

通过 provide() 函数向后代传递数据,可以把数据传递给子组件,只要是后代组件,都可以接收数据。

此时传递的数据不具有响应式,因为 msg 是普通字符串,但可以使用 ref 函数将其变成响应式数据,代码如下。

<template>
  <div id="nav">
    <h1>父组件</h1>
    //2.使用v-model做双向数据绑定
    <input type="text" v-model="newmsg" />
    <ComSon></ComSon>
  </div>
  <router-view />
</template>

<script>
import ComSon from "./components/ComSon.vue";
import { provide, ref } from "vue";

export default {
  components: {
    ComSon,
  },
  setup() {
    provide("msg", "hello Vue3");
    // 1.使用 ref 定义响应式数据
    var newmsg = ref(1);
    // 3.通过 provide 把响应式数据传递给子组件
    provide("newmsg", newmsg);
    return {
      newmsg,
    };
  },
};
</script>

ComSon.vue 子组件接收父组件传递的数据,代码如下。

<template>
  <div>
    <h1>子组件</h1>
    <h1>接收父组件数据:{{ msg }}</h1>
    <h1>接收父组件响应式数据:{{ newmsg.value }}</h1>
  </div>
</template>

<script>
import { inject } from "vue";

export default {
  setup() {
    var msg = inject("msg");
    // 接收父组件传递的响应式数据,并挂载到子组件中
    var newmsg = inject("newmsg");

    // 打印一下,看看是不是一个ref对象
    console.log("newmsg is ref:", newmsg.value); // 这里访问.value

    return {
      msg,
      newmsg,
    };
  },
};
</script>

此时修改父组件中 input 文本框中的值,子组件会随之修改。