Vue
Vue
目录
模板语法
Vue 使用一种基于 HTML 的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的 DOM 上。 所有的 Vue 模板都是语法层面合法的 HTML,可以被符合规范的浏览器和 HTML 解析器解析。
在底层机制中,Vue 会将模板编译成高度优化的 JavaScript 代码。 结合响应式系统,当应用状态变更时,Vue 能够智能地推导出需要重新渲染的组件的最少数量,并应用最少的 DOM 操作。
如果你对 虚拟 DOM 的概念比较熟悉,并且偏好直接使用 JavaScript,你也可以结合可选的 JSX 支持直接手写渲染函数而不采用模板。 但请注意,这将不会享受到和模板同等级别的编译时优化。
文本插值(“Mustache”语法)
最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号):
<span>Message: {{ msg }}</span>
原始 HTML(v-html)
<p>Using text interpolation: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
这里我们遇到了一个新的概念。这里看到的 v-html
attribute 被称为一个指令。 指令由 v-
作为前缀,表明它们是一些由 Vue 提供的特殊 attribute,你可能已经猜到了,它们将为渲染的 DOM 应用特殊的响应式行为。 这里我们做的事情简单来说就是:在当前组件实例上,将此元素的 innerHTML 与 rawHtml
属性保持同步。
span
的内容将会被替换为 rawHtml
属性的值,插值为纯 HTML——数据绑定将会被忽略。 注意,你不能使用 v-html
来拼接组合模板,因为 Vue 不是一个基于字符串的模板引擎。 在使用 Vue 时,应当使用组件作为 UI 重用和组合的基本单元。
[|安全警告]
在网站上动态渲染任意 HTML 是非常危险的,因为这非常容易造成 XSS 漏洞。 请仅在内容安全可信时再使用 v-html
,并且永远不要使用用户提供的 HTML 内容。
Attribute 绑定
双大括号不能在 HTML attributes 中使用。想要响应式地绑定一个 attribute,应该使用 v-bind
指令:
<div v-bind:id="dynamicId"></div>
v-bind
指令指示 Vue 将元素的 id
attribute 与组件的 dynamicId
属性保持一致。如果绑定的值是 null
或者 undefined
,那么该 attribute 将会从渲染的元素上移除。
因为 v-bind 非常常用,我们提供了特定的简写语法:
<div :id="dynamicId"></div>
布尔型 Attribute
[|笔者]:(这个好像是新增的)
布尔型 attribute 依据 true / false 值来决定 attribute 是否应该存在于该元素上。disabled
就是最常见的例子之一。
v-bind
在这种场景下的行为略有不同:
<button :disabled="isButtonDisabled">Button</button>
当 isButtonDisabled
为真值或一个空字符串 (即 <button disabled="">
) 时,元素会包含这个 disabled
attribute。 而当其为其他假值时 attribute 将被忽略。
动态绑定多个值
<div v-bind="objectOfAttrs"></div>
const objectOfAttrs = {
id: 'container',
class: 'wrapper'
}
使用 JavaScript 表达式
Vue 实际上在所有的数据绑定中都支持完整的 JavaScript 表达式
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div :id="`list-${id}`"></div>
JavaScript 表达式可以被使用在如下场景上:
- 在文本插值中 (双大括号)
- 在任何 Vue 指令 (以
v-
开头的特殊 attribute) attribute 的值中
仅支持表达式
每个绑定仅支持单一表达式,也就是一段能够被求值的 JavaScript 代码。 一个简单的判断方法是是否可以合法地写在 return
后面。
因此,下面的例子都是无效的:
<!-- 这是一个语句,而非表达式 -->
{{ var a = 1 }}
<!-- 条件控制也不支持,请使用三元表达式 -->
{{ if (ok) { return message } }}
调用函数
可以在绑定的表达式中使用一个组件暴露的方法:
<span :title="toTitleDate(date)">
{{ formatDate(date) }}
</span>
[|TIP] 绑定在表达式中的方法在组件每次更新时都会被重新调用,因此不应该产生任何副作用,比如改变数据或触发异步操作。
受限的全局访问
模板中的表达式将被沙盒化,仅能够访问到有限的全局对象列表。 该列表中会暴露常用的内置全局对象,比如 Math
和 Date
。
没有显式包含在列表中的全局对象将不能在模板内表达式中访问,例如用户附加在 window
上的属性。然而,你也可以自行在 app.config.globalProperties
上显式地添加它们,供所有的 Vue 表达式使用。
指令 Directives
指令是带有 v-
前缀的特殊 attribute
参数 Arguments
略
动态参数
同样在指令参数上也可以使用一个 JavaScript 表达式,需要包含在一对方括号内:
<!--
注意,参数表达式有一些约束,
参见下面“动态参数值的限制”与“动态参数语法的限制”章节的解释
-->
<a v-bind:[attributeName]="url"> ... </a>
<!-- 简写 -->
<a :[attributeName]="url"> ... </a>
这里的 attributeName
会作为一个 JavaScript 表达式被动态执行,计算得到的值会被用作最终的参数。 举例来说,如果你的组件实例有一个数据属性 attributeName
,其值为 "href"
,那么这个绑定就等价于 v-bind:href
。
相似地,你还可以将一个函数绑定到动态的事件名称上:
<a v-on:[eventName]="doSomething"> ... </a>
<!-- 简写 -->
<a @[eventName]="doSomething">
在此示例中,当 eventName
的值是 "focus"
时,v-on:[eventName]
就等价于 v-on:focus
。
动态参数值的限制
动态参数中表达式的值应当是一个字符串,或者是 null
。特殊值 null
意为显式移除该绑定。其他非字符串的值会触发警告。
动态参数语法的限制
动态参数表达式因为某些字符的缘故有一些语法限制,比如空格和引号,在 HTML attribute 名称中都是不合法的。例如下面的示例:
<a :['foo' + bar]="value"> ... </a>
如果你需要传入一个复杂的动态参数,我们推荐使用计算属性替换复杂的表达式,也是 Vue 最基础的概念之一,我们很快就会讲到。
当使用 DOM 内嵌模板 (直接写在 HTML 文件里的模板) 时,我们需要避免在名称中使用大写字母,因为浏览器会强制将其转换为小写:
<a :[someAttr]="value"> ... </a>
上面的例子将会在 DOM 内嵌模板中被转换为 :[someattr]
。如果你的组件拥有 “someAttr” 属性而非 “someattr”,这段代码将不会工作。单文件组件内的模板不受此限制。
修饰符 Modifiers
修饰符是以点开头的特殊后缀,表明指令需要以一些特殊的方式被绑定。 例如 .prevent
修饰符会告知 v-on
指令对触发的事件调用 event.preventDefault()
:
<form @submit.prevent="onSubmit">...</form>
之后在讲到 v-on
和 v-model
的功能时,你将会看到其他修饰符的例子。
最后,在这里你可以直观地看到完整的指令语法:
总结
新总结
数据单向绑定
Mustache 语法
<h1>{{ message }}</h1>
v-html
<h1 v-html='message'></h1>
v-text
<h1 v-text='message'></h1>
数据双向绑定
v-model
<input type="text" v-model="message"/>
属性单向绑定
v-bind
<h1 v-bind:id="dynamicId"></h1> <!-- 简写 --> <h1 :id="dynamicId"></h1>
函数绑定
v-on
<button v-on:click="handleIncrement"></button> <!-- 简写 --> <button @click="handleIncrement"></button>
旧笔记的总结
<div id="app">
<!-- 4种数据绑定----------------------------------------->
<h1>{{ message }}</h1> // 数据绑定 {{}}、v-html、v-text
<input type="text" v-model="message"/> // 双向绑定 v-model
<button v-on:click="handleIncrement"></button> // 函数绑定 v-on:方法、@方法
<h1 v-bind:class="{done: item.done}"></h1> // 属性绑定 v-bind:属性、:属性
<!-- 2种流程语法------------------------------------------->
<li v-if="show">mess</li> // 显示隐藏 v-if、v-else-if、v-else、v-show
<li v-for="item in items">{{item.mess}}</li> // 循环指令 v-for; item in shuzu、item in obj取v
</div>
补充
数据绑定的补充,插值语法
<h1>{{ message }}</h1> // Mustache语法,可运算
<h1 v-html=''></h1> // 编译内容
<h1 v-text=''></h1> // 不编译内容
<h1 v-cloak></h1> // 解析再显 v-cloak 斗篷,解决js卡顿时用户能看到{{}}的问题
<h1 v-once>{{ message }}</h1> // 禁用改变 v-once 只改变一次(不让数据驱动视图)
<h1 v-pre>{{ message }}</h1> // 禁用编译 v-pre 文本显示
双向绑定的补充
多种表单的的绑定
绑定文本框 // 返回内容
绑定单选框 // (多个绑定同一个变量)返回选中值
绑定复选框单选 // 返回布尔
绑定复选框多选 // (多个绑定同一个变量)返回数组
绑定Select单选 // 返回Value
修饰符
v-model.lazy // 懒绑定,让input事件更新数据 转换为 回车/失焦时更新数据
v-model.number // 把内容自动转换为数字
v-model.trim // 删除两侧空格
属性绑定的补充,对象语法和数组语法
对象语 法,后接对象 :class="{active: true, line: false}" :style="{font-size: '50px'}"
数组语法,后接数组 :class=[actice, 'line'] :style="[{}, {}]"
也可以接返回对象/数组的函数 :class="getClasses()"
方法绑定的补充,'()'的省略与修饰符
括号省略
方法无参时 // 可省略'()'
方法有参时 // 不省略'()'时传递undefine,省略'()'时传递浏览器生成的event时间对象
event值 // 也可用'($event)'手动传递,这个值挺有用的:如:event.target.value
修饰符
.stop // 阻止事件冒泡(嵌套事件监听),Ex:@click.stop=''
.prevent // 阻止默认行为(后接函数以外),Ex:@submit.prevent,@click.stop.prevent=''
.(键值/别名) // 监听指定键盘键帽(键别名/键值)Ex:@keyup.enter='onEnter',@keydown.13='onEnter'
.native // (在组件内才会用到)
.once // 只触发一次回调,Ex:@click.once='doThis'
if补充
v-if/v-else-if/v-else(整体删减))、v-show(display隐藏)
Virtual Dom对Dom的复用问题
for补充
v-for; (item, index) in shuzu、(value, key, index) in obj
Virtual Dom对Dom的复用问题。这里建议加key:item
能更好复用。如数组内插入元素后,原来的dom不会修改