首页  >  问答  >  正文

有没有办法在主机设置函数之外的 Vue3 动态组件中声明提供/注入?

<p>我正在 <code>Vue3</code> 中创建一个<code>动态组件</code>。我使用 <code>v-bind</code> 提供 <code>props</code>。</p> <pre class="lang-js prettyprint-override"><code><component :is='MyComponent' v-bind='myProps' /> </code></pre> <p>我想使用<code>提供/注入</code>功能。如何将我提供的属性放入动态组件中。我的动态组件在 <code>setup</code> 函数中调用 <code>inject</code>,并期望为其子组件<code>提供</code>值。</p> <p>虽然这在 Vue 上没有记录,但我没有成功尝试:</p> <pre class="brush:php;toolbar:false;"><component :is='MyComponent' v-bind='myProps' :provide='myProvidedProps'/></pre> <p>甚至尝试将 <code>provide</code> 对象放入 <code>props</code> 对象中。</p>
P粉384366923P粉384366923438 天前490

全部回复(1)我来回复

  • P粉122932466

    P粉1229324662023-08-31 00:50:39

    浏览完 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>

    回复
    0
  • 取消回复