Vue provide inject
在 vue 嵌套组件之间,上级组件可以通过使用 provide 将值传送到深层的子组件内(通过inject接收)
<!-- fa.vue -->
<template>
<sub-component></sub-component>
</template>
<script>
import subComponent from './SubCompenent.vue'
export default {
components: {
subComponent
},
provide: {
'msg': 123
}
}
</script>
<!-- SubCompenent.vue -->
<template>
<div>{{ msg }}</div><!-- 123 -->
</template>
<script>
export default {
inject: ['msg']
}
</script>
<!-- provide: {} 无法直接传递 data 的值 -->
<script>
import { reactive } from 'vue'
import subComponent from './SubCompenent.vue'
export default {
components: {
subComponent
},
setup () {
return reactive({
msg: 'text'
})
},
provide: {
'msg': this.msg // 报错
},
}
</script>
<!-- 需要使用返回值的方式 -->
<script>
import { reactive } from 'vue'
import subComponent from './SubCompenent.vue'
export default {
components: {
subComponent
},
setup () {
return reactive({
msg: 'text'
})
},
provide () { // ok
return {
'msg': this.msg
}
}
}
</script>
<!-- 然而使用这种方式,将失去数据绑定 -->
<template>
<input v-model="msg" /><!-- 使用 v-model 修改 msg -->
<sub-component></sub-component><!-- 子组件内无变化 -->
</template>
<script>
import { reactive } from 'vue'
import subComponent from './SubCompenent.vue'
export default {
components: {
subComponent
},
setup () {
return reactive({
msg: 'text'
})
},
provide () {
return {
'msg': this.msg
}
}
}
</script>
<!-- 直接使用 ref 一样没有效果 -->
<script>
import { ref } from 'vue'
import subComponent from './SubCompenent.vue'
export default {
components: {
subComponent
},
setup () {
let msg = ref('text')
return {
msg
}
},
provide () {
return {
'msg': this.msg
}
}
}
</script>
<!-- 使用 computed 添加数据绑定 -->
<script>
import { computed, reactive } from 'vue'
import subComponent from './SubCompenent.vue'
export default {
components: {
subComponent
},
setup () {
return reactive({
msg: 'text'
})
},
provide () {
return {
'msg': computed(() => this.msg)
}
}
}
</script>
<!-- 子组件接受数据 -->
<template>
<div>{{ msg.value }}</div><!-- 使用.value拿取数据 -->
</template>
<script>
export default {
inject: ['msg']
}
</script>
<!-- 使用 provide() 进行传输, inject: [] 接收 -->
<script>
import { computed, ref, provide, reactive } from 'vue'
import subComponent from './SubCompenent.vue'
export default {
components: {
subComponent
},
setup () {
/*
let msg = ref('text') 有效,具有数据绑定 {{ msg.value }}
provide('msg', msg)
return {
msg
}
*/
let data = reactive({
msg: 'text'
})
// provide('msg', data.msg) 有效, 没有数据绑定,{{ msg }}
provide('msg', computed(() => data.msg)) // 有效,具有数据绑定 {{ msg.value }}
return data
},
}
</script>
<!-- 使用 provide() 进行传输, inject() 接收 -->
<!-- SubCompenent.vue -->
<template>
<div>{{ msg }}</div>
</template>
<script>
import { inject } from 'vue'
export default {
setup () {
let msg = inject('msg')
return {
msg
}
}
}
</script>
<!-- fa.vue -->
<script>
import { computed, ref, provide, reactive } from 'vue'
import subComponent from './SubCompenent.vue'
export default {
components: {
subComponent
},
setup () {
/*
let msg = ref('text') 有效,具有数据绑定 {{ msg }}
provide('msg', msg)
return {
msg
}
*/
let data = reactive({
msg: 'text'
})
// provide('msg', data.msg) 有效, 没有数据绑定,{{ msg }}
// 采用 . 属性没有数据绑定,需要直接采用 ref/reactive 的值,或者使用 computed
provide('msg', computed(() => data.msg)) // 有效,具有数据绑定 {{ msg }}
return data
},
}
</script>
<!-- 还能通过传递方法进行组件间的通信 -->
<!-- fa.vue -->
<template>
<input v-model="msg" />
<sub-component></sub-component>
</template>
<script lang="ts">
import { computed, ref, provide, reactive } from 'vue'
import subComponent from './SubCompenent.vue'
export default {
components: {
subComponent
},
setup() {
let data = reactive({
msg: 'text'
})
let change = (val: string) => {
data.msg = val
}
provide('msg', computed(() => data.msg))
provide('change', change)
return data
},
}
</script>
<!-- SubCompenent.vue -->
<template>
<div>{{ msg }}</div>
<button @click="change('change')">change</button>
</template>
<script>
import { inject } from 'vue'
export default {
setup () {
let msg = inject('msg')
let change = inject('change')
return {
msg,
input
}
}
}
</script>