一个 Vue 模板可以有多个根节点(Fragments)?
2020/3/9 14:02:59
本文主要是介绍一个 Vue 模板可以有多个根节点(Fragments)?,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
作者:Anthony Gore
译者:前端小智
来源:vuejsdevelopers
点赞再看,养成习惯本文
GitHub
https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了很多我的文档,和教程资料。欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。
如果我们试图创建一个没有根节点的Vue模板,比如这样:
<template> <div>Node 1</div> <div>Node 2</div> </template>
我们就会收到编译或运行时错误,因为模板必须具有单个根元素。
通常,我们通过在最外层包裹一层 div
来解决这个问题,但这个div
元素一般没有啥使用,就是让模板符合单根需求。
<template> <div><!--只是来包装一下--> <div>Node 1</div> <div>Node 2</div> </div> </template>
这样的方式通常问题不在,但是在某些情况下,拥有多根模板是必要的。在本文中,我们来探讨一下何时需要以及如何解决多根的问题。
渲染数组
某些情况下,可能需要组件渲染子节点数组以包含在父组件中。
例如,一些CSS特性需要非常特殊的元素层次结构才能正确工作,比如CSS grid
或flex
,不能在父元素和子元素之间使用包装器。
<template> <div style="display:flex"> <!-- 如果子组件有多包裹一层那么 flex 不能正常工作--> <FlexChildren/> </div> </template>
还有一个问题,在组件中添加包装元素可能会导致渲染无效的HTML。 例如,如果要构建table,则表行<tr>必
须仅具有用于子项的表单元格<td>
。
<template> <table> <tr> <!--使用div包装器会使这个HTML无效--> <TableCells/> </tr> </table> </template>
简而言之,单根需求意味着在Vue中将无法返回子元素的组件的设计模式。
Fragments
这个单根限制对于React也是一个问题,但是它在版本16中提供了一个称为fragments的功能。 要使用它,只需要将多根模板包装在特殊的React.Fragment
元素中:
class Columns extends React.Component { render() { return ( <React.Fragment> <td>Hello</td> <td>World</td> </React.Fragment> ); } }
这将使子组件没有多余包装,还有一个简洁的短语法<>
:
class Columns extends React.Component { render() { return ( <> <td>Hello</td> <td>World</td> </> ); } }
Vue中的 Fragments
那么 Vue 是否也会引入 fragments
?这可能不会很快,原因是虚拟DOM
差异算法依赖于具有单个根的组件。 根据Vue贡献者Linus Borg的说法:
“允许 fragments 需要对[diffing]算法进行重大更改...不仅要使其能够正常工作,而且还必须使其具有高性能。...这是一项非常繁重的任务”
具有渲染功能的函数组件
函数组件没有单根限制,因为它们不需要像有状态组件那样在虚拟DOM中进行区分。这意味着,如果组件只需要返回静态HTML,那么拥有多个根节点也没什么问题。
还有一个警告:我们需要使用渲染功能,因为vue-loader
当前不支持多根功能(尽管对此进行了讨论)。
export default { functional: true, render: h => [ h('tr', [ h('td', 'foo'), h('td', 'bar'), ]), h('tr', [ h('td', 'lorem'), h('td', 'ipsum'), ]) ]; }); ------------------------------------------- import TableRows from "TableRows"; new Vue({ el: '#app', template: `<div id="app"> <table> <table-rows></table-rows> </table> </div>`, components: { TableRows } });
使用指令技巧
还可以使用一种简单的方法来绕过单根限制。就是使用自定义指令,首先我们先所包裹的元素删除
之前的:
<parent> <wrapper> <child/> <child/> </wrapper> </parent>
中间步骤:
<parent> <wrapper/> <child/> <child/> </parent>
最终:
<parent> <!-- 删除 <wrapper/> --> <child/> <child/> </parent>
要使它正常工作有点棘手,这里可以使用由Julien Barbay
写的 vue-fragments 的插件。
vue-fragments
vue-fragments
可以作为一个插件安装到你的Vue项目中
import { Plugin } from "vue-fragments"; Vue.use(Plugin);
该插件注册了一个全局VFragment
组件,将其用作组件模板中的包装器,类似于React
片段的语法:
<template> <v-fragment> <div>Fragment 1</div> <div>Fragment 2</div> </v-fragment> </template>
我不确定这个插件在所有的用例中有多健壮——它看起来可能是脆弱的——但在我做的实验中,它工作得很好。
代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
https://vuejsdevelopers.com/2...
交流
文章每周持续更新,可以微信搜索「 大迁世界 」第一时间阅读和催更(比博客早一到两篇哟),本文 GitHub https://github.com/qq449245884/xiaozhi 已经收录,整理了很多我的文档,欢迎Star和完善,大家面试可以参照考点复习,另外关注公众号,后台回复福利,即可看到福利,你懂的。
这篇关于一个 Vue 模板可以有多个根节点(Fragments)?的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-05HTML 颜色
- 2024-10-05HTML 颜色名
- 2024-10-01AntDesign-Form-rules学习:轻松入门教程
- 2024-10-01classnames学习:轻松掌握前端中的类名管理
- 2024-09-30前端案例资料:新手入门必读教程
- 2024-09-30前端编程资料:新手入门必备教程
- 2024-09-30前端培训资料:新手入门必读教程
- 2024-09-30滚动吸顶项目实战:从入门到上手
- 2024-09-29HTML学习:span标签教程详解
- 2024-09-29HTML基础:button标签教程