这一节了解一下Vue3中的模板知识,模板是Vue框架中重要组成部分,它采用了基于HTML的模板语法。模板属于视图层,它的作用是让开发者将重心放在页面布局渲染上,而不是关心数据逻辑。
API
1、模板插值语法 1.1. {{ 变量名 }} 文本插值
含义:最基础的模板输出,将数据渲染到页面。作用:显示变量、表达式结果。
javascript
<template>
<view>姓名:{{ name }}</view>
<view>计算:{{ 10 + 20 }}</view>
</template>
<script setup>
const name = '张三'
</script>
1.2. v-once 一次性插值
含义:只渲染一次,数据变化不再更新。作用:优化静态内容。
javascript
<view v-once>{{ msg }}</view>
<script setup>const msg = '只显示一次'</script>
1.3. v-html 输出 HTML
含义:渲染富文本。作用:展示带标签的内容。
javascript
<view v-html="html"></view>
<script setup>const html = '<span style="color:red">红色文字</span>'</script>
2、属性绑定 API
2.4. v-bind:属性 / :属性
含义:动态绑定标签属性(id、class、src、style 等)。作用:让 HTML 属性变成动态可修改。
javascript
<view :id="myId" :title="tip"> hover 看提示 </view>
<script setup>const myId = 'test', tip = '提示文字'</script>
2.5. v-bind:class 对象绑定
含义:按条件显示样式类。作用:动态切换样式。
javascript
<view :class="{ active: isActive }">文字</view>
<script setup>const isActive = true</script>
<style>.active{color:red}</style>
2.6. v-bind:class 数组绑定
含义:同时应用多个样式。作用:组合样式。
javascript
<view :class="[classA, classB]">内容</view>
<script setup>const classA='box', classB='border'</script>
2.7. v-bind:style 内联样式
含义:动态绑定 CSS 样式。作用:实时修改颜色、大小、位置。
javascript
<view :style="{ color: textColor }">颜色</view>
<script setup>const textColor = 'blue'</script>
3、条件渲染 API
3.8. v-if
含义:满足条件才渲染节点(会销毁 / 重建)。作用:控制模块显示 / 隐藏。
javascript
<view v-if="show">显示内容</view>
<script setup>const show = true</script>
3.9. v-else-if
含义:多条件分支。作用:类似 if...else if...else。
javascript
<view v-if="score>=90">优秀</view>
<view v-else-if="score>=60">及格</view>
<view v-else>不及格</view>
<script setup>const score = 85</script>
3.10. v-else
含义:否则渲染。作用:兜底显示。
3.11. v-show
含义:通过 display:none 显示 / 隐藏。作用:频繁切换用 v-show 性能更好。
javascript
<view v-show="isShow">v-show 控制</view>
<script setup>const isShow = true</script>
4、循环渲染 API
4.12. v-for="item in list"
含义:遍历数组 / 对象,循环渲染列表。作用:展示列表数据
javascript
<view v-for="item in list" :key="item.id">{{ item.name }}</view>
<script setup>
const list = [{id:1,name:'苹果'}, {id:2,name:'香蕉'}]
</script>
4.13. v-for="(item,index) in list"
含义:带索引循环。作用:显示序号。
javascript
<view v-for="(item,idx) in list" :key="idx">第{{idx+1}}项:{{item}}</view>
<script setup>const list=['A','B','C']</script>
4.14. v-for="(val,key,idx) in obj"
含义:遍历对象。作用:读取对象键值对。
javascript
<view v-for="(val,key) in user" :key="key">{{key}}:{{val}}</view>
<script setup>const user={name:'小明',age:20}</script>
4.15. template 无渲染包装
含义:包装多元素,不产生额外标签。作用:批量控制 v-if /v-for。
javascript
<template v-if="show">
<view>标题</view>
<view>内容</view>
</template>
5、事件绑定 API
5.16. v-on:事件 / @事件
含义:绑定点击、输入、触摸等事件。作用:响应用户操作。
javascript
<button @click="add">+1</button>
<script setup>
const count = ref(0)
const add = () => count.value++
</script>
5.17. 事件对象 $event
含义:自动传入事件信息。作用:获取输入值、点击位置等。
javascript
<input @input="onInput($event)" />
<script setup>
const onInput = (e) => console.log(e.target.value)
</script>
6、表单双向绑定
6.18. v-model
含义:数据 ↔ 视图自动同步。作用:快速处理表单。
javascript
<input v-model="val" placeholder="输入测试" />
<view>输入:{{ val }}</view>
<script setup>const val = ref('')</script>
6.19. v-model.trim
含义:自动去除首尾空格。作用:净化输入。
javascript
<input v-model.trim="msg" />
6.20. v-model.lazy
含义:失去焦点再同步。作用:减少频繁更新。
javascript
<input v-model.lazy="info" />
6.21. v-model.number
含义:自动转数字。作用:输入数字专用。
javascript
<input v-model.number="num" type="text" />
栗子:
javascript
<template>
<view class="p-4">
<view>{{ msg }}</view>
<view v-html="html"></view>
<button @click="count++">点击:{{ count }}</button>
<view v-if="isShow">v-if 显示</view>
<view v-show="isShow">v-show 显示</view>
<view v-for="(item,idx) in list" :key="idx">
{{ idx+1 }}. {{ item }}
</view>
<input v-model.trim="inputVal" placeholder="输入" />
<view>输入内容:{{ inputVal }}</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const msg = ref('模板Demo')
const html = ref('<span style=color:blue>v-html演示</span>')
const count = ref(0)
const isShow = ref(true)
const list = ref(['Vue', '模板', '指令'])
const inputVal = ref('')
</script>
javascript
<template>
<view class="container">
<view class="title">模板Demo</view>
<view v-once class="tip">固定内容:{{ fixedText }}</view>
<view v-html="htmlContent" class="tip"></view>
<view
class="box"
:class="{ active: isActive }"
:style="{ backgroundColor: bgColor }"
@click="isActive = !isActive"
>
点击切换样式
</view>
<view class="section">
<button @click="showContent = !showContent">切换显示</button>
<view v-if="showContent" class="info">内容已显示</view>
<view v-else class="info">内容已隐藏</view>
</view>
<view v-show="showContent" class="tip">v-show 跟随显示</view>
<view class="section">
<input
v-model.trim="inputValue"
class="input"
placeholder="输入文字"
/>
<view>实时输入:{{ inputValue }}</view>
</view>
<view class="section">
<view class="sub-title">水果列表</view>
<view
v-for="(item, index) in fruitList"
:key="index"
class="list"
>
{{ index + 1 }}. {{ item }}
<button size="mini" @click="delItem(index)">删除</button>
</view>
</view>
<button type="primary" @click="addItem">添加水果</button>
</view>
</template>
<script setup>
import { ref } from 'vue'
const fixedText = ref('我不会变')
const htmlContent = ref('<span style="color:blue">我是蓝色HTML文本</span>')
const isActive = ref(false)
const bgColor = ref('#f5f5f5')
const showContent = ref(true)
const inputValue = ref('')
const fruitList = ref(['苹果', '香蕉', '橙子', '葡萄'])
const addItem = () => {
if (!inputValue.value) return
fruitList.value.push(inputValue.value)
inputValue.value = ''
}
const delItem = (index) => {
fruitList.value.splice(index, 1)
}
</script>
<style scoped>
.container {
padding: 30rpx;
}
.title {
font-size: 36rpx;
font-weight: bold;
margin-bottom: 20rpx;
text-align: center;
}
.tip {
margin: 10rpx 0;
}
.box {
padding: 30rpx;
border-radius: 10rpx;
text-align: center;
margin: 20rpx 0;
}
.active {
color: white;
font-weight: bold;
}
.section {
margin: 25rpx 0;
}
.info {
margin-top: 15rpx;
padding: 15rpx;
background: #f9f9f9;
border-radius: 8rpx;
}
.input {
border: 1rpx solid #eee;
padding: 20rpx;
border-radius: 10rpx;
margin-bottom: 10rpx;
}
.sub-title {
font-weight: bold;
margin-bottom: 10rpx;
}
.list {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
</style>