极米投影仪
149.20M · 2026-03-22
墨渊书肆/Vue 基础理论 & API 使用
Vue 是一个渐进式 JavaScript 框架,由尤雨溪于 2014 年创建。Vue 核心库聚焦于视图层,易于学习和集成,同时能够驱动复杂的单页应用程序(SPA)开发。
核心特点:
# 创建 Vue3 项目
npm create vue@latest
# 或使用 Vite 直接创建
npm create vite@latest my-vue-app -- --template vue
npm install -g @vue/cli
vue create my-project
v-model 是 Vue 中用于表单输入和数据双向绑定的核心指令,本质是 v-bind + v-on 的语法糖。
基本用法:
<input v-model="message">
<p>{{ message }}</p>
修饰符:
| 修饰符 | 说明 |
|---|---|
.lazy | 在 change 事件时更新,而非 input |
.number | 自动转换为数值 |
.trim | 去除首尾空白 |
自定义 v-model(Vue 3.4+):
// 子组件
defineProps(['modelValue'])
defineEmits(['update:modelValue'])
// 父组件
<MyInput v-model:title="title" />
| 特性 | v-if | v-show |
|---|---|---|
| DOM 操作 | 创建/销毁 | display: none |
| 初始渲染 | 惰性 | 立即渲染 |
| 切换性能 | 低 | 高 |
| 适用场景 | 很少切换 | 频繁切换 |
<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else>C</div>
<li v-for="(item, index) in items" :key="item.id">
{{ index }} - {{ item.name }}
</li>
注意事项:
:key 绑定唯一标识<!-- 绑定属性 -->
<img :src="url">
<!-- 绑定多个属性 -->
<img v-bind="attrs">
<!-- 事件 -->
<button @click="handleClick">Click</button>
<!-- 事件修饰符 -->
<button @click.stop="handle">阻止冒泡</button>
<button @click.prevent="handle">阻止默认行为</button>
组件的响应式数据源,必须返回纯对象:
export default {
data() {
return {
count: 0,
user: { name: 'Vue' }
}
}
}
父子组件通信的重要方式,支持类型校验和默认值:
export default {
props: {
// 基础类型
title: String,
// 多个类型
age: [Number, String],
// 带默认值
size: {
type: String,
default: 'medium'
},
// 必需
id: {
type: Number,
required: true
},
// 自定义校验
score: {
validator: (value) => value >= 0 && value <= 100
}
}
}
Vue3 组合式 API:
const props = defineProps({
title: String,
count: { type: Number, default: 0 }
})
缓存计算结果,只在依赖变化时重新计算:
export default {
data() { return { count: 1 } },
computed: {
// 只读
doubled() { return this.count * 2 },
// 可写
plusOne: {
get() { return this.count + 1 },
set(val) { this.count = val - 1 }
}
}
}
处理业务逻辑,每次渲染都会重新创建:
export default {
methods: {
handleClick() { /* ... */ }
}
}
数据变化并执行回调:
export default {
data() { return { count: 0 } },
watch: {
count(newVal, oldVal) {
console.log(`变化: ${oldVal} → ${newVal}`)
},
// 深度
'obj.data': {
handler() { /* ... */ },
deep: true
},
// 立即执行
name: {
handler() { /* ... */ },
immediate: true
}
}
}
Vue3 引入的组合式 API,提供了更灵活的逻辑组织方式。
import { ref, reactive } from 'vue'
// ref - 原始类型
const count = ref(0)
count.value++
// reactive - 对象
const state = reactive({
user: { name: 'Vue' }
})
state.user.name = 'Vue3'
区别:
| 特性 | ref | reactive | | ----- -| ----- | ---------- | | 适用类型 | 任意类型 | 对象/数组 | | 访问方式 | .value | 直接属性 | | 重新赋值 | 响应式 | 替换整个对象 |
将 reactive 对象解构为独立的 ref:
import { reactive, toRefs } from 'vue'
const state = reactive({ name: 'Vue', age: 25 })
const { name, age } = toRefs(state)
// 或创建单个 ref
const nameRef = toRef(state, 'name')
import { ref, computed } from 'vue'
const count = ref(0)
const doubled = computed(() => count.value * 2)
import { ref, watch, watchEffect } from 'vue'
// watch - 显式
watch(count, (newVal, oldVal) => { /* ... */ })
watch(() => state.name, (newVal) => { /* ... */ })
// watchEffect - 自动收集依赖
watchEffect(() => {
console.log(count.value) // 自动追踪
})
执行时机控制:
watch:默认同步执行watchEffect:默认 pre(在组件更新前)watchPostEffect:在组件更新后执行watchSyncEffect:同步执行import {
onMounted,
onUpdated,
onUnmounted
} from 'vue'
export default {
setup() {
onMounted(() => { console.log('mounted') })
onUpdated(() => { console.log('updated') })
onUnmounted(() => { console.log('unmounted') })
}
}
// 父组件
<Child :count="count" @update="handleUpdate" />
// 子组件
const props = defineProps({ count: Number })
const emit = defineEmits(['update'])
emit('update', props.count + 1)
祖先向后代跨级传值:
// 祖先组件
provide('key', 'value')
// 后代组件
const value = inject('key')
响应式:
// 祖先
const count = ref(0)
provide('count', count)
// 后代 - 修改会影响所有后代
const count = inject('count')
透传属性和事件:
<!-- 透传所有 -->
<Child v-bind="$attrs" v-on="$listeners" />
Vue3 推荐的状态管理方案:
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
getters: {
doubled: (state) => state.count * 2
},
actions: {
increment() { this.count++ }
}
})
为元素添加过渡动画:
<Transition name="fade">
<div v-if="show">Content</div>
</Transition>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
过渡类名:
v-enter-from / v-leave-from:起始状态v-enter-active / v-leave-active:过渡中v-enter-to / v-leave-to:结束状态缓存组件实例:
<KeepAlive include="A,B" exclude="C">
<component :is="current" />
</KeepAlive>
生命周期:
activated:激活时deactivated:停用时渲染到指定 DOM 位置:
<Teleport to="#modal-root">
<div class="modal">Content</div>
</Teleport>
处理异步组件(实验性):
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
Loading...
</template>
</Suspense>
| 阶段 | 钩子 | 说明 |
|---|---|---|
| 初始化 | beforeCreate | 实例创建前 |
| 初始化 | created | 数据观测完成 |
| 挂载 | beforeMount | 模板编译完成 |
| 挂载 | mounted | DOM 挂载完成 |
| 更新 | beforeUpdate | 数据变化,DOM 未更新 |
| 更新 | updated | DOM 更新完成 |
| 销毁 | beforeUnmount | 实例销毁前 |
| 销毁 | unmounted | 实例已销毁 |
挂载:父 created → 子 created → 子 mounted → 父 mounted
更新:父 beforeUpdate → 子 beforeUpdate → 子 updated → 父 updated
销毁:父 beforeUnmount → 子 beforeUnmount → 子 unmounted → 父 unmounted
<div :class="{ active: isActive, 'text-center': isCenter }">
<div :class="[activeClass, errorClass]">
<div :class="[isActive && 'active']">
<div :style="{ color: textColor, fontSize: fontSize + 'px' }">
export default {
functional: true,
props: { msg: String },
render(h, context) {
return h('div', context.props.msg)
}
}
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent({
loader: () => import('./Async.vue'),
loadingComponent: Loading,
errorComponent: Error,
delay: 200,
timeout: 3000
})
本质是 v-bind:value + @input 的语法糖, input 事件并更新数据。
帮助 Vue 识别节点身份,实现高效的 DOM 复用。推荐使用数据唯一 ID,避免使用数组索引。
通过 Proxy/Object.defineProperty 劫持数据访问,在 getter 中收集依赖,setter 中触发更新。
Vue 以其简洁的 API 和渐进式的设计理念,成为前端开发的主流框架。掌握 Vue 的基础理论、常用 API 以及组件通信方式,是 Vue 开发者的必备技能。Vue3 的 Composition API 提供了更现代化的开发范式,建议在实际项目中优先使用。