Vue.js是以HTML为基础的模板语法,它允许你声明式的将底层组件实例的data数据绑定到渲染的DOM。所有的Vue.js模板都是合法的HTML,可以被标准浏览器或HTML解释器识别。
在底层,Vue将模板编译成虚拟DOM渲染函数。结合系统响应方面,当场景发生变化时,Vue巧妙的用最少的重新渲染组件最少操作DOM次数提升运行效率。
如果你熟悉虚拟DOM以及喜欢原生JavaScript,你也可以直使用JSX支持编写渲染函数来替代模板。
插值
文字
文字是使用最多的基础表单绑定数据,使用"Mustache"语法(双花括号):<span>Message: {{ msg }}</span>
双花括号标签会被相关实例中的msg```变量值所替换。当实例中
msg发生变化时,模板中的内容也会同步更新。也可以使用
v-once指令对插值做一次性绑定,当data中的msg发生变化时,模板不会更新。但是需要注意,这也会影响到同一节点下的其他绑定。
Message: {{ msg }}```
原生HTML
双花括号插值只能显示静态文本,不能解释HTML。如果想输出真正的HTML,你可以使用v-html
指令:
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>vue demo3</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<p>静态文本插值:{{ rawHTML }}</p>
<p>使用v-html指令:<span v-html="rawHTML"></span></p>
</div>
</body>
<script type="text/javascript">
const app = {
data() {
return {
rawHTML : '<span style="color: red">这段文字应该展示成红色.</span>'
}
},
}
Vue.createApp(app).mount("#app")
</script>
</html>
运行结果如下图:
span标签的内容将会被rawHTML值替换掉,静态文本插值--数据绑定被忽略。注意,你不能通过v-html
来对合成局部模板,因为Vue不是基于字符串的模板引擎。对于一些需要重复使用的需要组合的界面UI,可以使用组件来代替。
提示
站点中动态渲染任意HTML是非常危险的,因为很容易导致XSS攻击。只渲染受信任的内容,永远不要相信用户输入。
属性
Mustaches语法不能用于HTML属性,应用使用v-bind
指令代替:
<div v-bind:id="dynamicId"></div>
如果被绑定的值是null
或undefined
,这个属性将不会被渲染到该标签。
布尔值因为只要存在就可以被认为是true``,
v-bind```的工作方式有一点不同:
<button v-bind:disabled="isButtonDisabled">btn</button>
只要isButtonDisabled
有值disabled
属性就会被包含进来,甚至是一个空字符串也会被解释成disabled=""
。对于其他错误的值,该属于将被忽略掉。
使用JavaScript表达式
到目前为止,我们还是只在模板中绑定简单的属性键,实际上Vue.js可以绑定所有JavaScript表达式。
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-'+id"></div>
这些表达式都会在当前活动实例的数据域中以JavaScript方式进行执行。有一个约束是一个绑定只能包含一个简单的表达式,所以下面的表达式不会被执行:
<!-- 这是一个赋值语句,不是一个表达式 -->
{{ var a = 1 }}
<!-- 流程控制也不会被执行,可以使用三元表达式来替代 -->
{{ if(ok) { return message }
指令
指令是有v-
前缀的特殊属性。指令值一般是一个简单的JavaScript表达式(v-for
和v-on
除外,后面再讨论)。指令的作用是当值发生改变时需要响应式的影响到界面的DOM上,我们来复习一下在介绍章节中的一个小示例:
<p v-if="seen">看不见我?看的见我?</p>
这里v-if
指令的作用是,通过控制seen
真或假,来插入/删除p
标签。
指令-参数
一些指令可以通过在指令名的后加冒号来携带一个“参数”,例如v-bind
指令可以响应式的更新HTML属性。
<a v-bind:href="url">...</a>
这里href
就是参数,它告诉v-bind
指令通过url
变量来绑定href
标签属性。
还有一个就是v-on
指令,用来监听DOM的事件:
<a v-on:click="doSomething">点我</a>
这里的参数用来监听事件。我们在后面会讨论事件。(doSomething可以在methods中定义一个方法就可以了)
指令-动态参数
同时指令也支持用方括号来包裹一个JavaScript动态的表达式指令参数:
<!--
注意有一些动态参数的约束,将会在下面的《动态表达式参数约束》中解释
-->
<a v-bind:[attributeName]="url">...</a>
这里attributeName
会通过JavaScript表达式动态指定,表达式结果将会作为指令的最终参数。例如你的组件实例有一个数据属性attributeName
,而它的值是href
,上面这条绑定就等价于v-bind:href
。
相似的,你可以通过动态属性绑定一个事件名:
<a v-on:[eventName]="doSomething">....</a>
在这个例子中,如果eventName
值是focus
,则v-on:[eventName]
等价于v-on:focus
。
指令-修饰符
修饰符是在指令加一个点号后缀,表明这个指令将以特殊的方式进行绑定。举个例子,prevent
修饰符是告诉指令当事件被触发时,将会调用event.preventDefault()
方法。
<form v-on:submit.prevent="onSubmit">...</form>
如果你想研究v-on
、```v-model``的修饰符功能,后面会有这方面的例子。
缩写
v-
前缀,可视化的表明是模板中一个特殊的Vue属性。这在你想用Vue.js标识一些动态行为时很有用处,但对一些频繁用到的指令来说就比较繁琐了。同时,当Vue管理所有模板时,构建SPA(单页面应用),v-
前缀的需求就没有那么重要了。因此Vue为经常用到的两个指令v-bind
,v-on
提供了缩写:v-bind
缩写:
<!-- 完整写法 -->
<a v-bind:href="url">...</a>
<!--缩写-->
<a :href="url">...</a>
<!-- 动态参数缩写 -->
<a :[key]="url">...</a>
v-on
缩写:
<!-- 完整写法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>
<!-- 动态参数缩写 -->
<a @[event]="doSomething">...</a>
这看起来跟普通HTML有一点区别,但:
和@
是合法的字符,属性名和所有Vue支持的浏览器上都能被正确解释。另外,他们不会出现在最终渲染标记中。缩写是一个可选项,但随着学习的深入你会喜欢上缩写的。
后面章节中示例中,我们会使用缩写,这是Vue开发人员通用使用方式。
警告
动态参数值约束
动态参数值期望是一个字符串,null
例外。null
比较特殊,会移除绑定。所有非字符串值将会触发一个告警。
动态参数表达式约束
因为某些字符,动态参数表达式有一些语法上的约束,比如空格和引号,是不能作为HTML属性名的。下面的例子是不合法的:
<!-- 这是触发编译器警告 -->
<a v-bind:['foo' + bar]="value">...</a>
我们推荐用计算属性来替代复杂表达式,计算属性是Vue非常重要的部分,马上就会学习到。
当使用内联DOM模板(在HTML中直接写模板)时,应当避免在关键字上使用大写字母,浏览器会将大写字母纠正为小写:
<!--
内联模板会转换为:v-bind:[someattr]。
除非在你的实例中有“someattr”属性,否则代码不会运行通过。
-->
<a v-bind:[someAttr]="value">...</a>
JavaScript表达式
模板表达式是沙箱,且只允许访问白名单中的全局变量,如Math
或Date
。你不应该在模板表达式中尝试访问用户自定义的全局变量。