详解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 25 Javascript
javascript动画浅析
Aug 30 Javascript
Javascript执行效率全面总结
Nov 04 Javascript
上传图片js判断图片尺寸和格式兼容IE
Sep 01 Javascript
javascript十六进制及二进制转化的方法
May 06 Javascript
五种js判断是否为整数类型方式
Dec 03 Javascript
Angular.js中$apply()和$digest()的深入理解
Oct 13 Javascript
Bootstrap进度条学习使用
Feb 09 Javascript
Vuex 进阶之模块化组织详解
Jan 12 Javascript
分享vue里swiper的一些坑
Aug 30 Javascript
详解vue项目中实现图片裁剪功能
Jun 07 Javascript
vue 自动化路由实现代码
Sep 03 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
《猛禽小队》:DC宇宙的又一超级大烂片
2020/04/09 欧美动漫
PHP编程与应用
2006/10/09 PHP
PHP入门速成教程
2007/03/19 PHP
php微信高级接口群发 多客服
2016/06/23 PHP
基于PHP微信红包的算法探讨
2016/07/21 PHP
PHP实现十进制、二进制、八进制和十六进制转换相关函数用法分析
2017/04/25 PHP
PHP实现的Redis多库选择功能单例类
2017/07/27 PHP
PHP实现git部署的方法教程
2017/12/19 PHP
javascript实时显示北京时间的方法
2015/03/12 Javascript
JavaScript简单修改窗口大小的方法
2015/08/03 Javascript
js和jquery实现监听键盘事件示例代码
2020/06/24 Javascript
JS验证input输入框(字母,数字,符号,中文)
2017/03/23 Javascript
详解Vue-基本标签和自定义控件
2017/03/24 Javascript
vue实现密码显示隐藏切换功能
2018/02/23 Javascript
JavaScript模板引擎应用场景及实现原理详解
2018/12/14 Javascript
js动态获取时间的方法分析
2019/08/02 Javascript
实现vuex与组件data之间的数据同步更新方式
2019/11/12 Javascript
Vue组件通信入门之Provide和Inject机制
2019/12/29 Javascript
jquery实现上传文件进度条
2020/03/26 jQuery
python中defaultdict的用法详解
2017/06/07 Python
Python3实现发送QQ邮件功能(附件)
2020/12/23 Python
python将字符串list写入excel和txt的实例
2019/07/20 Python
Django用户认证系统 User对象解析
2019/08/02 Python
基于Python计算圆周率pi代码实例
2020/03/25 Python
用Python爬取LOL所有的英雄信息以及英雄皮肤的示例代码
2020/07/13 Python
如何利用python 读取配置文件
2021/01/06 Python
编写用C语言实现的求n阶阶乘问题的递归算法
2014/10/21 面试题
如何找出EMP表里面SALARY第N高的employee
2013/12/05 面试题
汽车专业毕业生自荐信
2013/11/03 职场文书
小学教师听课制度
2014/02/01 职场文书
2014年小学体育工作总结
2014/12/11 职场文书
汤姆索亚历险记读书笔记
2015/06/29 职场文书
用position:sticky完美解决小程序吸顶问题的实现方法
2021/04/24 HTML / CSS
mysql 8.0.24 安装配置方法图文教程
2021/05/12 MySQL
vue项目打包后路由错误的解决方法
2022/04/13 Vue.js
nginx实现多geoserver服务的负载均衡
2022/05/15 Servers