详解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中RegExp保留小数点后几位数的方法分享
Aug 13 Javascript
JavaScript声明变量时为什么要加var关键字
Sep 29 Javascript
javascript动画算法实例分析
Jul 31 Javascript
网页从弹窗页面单选框传值至父页面代码分享
Sep 29 Javascript
jQuery插件uploadify实现ajax效果的图片上传
Jun 18 Javascript
深入浅析JS是按值传递还是按引用传递(推荐)
Sep 18 Javascript
JavaScript trim 实现去除字符串首尾指定字符的简单方法
Dec 27 Javascript
echarts实现地图定时切换散点与多图表级联联动详解
Aug 07 Javascript
JavaScript 对引擎、运行时、调用堆栈的概述理解
Oct 22 Javascript
AntV F2和vue-cli构建移动端可视化视图过程详解
Oct 08 Javascript
vue 解决异步数据更新问题
Oct 29 Javascript
解决Vue-cli3没有vue.config.js文件夹及配置vue项目域名的问题
Dec 04 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边学边教》(02.Apache+PHP环境配置――下篇)
2006/12/13 PHP
PHP和Mysqlweb应用开发核心技术 第1部分 Php基础-3 代码组织和重用2
2011/07/03 PHP
PHP引用的调用方法分析
2016/04/25 PHP
thinkphp利用模型通用数据编辑添加和删除的实例代码
2016/11/20 PHP
PHP面向对象程序设计继承用法简单示例
2018/12/28 PHP
php连接sftp的作用以及实例代码
2019/09/23 PHP
jQuery中使用data()方法读取HTML5自定义属性data-*实例
2014/04/11 Javascript
jQuery模拟点击A标记示例参考
2014/04/17 Javascript
js的延迟执行问题分析
2014/06/23 Javascript
jQuery添加/改变/移除CSS类及判断是否已经存在CSS
2014/08/20 Javascript
js强制把网址设为默认首页
2015/09/29 Javascript
基于Bootstrap和jQuery构建前端分页工具实例代码
2016/11/23 Javascript
微信小程序通过一个json实现分享朋友圈图片
2019/09/03 Javascript
vue 实现把路由单独分离出来
2020/08/13 Javascript
从表单校验看JavaScript策略模式的使用详解
2020/10/17 Javascript
分享一个简单的python读写文件脚本
2017/11/25 Python
微信跳一跳python代码实现
2018/01/05 Python
运行django项目指定IP和端口的方法
2018/05/14 Python
使用python判断你是青少年还是老年人
2018/11/29 Python
对Python 多线程统计所有csv文件的行数方法详解
2019/02/12 Python
Python实现Linux监控的方法
2019/05/16 Python
python中类的输出或类的实例输出为这种形式的原因
2019/08/12 Python
pytorch实现CNN卷积神经网络
2020/02/19 Python
pytorch 使用加载训练好的模型做inference
2020/02/20 Python
详解Python中openpyxl模块基本用法
2021/02/23 Python
Kent & Curwen:与大卫·贝克汉姆合作
2017/06/13 全球购物
墨尔本最受欢迎的复古风格品牌:Princess Highway
2018/12/21 全球购物
软件测试企业面试试卷
2016/07/13 面试题
《蒙娜丽莎之约》教学反思
2014/02/27 职场文书
公司股权转让协议书
2014/04/12 职场文书
男女朋友协议书
2014/04/23 职场文书
计算机考试作弊检讨书1000字
2015/01/01 职场文书
暑期工社会实践报告
2015/07/13 职场文书
python爬虫selenium模块详解
2021/03/30 Python
如何用H5实现好玩的2048小游戏
2022/07/23 HTML / CSS
Li list-style-image 图片垂直居中实现方法
2023/05/21 HTML / CSS