告别手动操作DOM,让数据驱动视图自动更新
作为Vue3的核心功能之一,模板语法让我们能够以声明式的方式将数据渲染到DOM中。无论你是刚入门的前端新手,还是从Vue2迁移过来的开发者,掌握模板语法都是用好Vue的第一步。今天我们就来全面解析Vue3的模板语法,从插值到指令,配合大量实用例子,帮你彻底搞懂!
一、插值:让数据“长”在页面上
1. 文本插值:最常用的{{ }}
数据绑定最常见的形式就是使用“Mustache”语法(双大括号)进行文本插值:
<template><div><p>message:<inputtype="text"v-model="message"/></p><p>count:<inputtype="number"v-model.number="count"min="0"step="0" /></p><p>isActive:<inputtype="checkbox"v-model="isActive"/></p></div><div><p>{{ message }}</p><p>{{ count + 1 }}</p><p>{{ isActive ? '激活' : '未激活' }}</p></div></template><scriptsetup>import { ref } from 'vue'const message = ref('Hello Vue3!')const count = ref(10)const isActive = ref(true)</script>
运行这段代码,可以看到双大括号标签会被替换为对应组件实例中属性的值,并且当数据发生变化时,插值处的内容会自动更新。
小技巧:如果你想实现一次性插值(数据变化不再更新),可以使用v-once指令:
<p v-once>{{ message }}</p>2. 原始HTML:使用v-html渲染富文本
双大括号会将数据解释为普通文本,而非HTML代码。要输出真正的HTML,需要使用v-html指令:
<template><div><p>使用双大括号: {{ rawHtml }}</p><p>使用v-html: <spanv-html="rawHtml"></span></p></div></template><scriptsetup>import { ref } from 'vue'const rawHtml = ref('<span style="color: red">我是红色的文字</span>')</script>
⚠️ 安全警告:在站点上动态渲染任意HTML是非常危险的,容易导致XSS攻击。请只对可信内容使用v-html,永远不要将用户提供的内容作为插值。
3. 属性绑定:v-bind动态绑定HTML属性
Mustache语法不能在HTML属性中使用,这时候需要v-bind指令出场了:
<template><div><!-- 完整语法 --><av-bind:href="url">访问链接</a><!-- 缩写语法(最常用) --><a:href="url">访问链接</a><!-- 动态绑定class --><div:class="{ active: isActive, 'text-danger': hasError }">动态类</div><!-- 绑定style --><div:style="{ color: textColor, fontSize: fontSize + 'px' }">动态样式</div></div></template><scriptsetup>import { ref } from 'vue'const url = ref('https://vuejs.org')const isActive = ref(true)const hasError = ref(false)const textColor = ref('blue')const fontSize = ref(20)</script>
注意:如果绑定的值是null或undefined,该属性将不会被包含在渲染出来的元素上。
4. 完整的JavaScript表达式支持
对于所有的数据绑定,Vue.js都提供了完全的JavaScript表达式支持:
<template><div><p>{{ number + 1 }}</p><p>{{ ok ? 'YES' : 'NO' }}</p><p>{{ message.split('').reverse().join('') }}</p><div:id="'list-' + id"></div><!-- 使用模板字符串 --><div:id="`list-${id}`"></div></div></template><scriptsetup>import { ref } from 'vue'const number = ref(100)const ok = ref(true)const message=ref('VUE3 TEST')const id = ref(1)</script>
⚠️ 限制:每个绑定只能包含单个表达式,下面的写法不会生效:
<!-- 这是语句,不是表达式 -->{{ var a = 1 }}<!-- 流控制也不会生效,请使用三元表达式 -->{{ if (ok) { return message } }}
二、指令:给DOM发号施令
指令是带有v-前缀的特殊属性,其职责是当表达式的值改变时,响应式地作用于DOM。
1. v-if / v-else-if / v-else:条件渲染
根据表达式的真假值,决定是否创建或销毁元素:
<template><div><!-- 登录状态展示不同内容 --><divv-if="!isLogin"><button @click="login">点击登录</button></div><divv-else><pv-if="userLevel === 'admin'">管理员:拥有所有权限</p><pv-else-if="userLevel === 'vip'">VIP用户:享受专属内容</p><pv-else>普通用户:基础功能</p><button @click="logout">退出登录</button></div></div></template><scriptsetup>import { ref } from 'vue'const isLogin = ref(false)const userLevel = ref('vip')const login = () => { isLogin.value = true }const logout = () => { isLogin.value = false }</script>
v-if vs v-show:
v-if:真正的条件渲染,条件为假时元素不会被渲染到DOM中。适合切换不频繁的场景
v-show:元素始终会被渲染,只是切换CSS的
display属性。适合频繁切换的场景
2. v-for:列表渲染
基于数组或对象循环渲染一组元素:
<template><div><!-- 1. 遍历数组 --><ul><liv-for="(item, index) in products":key="item.id">{{ index + 1 }}. {{ item.name }} - ¥{{ item.price }}</li></ul><!-- 2. 遍历对象 --><ul><liv-for="(value, key, index) in userInfo":key="key">{{ index }}. {{ key }}: {{ value }}</li></ul><!-- 3. 也可以使用of作为分隔符 --><liv-for="item of items":key="item.id">{{ item }}</li></div></template><scriptsetup>import { ref } from 'vue'const products = ref([{ id: 1, name: 'Vue实战教程', price: 99 },{ id: 2, name: 'TypeScript入门', price: 79 },{ id: 3, name: '前端面试指南', price: 129 }])const userInfo = ref({name: '小明',age: 25,profession: '前端开发'})</script>
⚠️ 关于key的黄金法则:
在v-for中,永远要加上:key,并且不要使用index作为key!
key帮助Vue识别每个节点的唯一性,从而高效更新DOM。使用id等唯一且稳定的标识符作为key是最佳实践。
<!-- ❌ 错误:使用index作为key --><liv-for="(item, index) in list":key="index">{{ item }}</li><!-- ✅ 正确:使用唯一id作为key --><liv-for="item in list":key="item.id">{{ item.name }}</li>
注意:不要在同一元素上同时使用v-if和v-for,因为v-if的优先级更高,会导致性能问题。应该先用计算属性过滤数据,再使用v-for渲染。
3. v-bind(缩写 :):属性绑定
我们已经在前面的属性绑定中介绍过了,这里再强调一下它的各种用法:
<template><div><!-- 基础用法 --><img:src="imageUrl"alt="图片"><a:href="linkUrl">链接</a><!-- 动态绑定class(对象语法) --><div:class="{ active: isActive, 'text-danger': hasError }">对象语法</div><!-- 动态绑定class(数组语法) --><div:class="[baseClass, statusClass]">数组语法</div><!-- 动态绑定style --><div:style="{ color: textColor, fontSize: fontSize + 'px' }">样式绑定</div></div></template>
4. v-on(缩写 @):事件绑定
用于监听DOM事件,并在触发时执行方法:
<template><div><p>点击次数:{{ count }}</p><!-- 1. 内联语句 --><button @click="count++">+1</button><!-- 2. 方法名 --><button @click="increment">+1</button><!-- 3. 带参数的方法 --><button @click="add(5)">+5</button><!-- 4. 访问事件对象 --><button @click="handleClick($event)">点击我</button><!-- 5. 事件修饰符 --><form @submit.prevent="onSubmit">阻止默认提交</form><div @click.stop="handleClick">阻止冒泡</div><button @click.once="doOnce">只触发一次</button><!-- 6. 按键修饰符 --><input @keyup.enter="submit"placeholder="按回车提交"></div></template><scriptsetup>import { ref } from 'vue'const count = ref(0)const increment = () => {count.value++}const add = (num) => {count.value += num}const handleClick = (event) => {console.log('点击了!', event)}const onSubmit = () => {console.log('提交表单')}</script>
常用事件修饰符:
.stop:阻止事件冒泡.prevent:阻止默认行为(如表单提交刷新页面).once:事件只触发一次.enter、.tab等:按键修饰符
5. v-model:双向数据绑定
在表单元素上创建双向数据绑定,数据变化驱动视图更新,视图变化也反过来更新数据
<template><div><inputv-model="message"placeholder="输入内容"><p>你输入的是:{{ message }}</p><textareav-model="desc"></textarea><inputtype="checkbox"v-model="checked"><p>{{ checked ? '已选中' : '未选中' }}</p><selectv-model="selected"><optionvalue="A">选项A</option><optionvalue="B">选项B</option></select></div></template><scriptsetup>import { ref } from 'vue'const message = ref('')const desc = ref('')const checked = ref(false)const selected = ref('A')</script>
三、总结
Vue3的模板语法让我们能够优雅地将数据与视图绑定,核心要点如下:
插值方式:
{{ }}:文本插值,支持JavaScript表达式v-html:渲染原始HTML(注意XSS风险)v-bind(:):动态绑定属性、class、style
核心指令:
v-if/v-else-if/v-else:条件渲染(创建/销毁)v-show:显示/隐藏(切换display)v-for:列表渲染(必须加key)v-on(@):事件绑定v-model:双向数据绑定
记住这些缩写:
v-bind:href→:hrefv-on:click→@click
掌握这些基础语法,你就能用Vue3构建出交互丰富的应用了!如果觉得文章有帮助,欢迎点赞收藏,我们下期见!🚀
往期回顾:
Vue3 侦听器全面指南:watch 和 watchEffect 你真的用对了吗?
夜雨聆风