provide和inject
1.概述
在 Vue 3 中,provide和inject是用于组件之间进行深层次数据传递的一对组合。它们可以跨越多个组件层级来共享数据,而不需要通过层层传递props的方式。
2.provide 的使用
基本语法:在组件的setup函数或者Composition API相关的函数中使用provide。它接受两个参数,第一个参数是要提供的属性名称(通常是一个字符串),第二个参数是要提供的值。
<script setup>import { ref, provide } from 'vue'import Header from './header.vue'const web = {name:"夏天学编程",url:"www.xiatian.com"}provide('provideWeb',web)const user = ref(10)provide('provideUser',user)const userAdd = () => {user.value++}provide('provideFuncUserAdd',userAdd)
</script>
<template><div><header/>user:{{ user }}</div>
</template>
在这个例子中,provide函数将web、user属性和provideFuncUserAdd方法提供出去,user其值是一个ref类型的响应式数据。这个数据可以是任何类型,包括基本数据类型、对象、函数等。
3.inject 的使用
基本语法:同样在组件的setup函数中使用inject。它接受一个参数,即要注入的属性名称(与provide提供的名称相对应),并且返回注入的值。
<script setup>import { inject } from 'vue'import Nav from './nav.vue'const user = inject('provideUser')console.log(user)
</script><template><div><h1>我是header</h1><nav/></div>
</template>
<script setup>import { inject } from 'vue'const web = inject('provideWeb')console.log(web)const funcUserAdd = inject('provideFuncUserAdd')console.log(funcUserAdd)
</script><template><div><h1>我是nav</h1><button @click="funcUserAdd">添加用户</button></div>
</template>
在这里,组件通过inject获取了名为provideWeb的属性值和provideFuncUserAdd的方法。如果在组件树的上层有对应的provide提供了这个属性,那么这个组件就能成功获取到数据。
4.响应式数据处理
当provide提供的是响应式数据(如ref或者reactive包装的数据)时,在注入端也能保持响应式。例如,如果user在父组件中发生变化,子组件中注入的user也会相应地更新。
不过,需要注意的是,如果provide提供的是一个普通的非响应式对象,然后在子组件中修改这个对象的属性,这不会触发视图更新。因为 Vue 无法追踪这种非响应式数据的变化。
5.与 Vue 2 的对比
在 Vue 2 中,provide和inject主要用于选项式 API,并且在处理响应式数据时的机制略有不同。Vue 3 的Composition API中的provide和inject在使用方式上更加灵活,和ref、reactive等响应式 API 结合得更好,能够更方便地处理复杂的组件间数据共享和响应式更新。
6.应用场景
主题颜色、主题配置等共享数据传递,可以方便地将主题相关的数据从根组件传递到各个需要应用主题的子组件。
全局状态管理的替代方案(小规模):对于一些小型应用或者局部功能模块,可以使用provide和inject来共享和传递状态,避免引入复杂的状态管理库。不过对于大型应用,还是建议使用专门的状态管理库如 Vuex 或者 Pinia。