Vue3-内置内容
内置指令
<template>
<div>
<!-- v-text -->
<h2 v-text="title"></h2>
<!-- v-html -->
<div v-html="htmlContent"></div>
<!-- v-show -->
<p v-show="showText">这段文字用 v-show 控制显示</p>
<!-- v-if / v-else-if / v-else -->
<div v-if="status === 'success'">操作成功</div>
<div v-else-if="status === 'error'">操作失败</div>
<div v-else>未知状态</div>
<!-- v-for -->
<ul>
<li v-for="(item, index) in list" :key="index">{{ index + 1 }} - {{ item }}</li>
</ul>
<!-- v-on -->
<button @click="handleClick">点击我</button>
<!-- v-bind -->
<img :src="imgUrl" :alt="imgAlt" />
<!-- v-model -->
<input v-model="inputText" placeholder="双向绑定输入框" />
<p>你输入了: {{ inputText }}</p>
<!-- v-slot -->
<BaseCard>
<template #header>
<h3>我是插槽 header</h3>
</template>
<template #default>
<p>我是默认插槽内容</p>
</template>
<template #footer>
<p>我是 footer 插槽</p>
</template>
</BaseCard>
<!-- v-pre -->
<div v-pre>{{ 不会被 Vue 解析的内容 }}</div>
<!-- v-once -->
<p v-once>只渲染一次,数据变化也不会更新:{{ onceText }}</p>
<!-- v-memo (仅 Vue3.2+,性能优化,演示写法) -->
<p v-memo="[memoCondition]">v-memo 控制的内容</p>
<!-- v-cloak -->
<p v-cloak>v-cloak 避免闪烁(需结合 CSS)</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
import BaseCard from './BaseCard.vue'
const title = ref('这是 v-text 渲染的标题')
const htmlContent = ref('<strong style="color:red">这是 v-html 渲染的加粗内容</strong>')
const showText = ref(true)
const status = ref('success') // 可改为 'error' 或其他值测试
const list = ref(['苹果', '香蕉', '橘子'])
const imgUrl = ref('https://via.placeholder.com/100')
const imgAlt = ref('示例图片')
const inputText = ref('')
const onceText = ref('这是只渲染一次的内容')
const memoCondition = ref(true)
</script>
<style scoped>
[v-cloak] {
display: none;
}
</style>
BaseCard 组件
<template>
<div class="card">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
<script setup>
</script>
<style scoped>
.card {
border: 1px solid #ddd;
padding: 10px;
margin-top: 10px;
border-radius: 8px;
}
</style>
| 指令 | 作用说明 |
|---|---|
v-text |
替换元素的文本内容,类似 textContent。 |
v-html |
渲染 HTML 字符串,注意 XSS 安全风险。 |
v-show |
控制元素显示隐藏,实际操作的是 display 样式。 |
v-if |
条件渲染,元素是否存在于 DOM 中。 |
v-else-if |
条件分支,配合 v-if 使用。 |
v-else |
条件分支兜底方案。 |
v-for |
列表循环渲染,支持数组、对象、数字。 |
v-on 或 @ |
绑定事件监听,常用于按钮、输入框交互。 |
v-bind 或 : |
动态绑定属性或 prop,控制值。 |
v-model |
双向数据绑定,常用于表单控件。 |
v-slot |
具名插槽,父组件向子组件传递结构化内容。 |
v-pre |
跳过该元素和子节点的 Vue 编译,输出原始模板内容。 |
v-once |
只渲染一次,数据变化不再更新该部分,适合静态结构。 |
v-memo |
性能优化,绑定条件不变时不重新渲染(Vue3.2+ 新特性)。 |
v-cloak |
页面加载期间防止模板闪烁,需配合 CSS [v-cloak]{ display: none; }。 |
区别
-
v-show与v-if区别:特性 v-show v-if 操作原理 控制 display样式控制 DOM 节点是否存在 性能消耗 初次渲染开销小,切换快 每次切换都会销毁与重建 DOM 适用场景 频繁切换 条件不频繁变化的结构 -
v-html警告:
渲染 HTML 字符串时,若数据不可信,存在 XSS 攻击风险,必须严格过滤或避免。
内置组件
1. 过渡动画
<template>
<button @click="show = !show">切换</button>
<Transition name="fade">
<p v-if="show">这是带淡入淡出效果的内容</p>
</Transition>
</template>
<script setup>
import { ref } from 'vue'
const show = ref(true)
</script>
<style scoped>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
</style>
2. 列表过渡
<template>
<button @click="add">添加</button>
<TransitionGroup name="list" tag="ul">
<li v-for="item in items" :key="item">{{ item }}</li>
</TransitionGroup>
</template>
<script setup>
import { ref } from 'vue'
const items = ref(['苹果', '香蕉', '橘子'])
const add = () => {
items.value.push('新增' + Math.floor(Math.random() * 100))
}
</script>
<style scoped>
.list-enter-active, .list-leave-active {
transition: all 0.5s;
}
.list-enter-from {
opacity: 0;
transform: translateY(-20px);
}
.list-leave-to {
opacity: 0;
transform: translateY(20px);
}
</style>
3. 缓存组件状态
<template>
<button @click="tab = 'A'">组件 A</button>
<button @click="tab = 'B'">组件 B</button>
<KeepAlive>
<component :is="tab === 'A' ? CompA : CompB" />
</KeepAlive>
</template>
<script setup>
import { ref } from 'vue'
import CompA from './CompA.vue'
import CompB from './CompB.vue'
const tab = ref('A')
</script>
CompA.vue、CompB.vue 随便写,切换时组件不会被销毁,状态会被保留。
4. 传送 DOM 到其他位置
<template>
<button @click="show = !show">打开弹窗</button>
<Teleport to="body">
<div v-if="show" class="modal">
这是传送到 body 的弹窗
<button @click="show = false">关闭</button>
</div>
</Teleport>
</template>
<script setup>
import { ref } from 'vue'
const show = ref(false)
</script>
<style scoped>
.modal {
position: fixed;
top: 30%;
left: 40%;
background: #fff;
padding: 20px;
border: 1px solid #ddd;
box-shadow: 0 0 10px rgba(0,0,0,0.3);
}
</style>
5. 异步组件占位
<template>
<Suspense>
<template #default>
<AsyncComp />
</template>
<template #fallback>
<p>加载中...</p>
</template>
</Suspense>
</template>
<script setup>
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() =>
new Promise(resolve => {
setTimeout(() => {
resolve(import('./HelloWorld.vue'))
}, 2000)
})
)
</script>
| 组件 | 作用描述 |
|---|---|
<Transition> |
单个元素或组件的进入、离开过渡动画。 |
<TransitionGroup> |
列表元素的批量进入、离开动画,支持同时多个元素。 |
<KeepAlive> |
缓存组件状态,切换时不销毁,常用于标签页、路由缓存。 |
<Teleport> |
将子元素传送到 DOM 的其他位置,常用于弹窗、全局挂载。 |
<Suspense> |
处理异步组件加载,提供加载中的占位符。 |
特殊元素
1. 动态组件
<template>
<button @click="current = 'CompA'">切换到组件 A</button>
<button @click="current = 'CompB'">切换到组件 B</button>
<component :is="current" />
</template>
<script setup>
import { ref } from 'vue'
import CompA from './CompA.vue'
import CompB from './CompB.vue'
const current = ref('CompA')
</script>
2. 插槽传递
//父组件
<template>
<BaseCard>
<template #header>
<h3>我是头部内容</h3>
</template>
<template #default>
<p>这是默认插槽内容</p>
</template>
<template #footer>
<p>我是底部内容</p>
</template>
</BaseCard>
</template>
<script setup>
import BaseCard from './BaseCard.vue'
</script>
//子组件 BaseCard.vue
<template>
<div class="card">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
3. template结构辅助
<template>
<ul>
<template v-for="(item, index) in list" :key="index">
<li>{{ item }}</li>
<li class="desc">描述:{{ item }}的附加信息</li>
</template>
</ul>
</template>
<script setup>
import { ref } from 'vue'
const list = ref(['苹果', '香蕉', '橘子'])
</script>

特殊 Attributes
1. key
key 保证每个元素的唯一标识,Vue 能高效复用 DOM 节点,避免重复渲染。
<template>
<button @click="shuffle">打乱列表</button>
<ul>
<li v-for="item in list" :key="item.id">{{ item.name }}</li>
</ul>
</template>
<script setup>
import { ref } from 'vue'
const list = ref([
{ id: 1, name: '苹果' },
{ id: 2, name: '香蕉' },
{ id: 3, name: '橘子' }
])
const shuffle = () => {
list.value.sort(() => Math.random() - 0.5)
}
</script>
2. ref
•ref 用于获取真实 DOM 节点或子组件实例。
•.value 访问 DOM 对象,操作原生方法。
<template>
//Vue 会自动把这个 input 的真实 DOM 节点,赋值给 inputRef.value。
<input ref="inputRef" placeholder="点击按钮自动聚焦" />
<button @click="focusInput">聚焦输入框</button>
</template>
<script setup>
import { ref } from 'vue'
// 定义容器,初始值是 null
const inputRef = ref(null)
const focusInput = () => {
inputRef.value.focus() //通过 .value 访问真实 DOM,调用 focus 方法
}
</script>
3. is
动态指定渲染的组件或元素
<template>
<button @click="currentTag = 'h1'">切换为 h1</button>
<button @click="currentTag = 'p'">切换为段落</button>
<button @click="currentTag = 'MyComp'">切换为自定义组件</button>
//currentTag的值是h1,所以这里会用h1渲染
<component :is="currentTag">
这里是动态渲染的内容
</component>
</template>
<script setup>
import { ref } from 'vue'
import MyComp from './MyComp.vue'
//定义currentTag的值,可以是h1、可以是p也可以是子组件
const currentTag = ref('h1')
</script>

如果这篇文章对你有用,可以关注本人微信公众号获取更多ヽ(^ω^)ノ ~


浙公网安备 33010602011771号