详解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的模拟苹果桌面Dock效果(稳定版)
Oct 15 Javascript
js实现页面转发功能示例代码
Aug 05 Javascript
使用js简单实现了tree树菜单
Nov 20 Javascript
Node.js中使用事件发射器模式实现事件绑定详解
Aug 15 Javascript
JavaScript设计模式之建造者模式介绍
Dec 28 Javascript
Javascript 拖拽的一些高级的应用(逐行分析代码,让你轻松了拖拽的原理)
Jan 23 Javascript
浅谈轻量级js模板引擎simplite
Feb 13 Javascript
解决VUE框架 导致绑定事件的阻止冒泡失效问题
Feb 24 Javascript
layui点击导航栏刷新tab页的示例代码
Aug 14 Javascript
Vuex 快速入门(简单易懂)
Sep 20 Javascript
微信小程序使用map组件实现解析经纬度功能示例
Jan 22 Javascript
Vue.js组件实现选项卡以及切换特效
Jul 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
解析PHP中DIRECTORY_SEPARATOR,PATH_SEPARATOR两个常量的作用
2013/06/21 PHP
php实现信用卡校验位算法THE LUHN MOD-10示例
2014/05/07 PHP
php广告加载类用法实例
2014/09/23 PHP
php格式化json函数示例代码
2016/05/12 PHP
PHP安装memcache扩展的步骤讲解
2019/02/14 PHP
在网页中屏蔽快捷键
2006/09/06 Javascript
js变量作用域及可访问性的探讨
2006/11/23 Javascript
javascript中的作用域和上下文使用简要概述
2013/12/05 Javascript
jquery append()方法与html()方法的区别及使用介绍
2014/08/01 Javascript
关于js里的this关键字的理解
2015/08/17 Javascript
Javascript编程之继承实例汇总
2015/11/28 Javascript
AngularJS指令用法详解
2016/11/02 Javascript
jQuery验证表单格式的使用方法
2017/01/10 Javascript
vue.js之vue-cli脚手架的搭建详解
2017/05/05 Javascript
vue2.0 better-scroll 实现移动端滑动的示例代码
2018/01/25 Javascript
解决vue单页使用keep-alive页面返回不刷新的问题
2018/03/13 Javascript
菊花转动的jquery加载动画效果
2018/08/19 jQuery
JS实现滑动导航效果
2020/01/14 Javascript
JS call()及apply()方法使用实例汇总
2020/07/11 Javascript
python 实现归并排序算法
2012/06/05 Python
Django中的CACHE_BACKEND参数和站点级Cache设置
2015/07/23 Python
Python读取英文文件并记录每个单词出现次数后降序输出示例
2018/06/28 Python
python 发送json数据操作实例分析
2019/10/15 Python
python文件读写代码实例
2019/10/21 Python
Python3搭建http服务器的实现代码
2020/02/11 Python
CSS3属性选择符介绍
2008/10/17 HTML / CSS
网购亚洲时装、美容产品和生活百货:YesStyle
2016/09/15 全球购物
对于没有初始化的变量的初始值可以作怎样的假定
2014/10/12 面试题
Ajax主要包含了哪些技术
2014/06/12 面试题
餐厅服务员岗位职责
2015/02/09 职场文书
2015年精神文明建设工作总结
2015/04/21 职场文书
班主任班级管理心得体会
2016/01/07 职场文书
vue项目两种方式实现竖向表格的思路分析
2021/04/28 Vue.js
Java生成读取条形码和二维码的简单示例
2021/07/09 Java/Android
Spring中bean集合注入的方法详解
2022/07/07 Java/Android
基于Redission的分布式锁实战
2022/08/14 Redis