详解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 相关文章推荐
prototype.js的Ajax对象
Sep 23 Javascript
jquery常用函数与方法汇总
Sep 01 Javascript
深入理解React中es6创建组件this的方法
Aug 29 Javascript
js面向对象实现canvas制作彩虹球喷枪效果
Sep 24 Javascript
ES6概念 Symbol.keyFor()方法
Dec 25 Javascript
js指定步长实现单方向匀速运动
Jul 17 Javascript
vue实现自定义日期组件功能的实例代码
Nov 06 Javascript
微信实现自动跳转到用其他浏览器打开指定APP下载
Feb 15 Javascript
node.js基于socket.io快速实现一个实时通讯应用
Apr 23 Javascript
JS实现的tab切换并显示相应内容模块功能示例
Aug 03 Javascript
详解Nuxt内导航栏的两种实现方式
Apr 16 Javascript
vue mvvm数据响应实现
Nov 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
PHP 学习路线与时间表
2010/02/21 PHP
PHP命令行脚本接收传入参数的三种方式
2014/08/20 PHP
Laravel 5框架学习之Laravel入门和新建项目
2015/04/07 PHP
php生成酷炫的四个字符验证码
2016/04/22 PHP
PHP封装XML和JSON格式数据接口操作示例
2019/03/06 PHP
javascript多行字符串的简单实现方式
2015/05/04 Javascript
Angularjs中使用Filters详解
2016/03/11 Javascript
JavaScript实现复制内容到粘贴板代码
2016/03/31 Javascript
canvas实现绘制吃豆鱼效果
2017/01/12 Javascript
bootstrap IE8 兼容性处理
2017/03/22 Javascript
详解vue项目优化之按需加载组件-使用webpack require.ensure
2017/06/13 Javascript
微信小程序之绑定点击事件实例详解
2017/07/07 Javascript
JS实现显示当前日期的实例代码
2018/07/03 Javascript
vue form 表单提交后刷新页面的方法
2018/09/04 Javascript
js事件on动态绑定数据,绑定多个事件的方法
2018/09/15 Javascript
详解Node.js amqplib 连接 Rabbit MQ最佳实践
2019/01/24 Javascript
超详细小程序定位地图模块全系列开发教学
2020/11/24 Javascript
[02:27]DOTA2英雄基础教程 莱恩
2014/01/17 DOTA
[02:26]2016国际邀请赛8月3日开战 中国军团出征西雅图
2016/08/02 DOTA
[54:19]完美世界DOTA2联赛PWL S2 Magma vs PXG 第二场 11.28
2020/12/01 DOTA
零基础写python爬虫之抓取百度贴吧并存储到本地txt文件改进版
2014/11/06 Python
Python使用cookielib模块操作cookie的实例教程
2016/07/12 Python
python爬取指定微信公众号文章
2018/12/20 Python
python爬虫中多线程的使用详解
2019/09/23 Python
Python+Redis实现布隆过滤器
2019/12/08 Python
丝芙兰巴西官方商城:SEPHORA巴西
2016/10/31 全球购物
英国天然有机美容护肤品:Neal’s Yard Remedies
2018/05/05 全球购物
Tommy Hilfiger美国官网:美国高端休闲领导品牌
2019/01/14 全球购物
自我评价是什么
2014/01/04 职场文书
计算机科学系职业生涯规划书
2014/03/08 职场文书
优秀学生评语大全
2014/04/25 职场文书
2014年高一班主任工作总结
2014/12/05 职场文书
员工辞职信怎么写
2015/02/27 职场文书
外贸英文求职信范文
2015/03/19 职场文书
北京爱情故事观后感
2015/06/12 职场文书
浅谈resultMap的用法及关联结果集映射
2021/06/30 Java/Android