Vue3 组件通信 provide 和 inject
父组件如果需要给子组件传递数据可以使用 props
。
父组件如果需要给子组件下的子组件传递数据也可以使用 props
把数据传给子组件,然后子组件再把数据通过 props
逐级的传给下面的子组件。
使用 props
逐级传递,如果组件层级不深的话也可以,但如果组件层级较深的话,使用这种层层转发的方式就不太好维护了。
使用 Vuex 和 Pinia 虽然也能解决上面的问题,但如果你只是简单传个数据的话,也没必要引入一个重量级的状态管理库。
Vue3 提供了 provide
和 inject
API,使用 provide
和 inject
,祖先组件给后代组件传递数据不再需要层层转发。
provide 分享数据
祖先组件可以使用 provide
把数据分享出去,后代组件可以使用 inject
来接收数据。
provide
分享数据:
<script setup>
import { provide, ref } from 'vue';
provide('message', 'Hello');
provide('count', ref(1));
</script>
provide
的第一个参数是名称ID,后代组件需要通过这个名称ID 来取到数据。第二个参数是数据,数据可以是普通的 String 或 Number 之类的,也可以是 ref
的响应式数据。
如果你不用 script setup
写法的话,provide
需要写在 setup
函数中:
import { provide, ref } from 'vue';
export default {
setup() {
provide('message', 'hello');
provide('count', ref(1));
}
}
inject 接收数据
后代组件可以使用 inject
来接收 provide
分享的数据。
下面使用 inject
接收上面分享的数据:
<template>
<div>
{{ message }}
{{ count }}
</div>
</template>
<script setup>
import { inject } from 'vue';
const message = inject('message');
const count = inject('count');
</script>
不使用 script setup
:
<template>
<div>
{{ message }}
{{ count }}
</div>
</template>
<script>
import { inject } from 'vue';
export default {
setup() {
const message = inject('message');
const count = inject('count');
return { message, count };
}
}
</script>
入口全局 provide
provide
可以在单个组件中使用,也可以在应用入口为所有组件提供数据。
下面再入口 main.js
使用 provide
:
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
app.provide('message', 'My blog misterma.com');
app.mount('#app');
所有的组件都可以使用 inject
访问到 main.js
的 provide
。
响应式和数据更改
接收方组件使用 inject
接收数据后是可以对数据进行更改处理的,但是为了便于维护,不建议在接收方更改数据。使用 provide
提供数据的组件在提供数据时可以同时提供一个函数来更改数据。
下面使用 provide
分享数据并提供一个更改数据的函数:
<script setup>
import { provide, ref } from 'vue';
const count = ref(1); // 要分享的数据
// 用于更改数据的函数
function changeCount() {
count.value ++;
}
provide('count', { count, changeCount });
</script>
上面使用 provide
分享了一个对象,对象中包含 count
数据和 changeCount
更改数据的函数。
接收方可以使用 changeCount
来更改 count
:
<script setup>
import { inject } from 'vue';
const count = inject('count');
// 调用 count 的 changeCount 来更改 count
count.changeCount();
// 在控制台输出 count
console.log(count.count.value);
</script>
如果你需要让接收方不能更改数据可以使用 readonly
函数:
<script setup>
import { provide, ref, readonly } from 'vue';
const count = ref(1);
provide('readonly-count', readonly(count));
</script>
接收方还是一样的使用 inject
接收。
版权声明:本文为原创文章,版权归 Mr. Ma's Blog 所有,转载请联系博主获得授权。
本文地址:https://www.misterma.com/archives/923/
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。