详解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 构建客户/服务分离的链接模型中Table中的排序分析
Jan 22 Javascript
javascript setinterval 的正确语法如何书写
Jun 17 Javascript
有关json_decode乱码及NULL的问题
Oct 13 Javascript
利用jQuery解析获取JSON数据
Apr 08 jQuery
Javascript中八种遍历方法的执行速度深度对比
Apr 25 Javascript
Angular4 中内置指令的基本用法
Jul 31 Javascript
node通过express搭建自己的服务器
Sep 30 Javascript
bootstrap模态框嵌套、tabindex属性、去除阴影的示例代码
Oct 17 Javascript
微信小程序实现下拉框功能
Jul 16 Javascript
jQuery实现移动端图片上传预览组件的方法分析
May 01 jQuery
基于js实现的图片拖拽排序源码实例
Nov 04 Javascript
解决js中的setInterval清空定时器不管用问题
Nov 17 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 常用函数库和一些实用小技巧
2009/01/01 PHP
php连接odbc数据源并保存与查询数据的方法
2014/12/24 PHP
php生成图片缩略图功能示例
2017/02/22 PHP
经典海量jQuery插件 大家可以收藏一下
2010/02/07 Javascript
javascript基础知识大集锦(一) 推荐收藏
2011/01/13 Javascript
jquery+ajax每秒向后台发送请求数据然后返回页面的代码
2011/01/17 Javascript
重载toString实现JS HashMap分析
2011/03/13 Javascript
JavaScript 的继承
2011/10/01 Javascript
jQuery 属性选择器element[herf*='value']使用示例
2013/10/20 Javascript
JavaScript获取某年某月的最后一天附截图
2014/06/23 Javascript
javascript实现网页端解压并查看zip文件
2015/12/15 Javascript
Node.js的Koa框架上手及MySQL操作指南
2016/06/13 Javascript
微信小程序如何使用globalData的方法
2019/06/06 Javascript
如何构建 vue-ssr 项目的方法步骤
2020/08/04 Javascript
10分钟学会js处理json的常用方法
2020/12/06 Javascript
[00:47]DOTA2荣耀之路6:玩不了啦!
2018/05/30 DOTA
[01:14]英雄,所敬略同——2018完美盛典宣传视频
2018/12/05 DOTA
python调用API实现智能回复机器人
2018/04/10 Python
Python Json模块中dumps、loads、dump、load函数介绍
2018/05/15 Python
Django项目后台不挂断运行的方法
2019/08/31 Python
Python List列表对象内置方法实例详解
2019/10/22 Python
matplotlib subplot绘制多个子图的方法示例
2020/07/28 Python
Python如何实现机器人聊天
2020/09/10 Python
python 自定义异常和主动抛出异常(raise)的操作
2020/12/11 Python
python正则表达式re.match()匹配多个字符方法的实现
2021/01/27 Python
Python Spyder 调出缩进对齐线的操作
2021/02/26 Python
CSS Grid布局教程之什么是网格布局
2014/12/30 HTML / CSS
html5 input属性使用示例
2013/06/28 HTML / CSS
肯尼亚网上商城:Kilimall
2016/08/20 全球购物
使用索引(Index)有哪些需要考虑的因素
2016/10/19 面试题
《永远的白衣战士》教学反思
2014/04/25 职场文书
责任担保书范文
2014/05/21 职场文书
学校党风廉政建设调研报告
2015/01/01 职场文书
高质量“欢迎词”
2019/04/03 职场文书
python实现web邮箱扫描的示例(附源码)
2021/03/30 Python
spring boot中nativeQuery的用法
2021/07/26 Java/Android