详解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 相关文章推荐
javascript实现带节日和农历的日历特效
Feb 01 Javascript
jQuery中noConflict()用法实例分析
Feb 08 Javascript
js使用onmousemove和onmouseout获取鼠标坐标的方法
Mar 31 Javascript
JavaScript中的getDay()方法使用详解
Jun 09 Javascript
浅谈bootstrap源码分析之tab(选项卡)
Jun 06 Javascript
基于jQuery.validate及Bootstrap的tooltip开发气泡样式的表单校验组件思路详解
Jul 18 Javascript
javascript中使用未定义变量或值的情况分析
Jul 19 Javascript
Angular利用trackBy提升性能的方法
Jan 26 Javascript
解决vue单页路由跳转后scrollTop的问题
Sep 03 Javascript
koa2+vue实现登陆及登录状态判断
Aug 15 Javascript
详解elementui之el-image-viewer(图片查看器)
Aug 30 Javascript
eslint+prettier统一代码风格的实现方法
Jul 22 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
PHP 中执行系统外部命令
2006/10/09 PHP
PHP IN_ARRAY 函数使用注意事项
2010/07/24 PHP
PHP实现文件下载详解
2014/11/27 PHP
PHP中文编码小技巧
2014/12/25 PHP
PHP将session信息存储到数据库的类实例
2015/03/04 PHP
php生成不重复随机数、数组的4种方法分享
2015/03/30 PHP
PHP实现mysqli批量执行多条语句的方法示例
2017/07/22 PHP
PHP生成指定范围内的N个不重复的随机数
2019/03/18 PHP
Mozilla中显示textarea中选择的文字
2006/09/07 Javascript
js判断IE6/IE7/FF的代码[XMLHttpRequest]
2011/02/16 Javascript
JavaScript 匿名函数(anonymous function)与闭包(closure)
2011/10/04 Javascript
Ajax同步与异步传输的示例代码
2013/11/21 Javascript
利用JQuery制作符合Web标准的QQ弹出消息
2014/01/14 Javascript
js时间戳转为日期格式的方法
2015/12/28 Javascript
bootstrap datepicker 与bootstrapValidator同时使用时选择日期后无法正常触发校验的解决思路
2016/09/28 Javascript
Angular的$http的ajax的请求操作(推荐)
2017/01/10 Javascript
vue组件 $children,$refs,$parent的使用详解
2017/07/31 Javascript
Vuejs 单文件组件实例详解
2018/02/09 Javascript
JavaScript异步加载问题总结
2018/02/17 Javascript
vue权限问题的完美解决方案
2019/05/08 Javascript
解决Vue + Echarts 使用markLine标线(precision精度问题)
2020/07/20 Javascript
Python计算两个日期相差天数的方法示例
2017/05/23 Python
Python实现矩阵转置的方法分析
2017/11/24 Python
使用python批量读取word文档并整理关键信息到excel表格的实例
2018/11/07 Python
python实现飞机大战游戏
2020/10/26 Python
Python Numpy 实现交换两行和两列的方法
2019/06/26 Python
Python CategoricalDtype自定义排序实现原理解析
2020/09/11 Python
python 统计list中各个元素出现的次数的几种方法
2021/02/20 Python
西班牙灯具网上商店:Lampara.es
2018/06/05 全球购物
不用游标的SQL语句有哪些
2012/09/07 面试题
十佳党员事迹材料
2014/08/28 职场文书
2015年“公民道德宣传日”活动方案
2015/05/06 职场文书
2016年中学植树节活动总结
2016/03/16 职场文书
母婴行业实体、电商模式全面解析
2019/08/01 职场文书
比较node.js和Deno
2021/04/27 Javascript
Python趣味爬虫之用Python实现智慧校园一键评教
2021/05/28 Python