所属分类:web前端开发
vue只有一个根标签的原因:1、从查找和遍历DOM的角度来说,如果有多个根,那么查找和遍历DOM的效率会很低;2、从Vue本身来说,如果说一个组件有多个入口多个根,那就意味着用户的组件还可以进一步拆分成多个组件,进一步组件化,会降低代码之间的耦合程度。
前端(vue)入门到精通课程:进入学习
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API调试工具:点击使用
本教程操作环境:windows7系统、vue3版,DELL G3电脑。
vue为什么要求组件模板只能有一个根元素?下面一起来了解一下。
首先,我觉得这个问题要先从 Vue 的实例开始讲起。Vue 的实例一般都是长成下面这个样子,不同的只是 id 名的不同。
<div id="app"></div>
登录后复制
var vm = new Vue({
el: '#app',
data: {},
methods: {}
...
})
登录后复制
这就是 Vue 实例的基本结构,并不陌生。从这里可以看到,el 的指定是一个 id 为 app 的 div 元素,Vue 实例接管了对它的控制,减少了我们的 DOM 操作,需要被 vm 控制的元素全部加在它的内部。如果是需要控制不同的部分,这就需要多个 Vue 的实例来实现。疑问就来了,为什么需要不同的 Vue 实例来接管?
在 Vue 中指定 el 选项是给 Vue 实例指定一个 SPA 入口,有可能你的页面会长成像下面这样:
<div id="app"></div>
<div id="app1"></div>
<div id="app2"></div>
登录后复制
Vue 实例其实并不知道哪一个是入口,它应该接管哪一个部分,所以你要给它指定一个唯一的元素作为入口。每一个入口可以看作是一个 Vue 的类,Vue 要把这个入口进去的所有东西都取出来进行轮循渲染一遍,再把它重新挂载回页面中的 DOM 里面去。打给比方来说,一个 Vue 实例只拥有一个钥匙,一个钥匙只能开一把锁,但是页面上有很多把锁,如果你不说清楚它是哪把锁的钥匙,Vue 实例就不知道接下来要怎么做了。
当然,这只是一个比较浅显的理解。你可能会说,我指定几个入口让 Vue 实例去一个一个试就好了,我们往下看。
“虚拟 DOM”是我们对由 Vue 组件树建立起来的整个 VNode 树的称呼
学习 Vue 不得不说的就是2.0引入的Virtual DOM
,引入虚拟 DOM 后,在框架的内部将虚拟 DOM 树型结构与真实 DOM 做了映射,让我们不用再命令式的去操作 DOM。
引用里面的一张图片:
从这张图可以看出来虚拟 DOM 的一个渲染过程,那我们再回到本文的话题:为什么只能由一个根元素?
我们来看一个例子,假设你的 Vue 实例接管的 DOM 结构长成这个样子:
<div id="app">
<h1 id="h3">My title</h1>
<span>Content</span>
Other text
<!-- annotation text -->
</div>
登录后复制
它在浏览器内部的表现是一个这样的 DOM 树:
原谅我画图技术差,不过我想展示的效果达到了。从这可以看出它是一个树的结构,每个元素、文字、注释都是一个节点,虚拟 DOM 遵循的也是这样的一个树的数据结构。
回到正题,我们的指定的 el 也就是整个 DOM 结构的根。现在就很好说了,我们只有指定了唯一的 el 根元素,才能交给 Vue 实例在内部通过 createElement
方法生成一个对应的虚拟 DOM 结构映射真实的 DOM 元素进行操作渲染成真正的 HTML
换句话来说,可以把 el 对应的元素理解成 Vue 接管部分中的一个顶级标签,就像基本的 HTML 结构中,顶级标签是 <html></html>
,只能有一个这样的标签存在。对应到 Vue 中也是这样,如果你给它两个顶级标签,那么对应的 DOM 结构就无法生成了,这也就解释了之前的疑惑:为什么不能指定多个入口让 Vue 实例一个个的试。
不知道我这样的解释有没有说明白这个问题,如果没清楚我们下面再来看看。
现在实际的项目开发中,使用脚手架 vue-cli 开发居多,我们来看看。
vue-cli 的形式是单文件组件,一个 .vue 页面的基本结构是这样的:
<template>
<div></div>
</template>
<script>
export default {
}
</script>
<style>
</style>
登录后复制
在这里,<template>
标签下也只能有一个根元素 div,这是为什么?
在说这个话题之前,我们需要了解 H5 新标签 <template>
的一些特性,可以参考文档,它保证了内部的内容有效但不会被渲染。vue-cli 本质上是会把 .vue 文件通过 webpack 配置打包成一系列的 js/css 文件注入到一个 html 文件中交给浏览器进行解释执行,我们看一个打包好的文件目录:
这也就是说,每个 .vue 文件都会是一个 Vue 的实例,而 <template>
标签中的内容就是 Vue 实例接管形成虚拟 DOM 的那部分内容。如果在 template 下有多个 div,那么虚拟 DOM 树就没办法生成了。
其实这个问题归结到最后,也可以抽象为一个问题:为什么抽象出来的 DOM 树只能有一个根?
从查找和遍历的角度来说,如果有多个根,那么我们的查找和遍历的效率会很低。
如果一个树有多个根,说明可以优化,肯定会有一个节点是可以访问到所有的节点,那这个节点就会成为新的根节点。
再从 Vue 本身来说,如果说一个组件有多个入口多个根,那不就意味着你的组件还可以进一步拆分成多个组件,进一步组件化,降低代码之间的耦合程度。
【相关视频教程推荐:vue视频教程、web前端入门】
以上就是vue为什么只有一个根标签的详细内容,更多请关注zzsucai.com其它相关文章!