2.模板与指令
2.1 模板语法
学习:插值表达式、js表达式、v-cloak
Vue 使用一种基于 HTML 的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的 DOM 上。所有的 Vue 模板都是语法层面合法的 HTML,可以被符合规范的浏览器和 HTML 解析器解析。
{
{ number + 1 }}
{
{ ok ? 'YES' : 'NO' }}
{
{ message.split('').reverse().join('') }}
<div :id="`list-${id}`"></div>
在底层机制中,Vue 会将模板编译成高度优化的 JavaScript 代码。结合响应式系统,当应用状态变更时,Vue 能够智能地推导出需要重新渲染的组件的最少数量,并应用最少的 DOM 操作。
2.1.1 文本插值
最基本的数据绑定形式是文本插值,它使用的是“Mustache[ˈmʌstæʃ]”语法 (即双大括号):
<span>Message: {
{ msg }}</span>
双大括号标签会被替换为相应组件实例中
msg
属性的值。同时每次msg
属性更改时它也会同步更新。
2.1.2 js表达式
Vue 实际上在所有的数据绑定中都支持完整的 JavaScript 表达式:
这些表达式都会被作为 JavaScript ,以组件为作用域解析执行。
在 Vue 模板内,JavaScript 表达式可以被使用在如下场景上:
在文本插值中 (双大括号)
在任何 Vue 指令 (以
v-
开头的特殊 attribute) attribute 的值中绑定在表达式中的方法在组件每次更新时都会被重新调用,因此不应该产生任何副作用,比如改变数据或触发异步操作。
2.1.3 v-cloak
用于隐藏尚未完成编译的 DOM 模板。
当使用直接在 DOM 中书写的模板时,可能会出现一种叫做“未编译模板闪现”的情况:用户可能先看到的是还没编译完成的双大括号标签,直到挂载的组件将它们替换为实际渲染的内容。
v-cloak
会保留在所绑定的元素上,直到相关组件实例被挂载后才移除。配合像 [v-cloak] { display: none }
这样的 CSS 规则,它可以在组件编译完毕前隐藏原始模板。
[v-cloak] {
display: none;
}
<div v-cloak>
{
{ message }}
</div>
直到编译完成前,
<div>
将不可见。
完整案例:06_mustache.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>06_模板语法</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<!-- v-cloak -->
<div id="app" v-cloak>
<!-- 文本插值 -->
<div>{
{ msg }}</div>
<!-- js表达式 -->
<div>{
{ number + 1 }}</div>
<div>{
{ flag ? 'ok': 'no' }}</div>
<div>{
{ message.split('').reverse().join('-') }}</div>
<div v-bind:id="'list-' + id">111</div>
<div v-bind:id=`list-${id}`>222</div>
</div>
</body>
<script src="lib/vue.global.js"></script>
<script>
const { createApp } = Vue
const app = createApp({
data () {
return {
msg: 'hello vue',
number: 100,
flag: true,
message: 'hello world',
id: 100
}
}
})
app.mount('#app')
</script>
</html>
2.2 文本类指令
学习:v-text、v-html、v-pre
2.2.1 v-html & v-text
双大括号将会将数据插值为纯文本,而不是 HTML。若想插入 HTML,你需要使用 v-html 指令:
<div v-html="rawHTML"></div>
<div v-text="rawHTML"></div>
<div>{
{rawHTML}}</div>
在网站上动态渲染任意 HTML 是非常危险的,因为这非常容易造成 XSS 漏洞。请仅在内容安全可信时再使用
v-html
,并且永远不要使用用户提供的 HTML 内容(script也属于HTML内容)。
2.2.2 v-pre
元素内具有 v-pre
,所有 Vue 模板语法都会被保留并按原样渲染。最常见的用例就是显示原始双大括号标签及内容。
<div v-pre>{
{ rawHTML }}</div>
完整案例: 07_text.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>07_文本类指令</title>
</head>
<body>
<div id="app">
<!-- 解析输出 -->
<div v-html="msg"></div>
<!-- 转义输出 -->
<div v-text="msg"></div>
<!-- 文本插值 -->
<div>{
{ msg }}</div>
<!-- v-pre 含有该指令的标签内部的语法不会被vue解析 -->
<div v-pre>{
{ msg }}</div>
</div>
</body>
<script src="lib/vue.global.js"></script>
<script>
const { createApp } = Vue
const app = createApp({
data () {
return {
msg: '<h1>hello vue</h1>'
}
}
})
app.mount('#app')
</script>
</html>
2.3 属性绑定
学习:v-bind 以及简写形式
双大括号不能在 HTML attributes 中使用。想要响应式地绑定一个 attribute,应该使用 v-bind 指令:
<div v-bind:id="myId"></div>
如果绑定的值是
null
或者undefined
,那么该 attribute 将会从渲染的元素上移除。
因为 v-bind
非常常用,提供了特定的简写语法:
<div :id="myId"></div>
开头为
:
的 attribute 可能和一般的 HTML attribute 看起来不太一样,但它的确是合法的 attribute 名称字符,并且所有支持 Vue 的浏览器都能正确解析它。
布尔型 attribute 依据 true / false 值来决定 attribute 是否应该存在于该元素上。disabled 就是最常见的例子之一。
<button :disabled="flag">Button</button>
当 flag
为真值或一个空字符串 (即 <button disabled="">
) 时,元素会包含这个 disabled
attribute。而当其为其他假值时 attribute 将被忽略。
如果你有像这样的一个包含多个 attribute 的 JavaScript 对象:
data () {
return {
obj: {
a: 1,
b: 2
}
}
}
<div v-bind="obj"></div>
完整案例: 08_attribute.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatibl