代码之家  ›  专栏  ›  技术社区  ›  JasonWilczak

如何在Vue中使用重复的命名插槽

  •  1
  • JasonWilczak  · 技术社区  · 6 年前

    我正在为Vuetify中的v-stepper开发一个包装组件。在本例中,我希望用户在使用组件时定义一个插槽,然后使用该插槽名称构建步骤。

    我需要有这个插槽存在的桌面视图和移动视图。我尝试使用v-if来隐藏if-mobile或not,但这会导致其他问题,所以我使用v-show,但在开发人员控制台中出现了一个错误:

    在同一渲染树中发现插槽“page6”存在重复- 这可能会导致渲染错误。

    下面是组件的结构 请注意,它们位于同一位置 .vue file

    <v-stepper-items>
        <v-stepper-content v-for="(item,index) in steps" :key="index" :step="index+1">
          <slot :name="item.slot"></slot>
        </v-stepper-content>
      </v-stepper-items>
    

    移动代码段

    <v-stepper-content :key="`${index}-stepContent-mobile`" :step="index+1">
        <slot :name="item.slot"></slot>
      </v-stepper-content>
    

    我试着做了一个插槽范围,但这似乎不适用于这里

    <v-stepper-items>
        <v-stepper-content v-for="(item,index) in steps" :key="index" :step="index+1">
          <template :slot-scope="item.slot"><slot :name="item.slot"></slot></template>
        </v-stepper-content>
      </v-stepper-items>
    

    可见 here

     <div slot="page5">
        <h4>Step 3</h4>
      </div>
    

    所以这里的关键是用户在使用组件时设置了一个插槽,但是组件将该插槽放在.vue文件的两个位置,一个在桌面部分,一个在移动部分。它需要有相同的名字,但是,因为它实际上是同一个插槽。。。

    npm install 然后 npm run dev 要看到它的实际作用: Vuetify-Simple-Wizard

    2 回复  |  直到 6 年前
        1
  •  1
  •   Richard Matsen    6 年前

    你可以用 Portal-Vue 将阶梯槽多播到两个位置(办公桌和手机)。

    isMobile 更改门户重新评估的值并将其内容移动到相应的节。

    <v-stepper v-model="stepStage" :alt-labels="!isMobile" :vertical="isMobile" >
      <div v-show="!isMobile">
        ...
        <v-stepper-items>
          <v-stepper-content v-for="(item,index) in steps" :key="index" :step="index+1">
            <portal-target :name="`portal-desk-${index}`" :key="index" slim></portal-target>
          </v-stepper-content>
        </v-stepper-items>
        ...
      </div>
      <div v-show="isMobile">
        <template v-for="(item,index) in steps">
          ...
          <v-stepper-content :key="`${index}-stepContent-mobile`" :step="index+1">
            <portal-target :name="`portal-mobile-${index}`" :key="index" slim></portal-target>
          </v-stepper-content>
          ...
        </template>
      </div>  
    
      <template v-for="(item, index) in steps">
        <portal :to="portalName(index)" :key="index">
          <template :slot-scope="item.slot"><slot :name="item.slot"></slot></template>
        </portal>
      </template>
    
    </v-stepper>
    
    computed: {
      portalName() {
        return (index) => {
          const section = this.isMobile ? 'mobile' : 'desk';
          return `portal-${section}-${index}` 
        }
      }
    },
    

    v-中频

    我不知道你发现了什么问题 v-if ,但它似乎与v-if一起工作 v-stepper-content

    <div v-show="!isMobile">
      ...
      <v-stepper-content v-if="!isMobile" v-for="(item,index) in steps" :key="index" :step="index+1">
      ...
    <div v-show="isMobile">
      ...
      <v-stepper-content v-if="isMobile" :key="`${index}-stepContent-mobile`" :step="index+1">
    
        2
  •  1
  •   Richard Matsen    6 年前

    你可以把部件分解成 SimpleWizardMobile公司 简单磁盘

    模板

    <template>
      <component :is="deviceType" 
        :completeStep="completeStep" 
        :previousStepLabel="previousStepLabel"
        :nextStepLabel="nextStepLabel"
        :steps="steps"
        :onNext="onNext"
        :onBack="onBack"
        :mobileBreakpoint="mobileBreakpoint"
        :theme="theme"
        ></component>
    </template>
    

    成分

    <script>
    import SimpleWizardDesk from './SimpleWizardDesk'
    import SimpleWizardMobile from './SimpleWizardMobile'
    ...
    computed: {
      deviceType() {
        return this.isMobile ? SimpleWizardMobile : SimpleWizardDesk
      }
    },