DOM 模板解析注意事项
如果你想在 DOM 中直接书写 Vue 模板,Vue 则必须从 DOM 中获取模板字符串。由于浏览器的原生 HTML 解析行为限制,有一些需要注意的事项。
提示
请注意下面讨论只适用于直接在 DOM 中编写模板的情况。如果你使用来自以下来源的字符串模板,就不需要顾虑这些限制了:
- 单文件组件
- 内联模板字符串 (例如
template: '...'
) <script type="text/x-template">
大小写区分
HTML 标签和属性名称是不分大小写的,所以浏览器会把任何大写的字符解释为小写。这意味着当你使用 DOM 内的模板时,无论是 PascalCase 形式的组件名称、camelCase 形式的 prop 名称还是 v-on 的事件名称,都需要转换为相应等价的 kebab-case ( 短横线连字符) 形式:
// JavaScript 中的 camelCase
const BlogPost = {
props: ["postTitle"],
emits: ["updatePost"],
template: `
<h3>{{ postTitle }}</h3>
`,
};
template
<template>
<!-- HTML 中的 kebab-case -->
<blog-post post-title="hello!" @update-post="onUpdatePost"></blog-post>
</template>
闭合标签
我们在上面的例子中已经使用过了闭合标签 (self-closing tag):
<MyComponent />
这是因为 Vue 的模板解析器支持任意标签使用 />
作为标签关闭的标志。
然而在 DOM 模板中,我们必须显式地写出关闭标签:
<my-component></my-component>
这是由于 HTML 只允许一小部分特殊的元素 省略其关闭标签,最常见的就是 <input>
和 <img>
。对于其他的元素来说,如果你省略了关闭标签,原生的 HTML 解析器会认为开启的标签永远没有结束,用下面这个代码片段举例来说:
<template>
<my-component />
<!-- 我们想要在这里关闭标签... -->
<span>hello</span>
</template>
将被解析为:
<template>
<my-component>
<span>hello</span>
</my-component>
<!-- 但浏览器会在这里关闭标签 -->
</template>
元素位置限制
某些 HTML 元素对于放在其中的元素类型有限制,例如 <ul>
,<ol>
,<table>
和 <select>
,相应的,某些元素仅在放置于特定元素中时才会显示,例如 <li>
,<tr>
和 <option>
。
这将导致在使用带有此类限制元素的组件时出现问题。例如:
<template>
<table>
<blog-post-row></blog-post-row>
</table>
</template>
自定义的组件 <blog-post-row>
将作为无效的内容被忽略,因而在最终呈现的输出中造成错误。我们可以使用特殊的 is
attribute 作为一种解决方案:
<template>
<table>
<tr is="vue:blog-post-row"></tr>
</table>
</template>
注意
当使用在原生 HTML 元素上时,is
的值必须加上前缀 vue:
才可以被解析为一个 Vue 组件。这一点是必要的,为了避免和原生的自定义内置元素 相混淆。
以上就是你需要了解的关于 DOM 模板解析的所有注意事项,同时也是 Vue 基础部分的所有内容。
总结
vue 中 solt 的使用方式,以及 solt 作用域插槽的用法
使用方式:当组件当做标签进行使用的时候,用 slot 可以用来接受组件标签包裹的内容,当给 solt 标签添加 name 属性的 时候,可以调换响应的位置
(高级用法) 插槽作用域:当传递的不是单一的标签,例如需要循环时,把要循环的标签传入,组件内使用 v-for 在 slot 标签上, 内部可以
v-bind:
把值传出来,再外面把值赋予进去,看示例js<current-user> <template v-slot:default="slotProps"> {{slotProps.user.firstName}} </template> </current-user> // current-user 组件,user 属性和值,绑定给 slotProps 上 <span> <slot v-bind:user="user"> {{user.lastName}} </slot> </span>
跟 keep-alive 有关的生命周期是哪些?(必会)
在开发 Vue 项目的时候,大部分组件是没必要多次渲染的,所以 Vue 提供了一个内置组件 keep-alive 来缓存组件内部状态,避免重新渲染,在开发 Vue 项目的时候,大部分组件是没必要多次渲染的,所以 Vue 提供了一个内置组件 keep-alive 来缓存组件内部状态,避免重新渲染
生命周期函数:在被 keep-alive 包含的组件/路由中,会多出两个生命周期的钩子:
activated
与deactivated
。1、activated 钩子:在在组件第一次渲染时会被调用,之后在每次缓存组件被激活时调用。
Activated 钩子调用时机:
- 第 1 次进入缓存路由/组件,在
mounted
后面 - beforeRouteEnter 守卫传给 next 的回调函数之前调用
- 如果组件被缓存了,再次进入缓存路由、组件时,不会触发这些钩子函数,
beforeCreate
、created
、beforeMount
、mounted
都不会触发
2、deactivated 钩子:组件被停用(离开路由)时调用。
deactivated 钩子调用时机:
使用 keep-alive 就不会调用 beforeDestroy (组件销毁前钩子) 和 destroyed (组件销毁) ,因为组件没被销毁,被缓存起来了,这个钩子可以看作 beforeDestroy 的替代,
如果缓存了组件,要在组件销毁的的时候做一些事情,可以放在这个钩子里,组件内的离开当前路由钩子
beforeRouteLeave
=>beforeEach
(路由前置守卫) =>afterEach
(全局后置钩子) =>deactivated
(离开缓存组件) =>activated
进入缓存组件 (如果你进入的也是缓存路由)
- 第 1 次进入缓存路由/组件,在
自定义指令 (v-check、v-focus) 的方法有哪些?它有哪些钩子函数?还有哪些钩子函数参数?(必会)
全局定义指令:在 vue 对象的 directive 方法里面有两个参数,一个是指令名称,另外一个是函数。组件内定义指令:directives
钩子函数:bind(绑定事件触发)、inserted(节点插入的时候触发)、update(组件内相关更新)
钩子函数参数:el、binding
is 这个特性你有用过吗?主要用在哪些方面?(高薪常问)
1)动态组件
<component :is="componentName"></component>
,componentName 可以是在本页面已经注册的局部组件名和全局组件名,也可以是一个组件的选项对象。 当控制 componentName 改变时就可以动态切换选择组件。2)
is
的用法有些 HTML 元素,诸如
<ul>
、<ol>
、<table>
和<select>
,对于哪些元素可以出现在其内部是有严格限制的。而有些 HTML 元素,诸如
<li>
、<tr>
和<option>
,只能出现在其它某些特定的元素内部。html<ul> <card-list></card-list> </ul>
所以上面
<card-list></card-list>
会被作为无效的内容提升到外部,并导致最终渲染结果出错。应该这么写:html<ul> <li is="cardList"></li> </ul>