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>