我正在尝试创建一个 Tabs
中的组件Vue 3 与此类似 question here .
<tabs>
<tab title="one">content</tab>
<tab title="two" v-if="show">content</tab> <!-- this fails -->
<tab :title="t" v-for="t in ['three', 'four']">{{t}}</tab> <!-- also fails -->
<tab title="five">content</tab>
</tabs>
不幸的是,当 Tab
出现时,建议的解决方案不起作用。里面的 s 是动态的,即如果 Tab
上有 v-if或当 Tab
s 使用 v-for
呈现循环 - 它失败了。我在这里为它创建了一个 Codesandbox,因为它包含
.vue
文件:https://codesandbox.io/s/sleepy-mountain-wg0bi?file=%2Fsrc%2FApp.vue
我试过使用
onBeforeUpdate
喜欢 onBeforeMount
,但这也不起作用。实际上,它确实插入了新选项卡,但选项卡的顺序已更改。最大的障碍似乎是似乎没有办法获取/设置
child
来自 Vue 3 中父级的数据。 (如 Vue 2.x 中的 $children
)。有人建议使用this.$.subtree.children
但后来强烈建议不要这样做(无论如何我尝试过都没有帮助我)。谁能告诉我如何制作
Tab
内Tabs
react 和更新 v-if
, 等等?
最佳答案
这看起来像是使用项目索引作为 v-for
的问题。循环的 key
.
第一个问题是你已经申请了v-for
的 key
在应该在父元素上的子元素上(在这种情况下是在 <li>
上)。
<li v-for="(tab, i) in tabs">
<a :key="i"> ❌
</a>
</li>
另外,如果 v-for
支持数组可以重新排列其项目(或删除中间项目),不要使用项目索引作为 key
因为索引不会提供始终如一的唯一值。例如,如果从列表中删除了 3 项中的第 2 项,则第三项将向上移动到索引 1,采用 key
以前被删除的项目使用过的。由于没有 key
列表中的 s 发生了变化,Vue 重用了现有的虚拟 DOM 节点作为优化,不会发生重新渲染。不错
key
在您的情况下选择是选项卡的 title
值,因为在您的示例中,每个选项卡始终是唯一的。这是您的新 Tab.vue
与 index
替换为 title
支柱:// Tab.vue
export default {
props: ["title"], 👈
setup(props) {
const isActive = ref(false)
const tabs = inject("TabsProvider")
watch(
() => tabs.selectedIndex,
() => {
isActive.value = props.title === tabs.selectedIndex
} 👆
)
onBeforeMount(() => {
isActive.value = props.title === tabs.selectedIndex
}) 👆
return { isActive }
},
}
然后,更新您的 Tabs.vue
使用标签页的模板 title
而不是 i
:<li class="nav-item" v-for="tab in tabs" :key="tab.props.title">
<a 👆
@click.prevent="selectedIndex = tab.props.title"
class="nav-link" 👆
:class="tab.props.title === selectedIndex && 'active'"
href="#" 👆
>
{{ tab.props.title }}
</a>
</li>
demo
关于javascript - 如何在 Vue 3 中访问 $children 以创建 Tabs 组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65553105/