我有一个使用范围插槽紧密耦合的父子组件。在父级中,一些数据是通过作用域插槽 prop(我们称之为 myScopedProp)从子级接收的。这一切都很好。在父级的作用域插槽中,我可以将 myScopedProp 作为参数传递给父级脚本中的某些方法,这是可行的。
现在如何在父级中存在的计算函数中访问此 myScopedProp,而不首先将其设置为数据?是否有内置的 vuejs 方式从父脚本访问 myScopedProp?
<!-- parent -->
<template>
<child>
<template #theSlot="{ myScopedProp}">
{{ parentMethod(myScopedProp) }} <-- this works fine
</template>
</child>
</template>
<!-- child -->
<template>
<slot name="theSlot" :myScopedProp="someChildValue">
</slot>
</template>
我目前通过将父级的方法传递给子级来解决此问题,该方法在父级的数据中设置 myScopedProp 值,但这感觉是错误且多余的,因为我已经通过作用域插槽传递了该值。
有很多选择如何做到这一点,我会使用
provide/inject
,因为组件是紧密绑定的。这称为提升状态。即使 v-model
也可以。
另一个选择:
defineExpose()
宏和组件引用:<script setup>
import { ref, provide, cloneVNode } from 'vue';
import Comp from './Comp.vue';
const slotProp = ref();
const $comp = ref();
const providedProp = ref();
provide('providedProp', providedProp);
const directiveProp = ref();
const vAssign = (_, {value}, vnode) => {
value(vnode.ctx.setupState);
};
</script>
<template>
<h1>{{ slotProp }}</h1>
<h1>{{ $comp?.prop }}</h1>
<h1>{{ providedProp }}</h1>
<h1>{{ directiveProp }}</h1>
<comp ref="$comp" #="{prop}" v-assign="comp => directiveProp = comp.internal">{{ (slotProp = prop, '') }}</comp>
</template>
Comp.vue:
<script setup>
import {ref, inject} from 'vue';
const prop = ref('Slot prop');
const exposed = ref('Exposed prop');
defineExpose({prop: exposed});
const provided = inject('providedProp');
provided.value = 'Provided prop';
const internal = ref('Internal prop');
const changeProps = () => {
[prop, exposed, provided, internal].forEach(r => r.value += ' changed')
};
</script>
<template>
<div>
<slot v-bind="{prop}"/>
<div>
<button @click="changeProps">Change props</button>
</div>
</div>
</template>