Gibt es eine Möglichkeit, die Bereitstellung/Injektion in einer dynamischen Vue3-Komponente außerhalb der Host-Einstellungsfunktion zu deklarieren?
P粉384366923
P粉384366923 2023-08-30 09:41:50
0
1
516
<p>Ich erstelle eine <code>Dynamische Komponente</code> in <code>Vue3</code>. Ich verwende <code>v-bind</code>, um <code>props</code> bereitzustellen. </p> <pre class="lang-js Prettyprint-override"><code><component :is='MyComponent' v-bind='myProps' /> </code></pre> <p>Ich möchte mit <code> Funktionalität bereitstellen/einbinden. Wie kann ich die von mir bereitgestellten Eigenschaften in die dynamische Komponente einfügen? Meine dynamische Komponente ruft <code>inject</code> in der Funktion <code>setup</code> auf und erwartet einen </code>-Wert für ihre untergeordnete Komponente. </p> <p>Obwohl dies auf Vue nicht dokumentiert ist, habe ich es erfolglos versucht: </p> <pre class="brush:php;toolbar:false;"><component :is='MyComponent' v-bind='myProps' :provide='myProvidedProps'/></pre> <p>Ich habe sogar versucht, das <code>provide</code>-Objekt in das <code>props</code>-Objekt einzufügen. </p>
P粉384366923
P粉384366923

Antworte allen(1)
P粉122932466

浏览完 Vue3 源代码后,无法直接在模板中向动态组件指示provide规范。必须在托管动态组件的父级的设置函数或选项中,或者在动态组件的设置或选项中调用它。

这两个选项是:

  1. 您在托管动态组件的组件上调用 provide
setup() {
  provide('message', 'hello')
}
<template>
  <component :is='myComponent' />
</template>

这对我不起作用,因为我的设置函数在我的动态组件被激活之前就被调用了;我还需要将组件类型和提供的值一起设置。

  1. 将要提供的项目作为 prop 发送到组件中,并让动态组件调用它们。
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)
  }
}

现在这有它的问题,因为每个动态组件现在都需要负责了解并调用传入的提供项。

解决方案1

解决每个组件需要了解所提供值的方法是创建一个提供值的中间组件。

可提供(中间组件)

<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>

解决方案2

更简洁的解决方案是创建一个包装器组件,类似于 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>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage