4、模板语法:插值表达式、v-text与v-html、v-bind绑定属性、v-on绑定事件
好,咱们继续往下走。上一章我们把 Vue 实例和模板的关系理清了,现在该动真格的了——模板语法。
说白了,模板语法就是 Vue 用来“说话”的方式。你想让页面显示什么、怎么显示、点击后干什么,都得靠这些语法告诉 Vue。我个人觉得,这部分是 Vue 最直观、最好玩的地方。你写一行代码,页面立马变样,那种即时反馈感,真的很爽。
4.1 插值表达式:最基础的“填空”
插值表达式,就是那对花括号 {{ }}。你可以在里面写变量、写表达式,Vue 会自动把结果填到 DOM 里。
<div id="app">
<p>{{ message }}</p>
<p>{{ 1 + 1 }}</p>
<p>{{ isActive ? '激活' : '未激活' }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: '你好,Vue!',
isActive: true
}
})
</script>
你看,{{ message }} 直接渲染成“你好,Vue!”。{{ 1 + 1 }} 会算出 2。三元表达式也能用,Vue 会帮你算好再填进去。
{{ if (true) { return 'a' } }} 这样写会报错。记住,它只是个“填空”,不是“编程区”。
我在项目中遇到过有人把很长的计算逻辑塞进插值表达式里,结果模板变得又臭又长。我的建议是:复杂的逻辑放到计算属性(后面会讲)里,模板只负责展示。
4.2 v-text 与 v-html:控制内容的两种方式
插值表达式有个小问题——如果网速慢,页面刚加载时会闪现出 {{ message }} 这种原始文本,用户体验不好。这时候 v-text 就派上用场了。
<!-- 等价写法 -->
<p>{{ message }}</p>
<p v-text="message"></p>
v-text 会直接替换掉标签里的所有内容。它不会闪烁,因为 Vue 在渲染前就把内容处理好了。
但 v-text 有个限制——它把内容当纯文本处理。如果你要渲染 HTML 标签,比如从后端拿到的富文本内容,就得用 v-html。
<div id="app">
<p v-text="htmlContent"></p>
<p v-html="htmlContent"></p>
</div>
<script>
new Vue({
el: '#app',
data: {
htmlContent: '<strong>加粗文字</strong>'
}
})
</script>
结果:v-text 显示的是 <strong>加粗文字</strong> 这段字符串,而 v-html 会渲染成真正的加粗文字。
v-html 渲染用户输入的内容!比如评论框、用户简介这些。我曾经见过一个项目,因为用了 v-html 渲染用户评论,结果被人注入了恶意脚本,整个站点的用户数据都泄露了。如果你非要渲染 HTML,一定要先做 XSS 过滤。
4.3 v-bind:动态绑定属性
插值表达式只能用在标签内容里,那标签的属性怎么办?比如你想让图片的 src 根据数据变化,或者让按钮的 disabled 状态跟着变量走。这时候就需要 v-bind。
<div id="app">
<img v-bind:src="imageUrl" alt="动态图片">
<button v-bind:disabled="isDisabled">点击</button>
<a v-bind:href="link">跳转</a>
</div>
<script>
new Vue({
el: '#app',
data: {
imageUrl: 'https://example.com/logo.png',
isDisabled: true,
link: 'https://vuejs.org'
}
})
</script>
v-bind:src 的意思就是:把 src 属性跟 imageUrl 这个数据绑定起来。数据一变,属性值也跟着变。
嗯,这里要注意:v-bind 可以简写成冒号 :。上面的代码可以写成:
<img :src="imageUrl" alt="动态图片">
<button :disabled="isDisabled">点击</button>
<a :href="link">跳转</a>
我个人习惯用简写,代码看起来更干净。但刚开始学的时候,建议先写全称,等熟悉了再换简写。
还有一个很实用的场景——动态绑定 class。比如根据某个状态切换样式:
<div :class="{ active: isActive, 'text-danger': hasError }">
这段文字会根据状态变化样式
</div>
当 isActive 为 true 时,这个 div 会加上 active 类;hasError 为 true 时,加上 text-danger 类。这种写法在写列表高亮、表单验证时特别常用。
4.4 v-on:绑定事件,让页面动起来
光有数据显示还不够,用户得能交互。点击按钮、输入文字、鼠标移动……这些都需要事件绑定。Vue 用 v-on 来处理。
<div id="app">
<button v-on:click="handleClick">点我</button>
<input v-on:input="handleInput">
<p>你输入了:{{ inputValue }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
inputValue: ''
},
methods: {
handleClick() {
alert('按钮被点击了!')
},
handleInput(event) {
this.inputValue = event.target.value
}
}
})
</script>
v-on:click 监听点击事件,v-on:input 监听输入事件。事件处理函数写在 methods 对象里,通过 this 访问 data 中的数据。
跟 v-bind 一样,v-on 也有简写——用 @ 符号:
<button @click="handleClick">点我</button>
<input @input="handleInput">
是不是简洁多了?我平时写代码基本都用简写,除非是团队规范要求写全称。
事件绑定还能传参数:
<button @click="say('你好')">打招呼</button>
<button @click="say('再见')">告别</button>
<script>
methods: {
say(msg) {
alert(msg)
}
}
</script>
有时候你既需要传参数,又需要访问原生事件对象,可以用 $event:
<button @click="handleClick('参数', $event)">点我</button>
{{ }}:插值表达式,显示数据,不能用于属性v-text:纯文本渲染,不会闪烁v-html:渲染 HTML,小心 XSS 攻击v-bind(简写:):动态绑定属性、class、stylev-on(简写@):绑定事件,处理用户交互
这四种模板语法,基本覆盖了日常开发 80% 的场景。你想想看,显示数据、控制内容、绑定属性、处理事件——一个交互页面需要的功能,这里全有了。
下一章我们会聊条件渲染和列表渲染,到时候这些语法会组合起来用,威力更大。先把这个基础打牢,后面学起来就顺了。