详解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 弹出层注册页面等(asp.net后台)
Jun 17 Javascript
关于JavaScript定义类和对象的几种方式
Nov 09 Javascript
javascript 基础篇3 类,回调函数,内置对象,事件处理
Mar 14 Javascript
Jquery在指定DIV加载HTML示例代码
Feb 17 Javascript
JS Attribute属性操作详解
May 19 Javascript
全面解析多种Bootstrap图片轮播效果
May 27 Javascript
值得分享的轻量级Bootstrap Table表格插件
May 30 Javascript
jquery获取input type=text中的值的各种方式(总结)
Dec 02 Javascript
基于JavaScript实现百度搜索框效果
Jun 28 Javascript
get  post jsonp三种数据交互形式实例详解
Aug 25 Javascript
详解Vue.js iview实现树形权限表(可扩展表)
Sep 30 Javascript
详解vue之自行实现派发与广播(dispatch与broadcast)
Jan 19 Vue.js
微信小程序获取用户绑定手机号方法示例
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将图片保存为不同尺寸图片的图片类实例
2015/03/30 PHP
PHP编程计算日期间隔天数的方法
2017/04/26 PHP
php中Ioc(控制反转)和Di(依赖注入)
2017/05/07 PHP
php微信开发之音乐回复功能
2018/06/14 PHP
thinkphp5引入公共部分header、footer的方法详解
2018/09/14 PHP
php 多继承的几种常见实现方法示例
2019/11/18 PHP
用js实现键盘方向键翻页功能的代码
2007/06/03 Javascript
博客侧边栏模块跟随滚动条滑动固定效果的实现方法(js+jquery等)
2013/03/24 Javascript
js实现网页随机切换背景图片的方法
2014/11/01 Javascript
JS拖动鼠标画出方框实现鼠标选区的方法
2015/08/05 Javascript
Function.prototype.apply()与Function.prototype.call()小结
2016/04/27 Javascript
JS使用JSON作为参数实例分析
2016/06/23 Javascript
ComboBox(下拉列表框)通过url加载调用远程数据的方法
2017/08/06 Javascript
js+canvas实现滑动拼图验证码功能
2018/03/26 Javascript
Vue.js 十五分钟入门图文教程
2018/09/12 Javascript
JavaScript定时器使用方法详解
2020/03/26 Javascript
Vue使用轮询定时发送请求代码
2020/08/10 Javascript
[46:09]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS VG第三场
2014/05/26 DOTA
python实现rest请求api示例
2014/04/22 Python
解决tensorflow1.x版本加载saver.restore目录报错的问题
2018/07/26 Python
Django框架使用富文本编辑器Uedit的方法分析
2018/07/31 Python
python 高效去重复 支持GB级别大文件的示例代码
2018/11/08 Python
解决pyttsx3无法封装的问题
2018/12/24 Python
python 命令行传入参数实现解析
2019/08/30 Python
python 将dicom图片转换成jpg图片的实例
2020/01/13 Python
在spyder IPython console中,运行代码加入参数的实例
2020/04/20 Python
pycharm 快速解决python代码冲突的问题
2021/01/15 Python
Python开发.exe小工具的详细步骤
2021/01/27 Python
adidas瑞典官方网站:购买阿迪达斯鞋子和运动服
2019/12/11 全球购物
西班牙在线光学:Visual-Click
2020/06/22 全球购物
信息专业个人的自我评价
2013/12/27 职场文书
《燕子》教学反思
2014/02/18 职场文书
党的群众路线教育实践活动学习心得体会
2014/03/03 职场文书
cf收人广告词大全
2014/03/14 职场文书
个人整改措施书面材料
2014/10/24 职场文书
MySQL之select、distinct、limit的使用
2021/11/11 MySQL