我正在Vuetify中为v-stepper包装的组件。在这种情况下,我希望用户在使用组件时定义一个插槽,然后我将使用该插槽名称来构建步骤。
我需要在桌面视图和移动视图中都存在该插槽。我尝试使用v-if隐藏是否可移动,但这导致了其他问题,所以我使用了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文件中的2个位置中放置了该插槽,其中一个位于桌面区域,另一个位于移动区域。但是,它必须具有相同的名称,因为它实际上是相同的插槽...
这是我的带有代码的github项目,您可以将其下拉并运行npm install
,然后运行npm run dev
以查看其运行情况:Vuetify-Simple-Wizard
答案 0 :(得分:1)
您可以将组件分为 SimpleWizardMobile 和 SimpleWizardDesk ,然后在SimpleWizard中使用动态组件模板,
模板
<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
}
},
我确认您的开发工具仍在使用此结构,但尚未解决所有的js重构(只是对每个JS使用了相同的组件并重构了模板)。
答案 1 :(得分:1)
您可以使用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-if
上发现了什么问题,但似乎可以在v-stepper-content
上使用v-if
<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">