provide/inject让同一棵组件树中的数据能够跨层级传递
provide: 提供数据
inject: 注入数据
provide-提供ref响应式数据
vue
<script lang="ts">
import { defineComponent, reactive, ref, provide, readonly } from 'vue'
export default defineComponent({
name: 'HomeView',
setup() {
const count = ref(0)
provide('HomeViewCount', count)
}
})
</script>
inject
vue
<template>
<div>
我是孙组件 {{ count }}
</div>
</template>
<script lang="ts">
import { defineComponent, inject, toRefs } from 'vue'
export default defineComponent({
name: 'son-page',
setup () {
const count = inject('HomeViewCount')
console.log(count, 'inject count')
// 修改了父组件提供的数据,这违背了数据单向流动的原则,
count.value = 100
return {
count
}
}
})
</script>
readonly禁止子组件修改父组件提供的数据
使用readonly,让子组件不能修改父组件提供的数据
vue
<script lang="ts">
import { defineComponent, reactive, ref, provide, readonly } from 'vue'
export default defineComponent({
name: 'HomeView',
setup() {
const count = ref(0)
provide('HomeViewCount', readonly(count))
}
})
</script>
provide-提供reactive响应式数据
vue
<script lang="ts">
import { defineComponent, reactive, ref, provide, readonly } from 'vue'
export default defineComponent({
name: 'HomeView',
setup() {
const HomeViewInfo = reactive({
title: 'provide和inject的使用',
author: 'zhangsan',
publishTime: '2023-01-01'
})
provide('HomeViewInfo', readonly(HomeViewInfo))
}
})
</script>
vue
<template>
<div>
<h2>
{{ title }}
</h2>
<p>{{ author }}</p>
<p>{{ publishTime }}</p>
</div>
</template>
<script lang="ts">
import { defineComponent, inject, toRefs } from 'vue'
export default defineComponent({
name: 'son-page',
setup () {
// 父组件数据变更时,子组件也会同时变更
const info = inject('HomeViewInfo')
return {
...toRefs(info)
}
}
})
</script>
provide-提供方法
vue
<script lang="ts">
import { defineComponent, reactive, ref, provide, readonly } from 'vue'
export default defineComponent({
name: 'HomeView',
setup() {
const HomeViewInfo = reactive({
title: 'provide和inject的使用',
author: 'zhangsan',
publishTime: '2023-01-01'
})
provide('HomeViewInfo', readonly(HomeViewInfo))
const setHomeViewInfoTitle = (value: string) : void => {
HomeViewInfo.title = value
}
provide('updateHomeViewInfoTitle', setHomeViewInfoTitle)
}
})
</script>
vue
<template>
<div>
<h2>
{{ title }}
</h2>
<p>{{ author }}</p>
<p>{{ publishTime }}</p>
</div>
</template>
<script lang="ts">
import { defineComponent, inject, toRefs } from 'vue'
export default defineComponent({
name: 'son-page',
setup () {
const info = inject('HomeViewInfo')
const updateHomeViewInfoTitle = inject('updateHomeViewInfoTitle')
updateHomeViewInfoTitle('我是新的标题')
return {
...toRefs(info)
}
}
})
</script>
组件层级比较深的时候,provide和inject的使用,会导致,不知道数据是从哪里过来的。
要合理的使用provide和inject,不要滥用。
在provide命名的时候,可以加一个前缀,比如 HomeViewInfo,表示来自HomeView模块。