P粉1229324662023-08-31 00:50:39
浏览完 Vue3 源代码后,无法直接在模板中向动态组件
指示provide
规范。必须在托管动态组件的父级的设置函数或选项中,或者在动态组件的设置或选项中调用它。
这两个选项是:
provide
。setup() { provide('message', 'hello') }
<template> <component :is='myComponent' /> </template>
这对我不起作用,因为我的设置函数在我的动态组件被激活之前就被调用了;我还需要将组件类型和提供的值一起设置。
function setComponent(someImportedComponent, providedValues) { myComponent.value = someImportedComponent myProps.value = { toProvide: providedValues } }
<template> <component :is='myComponent' v-bind='myProps' /> </template>
我的组件
setup() { for(let [key,value] of Object.entries(props.toProvide) ) { provide(key, value) } }
现在这有它的问题,因为每个动态组件现在都需要负责了解并调用传入的提供项。
解决每个组件需要了解所提供值的方法是创建一个提供值的中间组件。
可提供(中间组件)
<script setup lang="ts"> import {provide} from 'vue' const props = defineProps<{ is: any provide?: Record<string, any> [key: string]: any }>() if (props.provide) { for (const [key, value] of Object.entries(props.provide)) { provide(key, value) } } const _props = Object.fromEntries(Object.entries(props).filter(it => { return it[0] !== 'is' && it[0] !== 'provide' })) </script> <template> <component :is="is" v-bind="_props"/> </template>
像这样使用它:
<template> <providable :is="myComponent" :provide='toProvide' v-bind='myProps' /> </template>
更简洁的解决方案是创建一个包装器组件,类似于 keep-alive 的工作原理。目标组件只需放入默认槽
即可。
提供.vue
<script setup lang="ts"> import {provide} from 'vue' const props = defineProps<{ value: Record<string, any> }>() for (const [key, value] of Object.entries(props.value)) { provide(key, value) } </script> <template> <slot name="default"/> </template>
并像这样使用它:
<template> <provide value='toProvide'> <my-component v-bind='myProps' /> </provide> </template>