一、组合式API(Composition API)
1. 基本响应式
import { ref, reactive, computed, watch } from 'vue'
// ref:基本类型
const count = ref(0)
count.value++
// reactive:对象/数组
const state = reactive({ name: 'Vue', list: [] })
// computed:计算属性
const double = computed(() => count.value * 2)
// watch:监听
watch(count, (newVal, oldVal) => { })
watch(() => state.name, (newVal) => { }) // 监听对象属性
2. 生命周期
import { onMounted, onUnmounted, onUpdated } from 'vue'
onMounted(() => { /* DOM已挂载 */ })
3. 获取DOM
const inputRef = ref(null)
// 模板:<input ref="inputRef" />
二、组件通信
1. Props / Emits
// 父传子
const props = defineProps(['title', 'data'])
// 子传父
const emit = defineEmits(['update', 'submit'])
emit('update', payload)
2. v-model 双向绑定
// 子组件
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
// 父组件:<Child v-model="value" />
3. provide / inject(跨层级)
// 父
provide('key', data)
// 子孙
const data = inject('key')
4. 兄弟组件通信(事件总线)
// 使用 mitt
import mitt from 'mitt'
const bus = mitt()
bus.emit('event', data)
bus.on('event', (data) => {})
三、路由(Vue Router)
import { useRouter, useRoute } from 'vue-router'
const router = useRouter()
const route = useRoute()
// 跳转
router.push('/path')
router.push({ path: '/user', query: { id: 1 } })
router.push({ name: 'User', params: { id: 1 } })
// 获取参数
route.params.id
route.query.key
四、状态管理(Pinia)
// store/user.js
export const useUserStore = defineStore('user', {
state: () => ({ name: '', token: '' }),
getters: { isLogin: (state) => !!state.token },
actions: { setUser(data) { this.name = data.name } }
})
// 使用
import { useUserStore } from '@/store/user'
const store = useUserStore()
store.setUser({ name: 'John' })
const { name, token } = store // 解构用 storeToRefs
五、工具函数
1. 异步处理
import { ref } from 'vue'
const loading = ref(false)
const fetchData = async () => {
loading.value = true
try {
const res = await api.getData()
// 处理数据
} finally {
loading.value = false
}
}
2. 防抖/节流
import { debounce, throttle } from 'lodash-es'
// 或手动实现
六、常用模板语法
<template>
<!-- 条件渲染 -->
<div v-if="visible">显示</div>
<div v-else>隐藏</div>
<!-- 列表渲染 -->
<div v-for="(item, index) in list" :key="item.id">
{{ item.name }}
</div>
<!-- 事件绑定 -->
<button @click="handleClick" @keydown.enter="submit">点击</button>
<!-- 动态属性 -->
<img :src="imageUrl" :alt="title" />
<!-- 插槽 -->
<slot name="header" :data="userData"></slot>
</template>
七、自定义指令
// 全局注册
app.directive('focus', {
mounted(el) { el.focus() }
})
// 使用:<input v-focus />
八、工具组合
useAsync(异步状态管理)
export function useAsync(fn) {
const data = ref(null), loading = ref(false), error = ref(null)
const execute = async (...args) => {
loading.value = true; error.value = null
try { data.value = await fn(...args) }
catch (e) { error.value = e }
finally { loading.value = false }
}
return { data, loading, error, execute }
}