vue为什么要求组件模板只能有一个根元素

vue为什么要求组件模板只能有一个根元素,第1张

1new Vue({el:'#app'})

2单文件组件中,template下的元素div

一、当我们实例化Vue的时候,填写一个el选项,来指定我们的SPA入口:

同时我们也会在body里面新增一个id为app的div

这很好理解,就是为vue开启一个入口,那我们不妨来想想,如果我在body下这样

Vue其实并不知道哪一个才是我们的入口,因为对于一个入口来讲,这个入口就是一个‘Vue类',Vue需要把这个入口里面的所有东西拿来渲染,处理,最后再重新插入到dom中。

如果同时设置了多个入口,那么vue就不知道哪一个才是这个‘类'。

二、当我们在webpack搭建的vue开发环境下,使用单文件组件时,你可能会这样:

那这里为什么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实例了。

1创建一个Vue实例

通过vue函数创建一个新的vue实例

一个 Vue 应用由一个通过new Vue创建的 根 Vue 实例 ,以及可嵌套的、可复用的组件树组成的。

我们先看看Vue基本的使用,至于组件我们后面详细的在来探讨

<divid="app"><!-- {{ 插值表达式,可以赋值 取值 三元 }} -->{{ msg }}</div><scriptsrc="/node_modules\vue\dist\vuejs"></script><script>// 引入vue后 会白给你一个Vue构造函数letvm=newVue({// 配置对象el:'#app',// 告诉vue能管理那个部分,使用的是querySelectordata:{// data中的数据会被vm所代理msg:'hello world',// 可以通过vmmsg取到对应的内容 ,也可以赋值      }})</script>

2声明式渲染

Vuejs 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:

21 关于{{}} 插值表达式

插值表达式,表达式,赋值运算,计算,三元表达式,但是尽量少在这里写逻辑计算

插值:

<!-- HTML ---><divid="app">{{ message }}</div><!-- JS ---><script>newVue({el:'#app',data:{messgae:'hello Vue!'}})</script>

我们已经成功创建了第一个 Vue 应用!看起来这跟渲染一个字符串模板非常类似,但是 Vue 在背后做了大量工作。现在数据和 DOM 已经被建立了关联,所有东西都是响应式的。我们要怎么确认呢?

如果需要确定现在的数据是否已经和DOM建立了关联,形成响应式

可以将js中的new Vue复制给一个全局变量vm此时vm就是Vue实例化对象,未来可能会用它来搞很多事情,但是最常用到它的时候,是通过this关键字来使用它

varvm=newVue({el:'#app',data:{messgae:'hello Vue!'}})

然后在浏览器的js控制台中修改vmmessage值,同时页面也会发生改变

在控制台中输入

vmmessge="你好,Vue"

22使用 JavaScript 表达式

迄今为止,在我们的模板中,我们一直都只绑定简单的属性键值。但实际上,对于所有的数据绑定,Vuejs 都提供了完全的 JavaScript 表达式支持。

{{ number + 1 }}{{ ok 'YES' : 'NO' }}{{ messagesplit('')reverse()join('') }}<divv-bind:id="'list-' + id"></div>

这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript 被解析。

示例:

<divid="app"><!-- 数字 *** 作 --><p>{{ number + 2 }}</p><!-- 三目运算 --><p>{{ ok 'YES' : 'NO' }}</p><!-- 字符串翻转 --><p>{{ messagesplit('')reverse()join('')  }}</p></div><script>constvm=newVue({el:"#app",data:{message:'Hello World',number:10,ok:true,}})</script>

显示结果:

1png

但是有个限制就是,每个绑定双大括号(Mustache语法)里面都只能包含 单个表达式

23 关于data数据

vue关注的是数据变化,不需要在像以前一样关注DOM的变化

比如我想在2秒之后让页面发生变化,我们只需要在2秒后更改数据就可以了

varvm=newVue({el:'#app',data:{msg:'hello world'}})setTimeout(function(){vm$datamsg="bye world"},2000)

关于实例介绍:

示例中vm是Vue的实例对象,

实例对象上有$data属性,其值就是选项对象中data属性值

选项对象就是在实例化Vue时传入的对象

data属性值是一个对象,因此$data也就是这个对象

当通过$data修改msg的值时,也就等于改data中的值, 对应是引用类型

因此示例的结果就是:

2秒后data数据中msg的值改变了, 又因为Vue是始终在关注着msg这个数据,一旦数据发生变化,就会触发Vue的响应式, 继而改变视图显示

24 再次理解MVVM模式

在上一节讲Vue的mvvm模式的时候就有提到,

Vue实例对象就是vm,data数据就是model,  页面显示的结果就是view

再来看一下mvvm的图

mvvmjpg

这张图在配合刚才的示例, 我们就能很好的理解,当数据Model发生变化以后, Vue就可以通过Data Bindings了解到,然后使用新的数据去改变页面显示

至于Vue如何通过DOM Listeners监听页面的改变,来改变数据,这个我们之后讲到在说

3实例上的方法

除了数据属性,Vue 选项对象中还暴露了一些有用的属性与方法。在通过实例对象使用选项对象的属性时,属性前面都需要带上前缀$,以便与用户定义的属性区分开来。例如:

vardata={a:1}varvm=newVue({el:'#example',data:data})vm$data===data// => truevm$el===documentgetElementById('example')// => true

31 实例上常用的属性和方法

vm$attrs// 用户获取父组件传递给子组件的属性,(除props,class,style外)vm$data// vm 上的数据vm$watch// 监听vm$el// 当前el元素vm$set// 后加的属性实现响应式vm$options// vm 配置 上的 所有属性vm$nextTick(()=>{})// 异步方法,等待渲染dom完成后来获取vmvm$refs// 获取dom元素或者组件实例的引用

其实我们可以创建一个Vue实例,然后在控制台上打印这个实例对象,你会看到很多的属性和方法

constvm=newVue({el:"#app",})

在控制台输入vm

显示结果:

实例属性png

这里面很多属性,我们暂时不用去关心他,因为随着学习的深入,慢慢都会学习到的

4实例化多个vue

我们可以在页面上同时实例化多个Vue, 不同的实例接管页面上不同的区域

看下如下的示例:

##  <h1>实例化多个Vue对象</h1><divid="app-one"><h2>{{ title }}</h2><p>{{ greet }}</p></div><divid="app-two"><h2>{{ title }}</h2><p>{{ greet }}</p><buttonv-on:click="changeTitle">点击改变app-one的h2的内容</button></div><script>//  Vue实例varone=newVue({el:'#app-one',data:{title:" vue-app-one的内容"},computed:{greet:function(){return"Hello App One"}}})//  Vue实例vartwo=newVue({el:'#app-two',data:{title:" vue-app-two的内容"},methods:{changeTitle:function(){onetitle="app-one的内容发生改变了"}},computed:{greet:function(){return"Hello App two"}}})</script>

Vue事件和方法还没有讲到, 先做一个了解即可:

示例分析:

两个实例one和two接管了不同的DOM元素,

点击按钮是在two实例接管的DOM元素中,

所以,当你点击时,只会触发two实例中的方法, 也只会改变two实例中的数据

那么问题来了

能否在two实例中修改one实例中的数据呢,

答案当然是可以的啦, 因为变量one是全局变量,

在two实例化中,就可以通过one变量得到第一个Vue实例化对象,

然后就可以通过实例化对象修改数据,这个可以自己尝试写写

5 Vue *** 作DOM元素

虽然Vue是数据驱动的,但是有的时候我们就需要自己手动的获取到DOM元素,对DOM元素进行 *** 作,那么该如何处理呢,

*** 作DOM元素:

在需要 *** 作的DOM元素中使用ref属性,

ref属性的值是自己随便定义的名字

通过Vue实例的$refs属性获取 *** 作dom元素

<divid="app"><divref="wuwei">无为</div></div><script>varvm=newVue({// 根实例el:'#app',data:{},mounted(){//dom元素中有多个一样的ref,dom如果不是通过v-for循环出来的,只能获取一个// 如果是循环出来的,可以获取多个,获取的是一个数组consolelog(this$refswuwei)}});</script>

关于示例中$refs属性的解释:

因为可以在多个DOM元素上使用ref

所以$refs属性获取的是所有具有ref属性的DOM元素的集

因此要想 *** 作确定的DOM元素就需要在通过当初的ref值获取

简而言之: 就是ref在dom元素上通过this$refs自定义名字是获取dom元素

当获取到DOM元素后,然后就可以采用原生的JavaScript对DOM进行 *** 作

注意:

Vue 接管的DOM元素之外的元素使用ref是获取不了的,值是undefined

指令(Directives),是vue为开发者提供的 模板语法 ,用于辅助开发者渲染页面的基本结构

所用到的数据定义在实例的 data 中,事件定义在实例的 methods

只能渲染纯文本内容, 会覆盖 标签内部原本的内容

只能渲染纯文本内容, 不会覆盖 标签内部原本的内容

能将带标签的字符串渲染成html内容, 会覆盖 标签内部原本的内容

为元素的属性 动态 绑定属性值

注意: 插值表达式 v-bind 还支持javascript表达式的运算

为元素绑定事件

只要是事件,就能使用的修饰符,以下列举5个常用的

只能在触发键盘事件时,使用的修饰符,以下列举2个常用的

快速获取表单数据(只应用于表单元素,如:input、textarea、select)

只能给v-model使用的修饰符

控制DOM的显示与隐藏(值为true显示,值为false隐藏),其原理为 动态添加/移除display:none样式 ,一般用于需频繁切换

控制DOM的显示与隐藏(值为true显示,值为false隐藏),其原理为 动态创建/移除元素 ,一般用于默认不展示且展示较少

配合 v-if 指令一起使用,否则将不会被识别

基于一个数组来循环渲染一个列表结构,它有特定的语法结构 v-for="item in items"

注意:在vue文件中,只要用到 v-for指令 ,一定要绑定一个 :key 属性

作者:用户2031777005900

链接:>

配置自定义的snippets。

通过vscode的snippets我们可以自己配置自定义的snippets,从而实现快捷生成代码片段,在VsCode里按F1,输入snippets->选择配置用户代码片段,选择后出现选择配置的界面,这里我们对Vue文件的代码片段进行配置,然后就完成了。

随着vscode以及vue的越来越普及,vetur这个名字也越来越被人熟知。vetur是一个vscode插件,用于为vue单文件组件提供代码高亮以及语法支持。

以上就是关于vue为什么要求组件模板只能有一个根元素全部的内容,包括:vue为什么要求组件模板只能有一个根元素、第二节:Vue实例化、入门:Vue六大常用内置指令等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10171401.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-06
下一篇 2023-05-06

发表评论

登录后才能评论

评论列表(0条)

保存