奇怪的模板和 vue.js 的根节点
Posted
技术标签:
【中文标题】奇怪的模板和 vue.js 的根节点【英文标题】:Oddity with templates and root node with vue.js 【发布时间】:2017-04-17 18:43:08 【问题描述】:我认为这可能是我偶然发现的错误,不确定。我收到一个组件的 Vue.js 警告:
vue.js:2611 [Vue 警告]:不能使用
<template>
作为组件根元素,因为它可能包含多个节点:
问题似乎是这样的:
<template id="tpl-field">
<template v-if="fieldType==='checkbox-inline'">
<label class="checkbox-inline">[SNIP]</label>
</template>
<template v-else>
[SNIP]
</template>
</template>
所以我有两个模板节点,这似乎是它阻塞的多个节点(当然每个模板节点只包含一个节点)。然而,这是 Vue 中的 if-else - 如果其中一个节点存在,则另一个节点在逻辑上不存在。
这里的问题演示:https://jsfiddle.net/jonmor51/Ldz3k0jp/1/。如果我将所有内容都包装在一个 div 中,它就可以工作。但是没有,它会失败。 (不幸的是,在我想使用它的上下文中,即对于 Bootstrap 网格中的内联复选框,包装在 div 中会破坏事情)。
【问题讨论】:
【参考方案1】:有用的东西 - 只需使用 div display: contents 作为组件的根,浏览器将忽略该元素并将子元素(可能很多)视为上层 dom 元素的子元素
<div style="display: contents">
<template v-if="...">
<template v-for="..."> ...
</template>
<template v-if="...">
</template>
</div
甚至可以在桌子内使用!
【讨论】:
【参考方案2】:内部template
s 直子,是单元素吗?如果是这样,您只需删除内部template
s 并将v-if
移动到label
。
或者,只是使用span
而不是div
作为您的快速修复,这不会破坏内联元素的样式。
【讨论】:
你是对的,这很有趣。如果我将 v-if 和 v-else 移动到包含的元素,则没有问题,即使表面上存在相同的情况(即两个替代根元素,这次是 div 不是模板)。所以看起来它只是导致问题的模板。 jsfiddle.net/jonmor51/Ldz3k0jp/3 @JohnMoore 当我建议删除template
s 时我实际上并没有尝试过...所以事实证明vue 可以正确判断v-if
时是否会有一个根元素用来。而template
只是不允许作为 root 用户,vue 直接发出警告,而不分析最终渲染的内容。【参考方案3】:
不确定这是否会解决您的引导问题...但您可以使用 <transition>
标记包装内部模板并为每个模板设置一个键。
请检查这个工作小提琴
https://jsfiddle.net/AldoRomo88/7c7znu3p/
【讨论】:
是的,这似乎很好地完成了这项工作。它也可以在没有“密钥”的情况下完成,那么为什么需要“密钥”呢?我可能会接受这个,即使它有点杂乱无章的感觉(这不是过渡的目的),但它至少让我感动! 我收到警告,但是转换不能与列表一起使用。 ;-) 在我看来 vue.js 开发人员把事情搞砸了。 @Drachenfels 确信这是因为您想同时在转换标记内渲染多个 dom 元素。在应用 v-if else 等条件后,必须只渲染一个元素,或者您需要使用将元素包装在附加标签中的转换组。顺便说一句,这太烦人了:我遇到了问题,几分钟后我考虑使用转换标签,然后出现下一个问题,我意外地找到了上一个任务的解决方案:|以上是关于奇怪的模板和 vue.js 的根节点的主要内容,如果未能解决你的问题,请参考以下文章
给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用