详解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 EasyUI的添加,修改,删除,查询等基本操作介绍
Oct 11 Javascript
JS实现的页面自定义滚动条效果
Oct 26 Javascript
jQuery上传多张图片带进度条样式(DEMO)
Mar 02 Javascript
为JQuery EasyUI 表单组件增加焦点切换功能的方法
Apr 13 jQuery
JavaScript 中Date对象的格式化代码方法汇总
Sep 06 Javascript
基于Vue开发数字输入框组件
Dec 19 Javascript
JS交互点击WKWebView中的图片实现预览效果
Jan 05 Javascript
详解性能更优越的小程序图片懒加载方式
Jul 18 Javascript
JS隐藏号码中间4位代码实例
Apr 09 Javascript
Vue.js计算机属性computed和methods方法详解
Oct 12 Javascript
Vue使用vue-recoure + http-proxy-middleware + vuex配合promise实现基本的跨域请求封装
Oct 21 Javascript
vue接口请求加密实例
Aug 11 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
使用NetBeans + Xdebug调试PHP程序的方法
2011/04/12 PHP
php判断上传的Excel文件中是否有图片及PHPExcel库认识
2013/01/11 PHP
给PHP开发者的编程指南 第一部分降低复杂程度
2016/01/18 PHP
基于PHP实现等比压缩图片大小
2016/03/04 PHP
PHP 图片处理
2020/09/16 PHP
js 页面输出值
2008/11/30 Javascript
JS获取当前网址、主机地址项目根路径
2013/11/19 Javascript
jQuery中parents()和parent()的区别分析
2014/10/28 Javascript
js字符串操作总结(必看篇)
2016/11/22 Javascript
JavaScript设计模式之单例模式详解
2017/06/09 Javascript
简单实现jQuery上传图片显示预览功能
2020/06/29 jQuery
Vue2.0权限树组件实现代码
2017/08/29 Javascript
Vue.js项目中管理每个页面的头部标签的两种方法
2018/06/25 Javascript
[38:31]完美世界DOTA2联赛PWL S3 Magma vs GXR 第一场 12.13
2020/12/17 DOTA
python中的__slots__使用示例
2015/02/26 Python
Python语言实现将图片转化为html页面
2017/12/06 Python
Python实现冒泡排序的简单应用示例
2017/12/11 Python
Python实现感知机(PLA)算法
2017/12/20 Python
python判断一个集合是否为另一个集合的子集方法
2018/05/04 Python
django queryset相加和筛选教程
2020/05/18 Python
在pycharm中关掉ipython console/PyDev操作
2020/06/09 Python
Debenhams百货英国官方网站:Debenhams UK
2016/07/12 全球购物
Marriott中国:万豪国际酒店查询预订
2016/09/02 全球购物
惊艳的手工时装首饰:Migonne Gavigan
2018/02/23 全球购物
舞会礼服和舞会鞋:PromGirl
2019/04/22 全球购物
程序运行正确, 但退出时却"core dump"了,怎么回事
2014/02/19 面试题
系统管理员的职责包括那些?管理的对象是什么?
2016/09/20 面试题
Shell编程面试题
2016/05/29 面试题
文秘专业个人求职信
2013/12/22 职场文书
班级学习计划书
2014/04/27 职场文书
人力资源管理求职信
2014/08/07 职场文书
英文辞职信范文
2015/05/13 职场文书
2015大学迎新晚会主持词
2015/07/16 职场文书
趣味运动会赞词
2015/07/22 职场文书
企业法人任命书
2015/09/21 职场文书
幼儿园体操比赛口号
2015/12/25 职场文书