详解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 学习笔记(onchange等)
Nov 14 Javascript
在Node.js应用中使用Redis的方法简介
Jun 24 Javascript
jq实现左侧显示图片右侧文字滑动切换效果
Aug 04 Javascript
jQuery简单实现两级下拉菜单效果代码
Sep 15 Javascript
jquery中的常见问题及快速解决方法小结
Jun 14 Javascript
基于Vuejs框架实现翻页组件
Jun 29 Javascript
如何实现星星评价(jquery.raty.js插件)
Dec 21 Javascript
简单实现IONIC购物车功能
Jan 10 Javascript
vue之nextTick全面解析
May 17 Javascript
bootstrap daterangepicker汉化以及扩展功能
Jun 15 Javascript
详解Vue中localstorage和sessionstorage的使用
Dec 22 Javascript
Node.js API详解之 assert模块用法实例分析
May 26 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中fsockopen用法实例
2015/01/05 PHP
JavaScript延迟加载
2021/03/09 Javascript
JavaScript语句可以不以;结尾的烦恼
2007/03/08 Javascript
JavaScript DOM学习第六章 表单实例
2010/02/19 Javascript
Jquery插件 easyUI属性汇总
2011/01/19 Javascript
js加入收藏以及使用Jquery更改透明度
2014/01/26 Javascript
jQuery 选择器详解
2015/01/19 Javascript
jQuery中each()、find()和filter()等节点操作方法详解(推荐)
2016/05/25 Javascript
详细AngularJs4的图片剪裁组件的实例
2017/07/12 Javascript
微信小程序methods中定义的方法互相调用的实例代码
2018/08/07 Javascript
从零开始搭建vue移动端项目到上线的步骤
2018/10/15 Javascript
详解超简单的react服务器渲染(ssr)入坑指南
2019/02/28 Javascript
JavaScript实现简单的弹窗效果
2020/05/19 Javascript
解决antd datepicker 获取时间默认少8个小时的问题
2020/10/29 Javascript
[08:42]DOTA2每周TOP10 精彩击杀集锦vol.2
2014/06/25 DOTA
Python连接MySQL并使用fetchall()方法过滤特殊字符
2016/03/13 Python
利用python的socket发送http(s)请求方法示例
2018/05/07 Python
pandas pivot_table() 按日期分多列数据的方法
2018/11/16 Python
浅谈python3.6的tkinter运行问题
2019/02/22 Python
Windows下PyCharm2018.3.2 安装教程(图文详解)
2019/10/24 Python
Django中使用MySQL5.5的教程
2019/12/18 Python
python设置环境变量的作用整理
2020/02/17 Python
python3实现将json对象存入Redis以及数据的导入导出
2020/07/16 Python
基于django和dropzone.js实现上传文件
2020/11/24 Python
阿迪达斯希腊官方网上商店:adidas希腊
2019/04/06 全球购物
室内设计实习自我鉴定
2013/09/25 职场文书
社区戒毒工作方案
2014/06/04 职场文书
化工专业求职信
2014/07/01 职场文书
检讨书1000字
2014/10/11 职场文书
2014年世界艾滋病日宣传活动总结
2014/11/18 职场文书
2014年派出所工作总结
2014/11/21 职场文书
教师个人学习总结
2015/02/11 职场文书
确保减税降费落地生根,用实实在在措施
2019/07/19 职场文书
MySQL数据库10秒内插入百万条数据的实现
2021/11/01 MySQL
python的列表生成式,生成器和generator对象你了解吗
2022/03/16 Python