详解vue为什么要求组件模板只能有一个根元素


Posted in Javascript onJuly 22, 2019

我是在知乎上看到的这个问题,转念一想,用了大半年的vue,好像真的没有了解过:

‘为什么只能有且只有一个根元素'

于是我花了二十多分钟去找了一下答案......竟然没有找到答案....

好的现在我来说说我的理解,如果有不对的地方欢迎指出。

我觉得这个问题需要从两个方面来说起:

1.new Vue({el:'#app'})

2.单文件组件中,template下的元素div

一、当我们实例化Vue的时候,填写一个el选项,来指定我们的SPA入口:

let vm = new Vue({

el:'#app'
})

同时我们也会在body里面新增一个id为app的div

<body>

<div id='app'></div>
</body>

这很好理解,就是为vue开启一个入口,那我们不妨来想想,如果我在body下这样

<body>

<div id='app1'></div>
<div id='app2'></div>
</body>

Vue其实并不知道哪一个才是我们的入口,因为对于一个入口来讲,这个入口就是一个‘Vue类',Vue需要把这个入口里面的所有东西拿来渲染,处理,最后再重新插入到dom中。

如果同时设置了多个入口,那么vue就不知道哪一个才是这个‘类'。

二、当我们在webpack搭建的vue开发环境下,使用单文件组件时,你可能会这样:

<template>

<div class='component'></div>
</template>

那这里为什么template下也必须有且只能有一个div呢?

这里我们要先看一看template这个标签,这个标签是HTML5出来的新标签,它有三个特性:

1.隐藏性:该标签不会显示在页面的任何地方,即便里面有多少内容,它永远都是隐藏的状态;

2.任意性:该标签可以写在页面的任何地方,甚至是head、body、sciprt标签内;

3.无效性:该标签里的任何HTML内容都是无效的,不会起任何作用;

但是呢,你可以通过innerHTML来获取到里面的内容。

知道了这个,我们再来看.vue的单文件组件。其实本质上,一个单文件组件,本质上(我认为)会被各种各样的loader处理成为.js文件(因为当你import一个单文件组件并打印出来的时候,是一个vue实例),通过template的任意性我们知道,template包裹的HTML可以写在任何地方,那么对于一个.vue来讲,这个template里面的内容就是会被vue处理为虚拟dom并渲染的内容,导致结果又回到了开始 :既然一个.vue单文件组件是一个vue实例,那么这个实例的入口在哪里?

如果在template下有多个div,那么该如何指定这个vue实例的根入口?

为了让组件能够正常的生成一个vue实例,那么这个div会被自然的处理成程序的入口。

通过这个‘根节点',来递归遍历整个vue‘树'下的所有节点,并处理为vdom,最后再渲染成真正的HTML,插入在正确的位置

那么这个入口,就是这个树的‘根',各个子元素,子组件,就是这个树的‘枝叶',而自然而然地,这棵‘树',就是指一个vue实例了。

链接: https://github.com/haizlin/fe-interview/issues/457

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
学习ExtJS border布局
Oct 08 Javascript
JS实现商品倒计时实现代码
May 03 Javascript
浅析jQuery对select操作小结(遍历option,操作option)
Jul 04 Javascript
Jquery实现弹性滑块滑动选择数值插件
Aug 08 Javascript
基于原生JS实现图片裁剪
Aug 01 Javascript
jQuery树形插件jquery.simpleTree.js用法分析
Sep 05 Javascript
BootStrap 动态添加验证项和取消验证项的实现方法
Sep 28 Javascript
vue数据传递--我有特殊的实现技巧
Mar 20 Javascript
15个顶级开源JavaScript框架和库
Oct 10 Javascript
详解从react转职到vue开发的项目准备
Jan 14 Javascript
解决layui-open关闭自身窗口的问题
Sep 10 Javascript
JavaScript正则表达式验证登录实例
Mar 18 Javascript
微信小程序获取用户绑定手机号方法示例
Jul 21 #Javascript
Vue商品控件与购物车联动效果的实例代码
Jul 21 #Javascript
浅析Angular 实现一个repeat指令的方法
Jul 21 #Javascript
Node.js 实现简单的无侵入式缓存框架的方法
Jul 21 #Javascript
Vue中遍历数组的新方法实例详解
Jul 21 #Javascript
Vue项目中使用WebUploader实现文件上传的方法
Jul 21 #Javascript
jquery插件开发模式实例详解
Jul 20 #jQuery
You might like
模拟OICQ的实现思路和核心程序(二)
2006/10/09 PHP
php include加载文件两种方式效率比较
2010/08/08 PHP
让PHP以ROOT权限执行系统命令的方法
2011/02/10 PHP
php学习笔记 面向对象中[接口]与[多态性]的应用
2011/06/16 PHP
php获取url参数方法总结
2014/11/13 PHP
PHP通过微信跳转的Code参数获取用户的openid(关键代码)
2016/07/06 PHP
php实现XML和数组的相互转化功能示例
2017/02/08 PHP
PHP队列场景以及实现代码实例详解
2021/02/26 PHP
Javascript 兼容firefox的一些问题
2009/05/21 Javascript
StringTemplate遇见jQuery冲突的解决方法
2011/09/22 Javascript
jQuery动画出现连续触发、滞后反复执行的解决方法
2015/01/28 Javascript
详解VUE 定义全局变量的几种实现方式
2017/06/01 Javascript
js使用generator函数同步执行ajax任务
2017/09/05 Javascript
JS实现的透明度渐变动画效果示例
2018/04/28 Javascript
在Vue项目中使用d3.js的实例代码
2018/05/01 Javascript
解决vue this.$forceUpdate() 处理页面刷新问题(v-for循环值刷新等)
2018/07/26 Javascript
Spring boot 和Vue开发中CORS跨域问题解决
2018/09/05 Javascript
在Vuex使用dispatch和commit来调用mutations的区别详解
2018/09/18 Javascript
php结合js实现多条件组合查询
2019/05/28 Javascript
package.json配置文件构成详解
2019/08/27 Javascript
JavaScript实现京东快递单号查询
2020/11/30 Javascript
[02:57]2014DOTA2国际邀请赛 选手辛苦解说更辛苦
2014/07/10 DOTA
用python代码做configure文件
2014/07/20 Python
python文本数据相似度的度量
2018/03/12 Python
Python图像处理之图像的读取、显示与保存操作【测试可用】
2019/01/04 Python
Python基于matplotlib画箱体图检验异常值操作示例【附xls数据文件下载】
2019/01/07 Python
python使用pandas处理大数据节省内存技巧(推荐)
2019/05/05 Python
Python django框架应用中实现获取访问者ip地址示例
2019/05/17 Python
Python 必须了解的5种高级特征
2020/09/10 Python
H5调用相机拍照并压缩图片的实例代码
2017/07/20 HTML / CSS
HTML5去掉输入框type为number时的上下箭头的实现方法
2020/01/03 HTML / CSS
Betsey Johnson官网:妖娆可爱的连衣裙及鞋子、手袋和配件
2016/12/30 全球购物
汽车技术服务与营销专业推荐信
2013/11/29 职场文书
职工代表大会主持词
2014/04/01 职场文书
班主任个人工作反思
2014/04/28 职场文书
初中军训感想
2015/08/07 职场文书