详解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 相关文章推荐
jQuery html()等方法介绍
Nov 18 Javascript
IE事件对象(The Internet Explorer Event Object)
Jun 27 Javascript
用js提交表单解决一个页面有多个提交按钮的问题
Sep 01 Javascript
jquery判断当前浏览器的实现代码
Nov 07 Javascript
剖析Node.js异步编程中的回调与代码设计模式
Feb 16 Javascript
EasyUI 中combotree 默认不能选择父节点的实现方法
Nov 07 Javascript
vue使用监听实现全选反选功能
Jul 06 Javascript
跨域请求两种方法 jsonp和cors的实现
Nov 11 Javascript
npm的lock机制解析
Jun 20 Javascript
Layui Form 自定义验证的实例代码
Sep 14 Javascript
js使用文档就绪函数动态改变页面内容示例【innerHTML、innerText】
Nov 07 Javascript
微信小程序如何获取地址
Dec 24 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
YII2框架中excel表格导出的方法详解
2017/07/21 PHP
php使用curl下载指定大小的文件实例代码
2017/09/30 PHP
PHP检查URL包含特定字符串实例方法
2019/02/11 PHP
php设计模式之建造器模式分析【星际争霸游戏案例】
2020/01/23 PHP
提高 DHTML 页面性能
2006/12/25 Javascript
ECMAScript 基础知识
2007/06/29 Javascript
jQuery学习笔记 操作jQuery对象 文档处理
2012/09/19 Javascript
javascript中判断一个值是否在数组中并没有直接使用
2012/12/17 Javascript
javascript:;与javascript:void(0)使用介绍
2013/06/05 Javascript
js整数字符串转换为金额类型数据(示例代码)
2013/12/26 Javascript
jquery实现鼠标滑过显示提示框的方法
2015/02/05 Javascript
jQuery Plupload上传插件的使用
2017/04/19 jQuery
基于Vue2实现简易的省市区县三级联动组件效果
2018/11/05 Javascript
Node.js如何对SQLite的async/await封装详解
2019/02/14 Javascript
微信小程序生成分享海报方法(附带二维码生成)
2019/03/29 Javascript
[04:04]DOTA2亚洲邀请赛比赛场馆&酒店全攻略
2017/03/23 DOTA
[36:20]KG vs SECRET 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/19 DOTA
详解Django中Request对象的相关用法
2015/07/17 Python
python 3.5实现检测路由器流量并写入txt的方法实例
2017/12/17 Python
Python中常用信号signal类型实例
2018/01/25 Python
Python读写及备份oracle数据库操作示例
2018/05/17 Python
python 获取图片分辨率的方法
2019/01/08 Python
python创建学生成绩管理系统
2019/11/22 Python
python list等分并从等分的子集中随机选取一个数
2020/11/16 Python
努比亚手机官网:nubia
2016/10/06 全球购物
便携式太阳能系统的创新者:GOAL ZERO
2018/02/04 全球购物
英国第一的市场和亚马逊替代品:OnBuy
2019/03/16 全球购物
德国药房apodiscounter中文官网:德国排名前三的网上药店
2019/06/03 全球购物
粗加工管理制度
2014/02/04 职场文书
2014年元旦联欢会活动策划方案
2014/02/16 职场文书
学校运动会霸气口号
2014/06/07 职场文书
中学生运动会口号
2014/06/07 职场文书
诚信考试标语
2014/06/24 职场文书
镇副书记专题民主生活会对照检查材料思想汇报
2014/10/02 职场文书
Nginx虚拟主机的搭建的实现步骤
2022/01/18 Servers
Nginx 502 bad gateway错误解决的九种方案及原因
2022/08/14 Servers