详解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中ComboBoxTree实现的下拉框树效果(自写)
May 28 Javascript
JS脚本defer的作用示例介绍
Jan 02 Javascript
Js实现网页键盘控制翻页的方法
Oct 30 Javascript
jQuery获取标签文本内容和html内容的方法
Mar 27 Javascript
js中setTimeout()与clearTimeout()用法实例浅析
May 12 Javascript
提高jQuery性能优化的技巧
Aug 03 Javascript
angular2倒计时组件使用详解
Jan 12 Javascript
详解Vue使用命令行搭建单页面应用
May 24 Javascript
浅谈Angular4实现热加载开发旅程
Sep 08 Javascript
Three.js基础学习之场景对象
Sep 27 Javascript
使用Node.js实现base64和png文件相互转换的方法
Mar 11 Javascript
javascript使用canvas实现饼状图效果
Sep 08 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下一个非常全面获取图象信息的函数
2008/11/20 PHP
ThinkPHP多表联合查询的常用方法
2020/03/24 PHP
Laravel 5框架学习之路由、控制器和视图简介
2015/04/07 PHP
php对象和数组相互转换的方法
2015/05/12 PHP
PHP版本如何选择?应该使用哪个版本?
2015/05/13 PHP
深入理解PHP之源码目录结构与功能说明
2016/06/01 PHP
javascript编程起步(第六课)
2007/02/27 Javascript
jquery多选项卡效果实例代码(附效果图)
2013/03/23 Javascript
js使用循环清空某个div中的input标签值
2014/09/29 Javascript
c#程序员对TypeScript的认识过程
2015/06/19 Javascript
Nodejs中session的简单使用及通过session实现身份验证的方法
2016/02/04 NodeJs
jQuery代码性能优化的10种方法
2016/06/21 Javascript
jQuery实现可以编辑的表格实例详解【附demo源码下载】
2016/07/09 Javascript
js中的关联数组与普通数组详解
2016/07/27 Javascript
JavaScript 继承详解(五)
2016/10/11 Javascript
JS 调用微信扫一扫功能
2016/12/22 Javascript
JS中数据结构之栈
2019/01/01 Javascript
JavaScript使用canvas绘制随机验证码
2020/02/17 Javascript
小程序接入腾讯位置服务的详细流程
2020/03/03 Javascript
Python实现判断给定列表是否有重复元素的方法
2018/04/11 Python
Python多线程及其基本使用方法实例分析
2019/10/29 Python
全面介绍python中很常用的单元测试框架unitest
2020/12/14 Python
python中doctest库实例用法
2020/12/31 Python
推荐10个CSS3 制作的创意下拉菜单效果
2014/02/11 HTML / CSS
简单整理HTML5的基本特性和语法
2016/02/18 HTML / CSS
Canvas波浪花环的示例代码
2020/08/21 HTML / CSS
中国领先的专业演出票务网:永乐票务
2016/08/29 全球购物
JSP和EJB可以共享HttpSession么?EJB里面可以改变session里面的内容
2013/06/05 面试题
鞋类设计与工艺专业销售求职信
2013/11/01 职场文书
2015年社区民政工作总结
2015/04/21 职场文书
2015年出纳年终工作总结
2015/05/14 职场文书
获奖感言怎么写
2015/07/31 职场文书
《夜莺的歌声》教学反思
2016/02/22 职场文书
详解CSS不受控制的position fixed
2021/05/25 HTML / CSS
MySQL 表锁定 LOCK和UNLOCK TABLES的 SQL语法
2022/04/18 MySQL
CentOS7安装MySQL8的超级详细教程(无坑!)
2022/06/10 Servers