Vue 知识速查表
本页面汇总了 Vue 3 开发中最常用的语法和知识点,方便快速查阅。
基础概念
创建应用
import { createApp } from 'vue'
const app = createApp({
data() {
return { message: 'Hello Vue!' }
}
})
app.mount('#app')
单文件组件 (.vue)
<script setup>
import { ref, computed } from 'vue'
// 逻辑代码
const count = ref(0)
</script>
<template>
<!-- 模板 -->
<p>{{ count }}</p>
</template>
<style scoped>
/* 样式 */
</style>
响应式 API
ref 和 reactive
import { ref, reactive } from 'vue'
// ref - 基本类型
const count = ref(0)
count.value++
// reactive - 对象
const state = reactive({
count: 0,
name: '张三'
})
state.count++
computed
import { computed } from 'vue'
const count = ref(1)
const doubled = computed(() => count.value * 2)
// 可写计算属性
const fullName = computed({
get: () => firstName.value + lastName.value,
set: (value) => { /* ... */ }
})
watch
import { watch } from 'vue'
watch(count, (newValue, oldValue) => {
console.log(`${oldValue} -> ${newValue}`)
})
// 深度监听
watch(state, (newValue) => { /* ... */ }, { deep: true })
// 立即执行
watch(count, (newValue) => { /* ... */ }, { immediate: true })
// 监听多个
watch([count1, count2], ([new1, new2]) => { /* ... */ })
watchEffect
import { watchEffect } from 'vue'
// 自动追踪依赖
watchEffect(() => {
console.log(count.value)
console.log(name.value)
})
模板语法
插值
<!-- 文本 -->
{{ message }}
<!-- 原始 HTML -->
<span v-html="rawHtml"></span>
<!-- JavaScript 表达式 -->
{{ message.split('').reverse().join('') }}
指令
<!-- 绑定属性 -->
<img :src="imageSrc" />
<div :class="{ active: isActive }"></div>
<!-- 绑定事件 -->
<button @click="handleClick">点击</button>
<form @submit.prevent="handleSubmit"></form>
<!-- 双向绑定 -->
<input v-model="message" />
<input v-model.number="age" />
<input v-model.trim="username" />
<!-- 条件渲染 -->
<div v-if="show">显示</div>
<div v-else>隐藏</div>
<div v-show="show">v-show</div>
<!-- 列表渲染 -->
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
<li v-for="(item, index) in items">{{ index }}. {{ item }}</li>
<!-- 绑定样式 -->
<div :style="{ color: textColor, fontSize: fontSize + 'px' }"></div>
事件修饰符
@click.stop="handleClick" <!-- 阻止冒泡 -->
@click.prevent="handleSubmit" <!-- 阻止默认行为 -->
@click.self="handleClick" <!-- 仅自身触发 -->
@click.once="handleClick" <!-- 只触发一次 -->
@click.ctrl="handleClick" <!-- Ctrl 键 -->
组件
Props
<!-- 父组件 -->
<ChildComponent
:title="title"
:count="count"
required-prop="必填"
:optional-prop="optional"
/>
<!-- 子组件 -->
<script setup>
defineProps({
title: String,
count: {
type: Number,
required: true,
default: 0
},
items: {
type: Array,
default: () => []
}
})
</script>
Emits
<!-- 子组件 -->
<script setup>
const emit = defineEmits(['update', 'delete'])
emit('update', newValue)
emit('delete', id)
</script>
<!-- 父组件 -->
<ChildComponent
@update="handleUpdate"
@delete="handleDelete"
/>
v-model
<!-- 组件支持 v-model -->
<script setup>
defineProps({ modelValue: String })
defineEmits(['update:modelValue'])
</script>
<!-- 使用 -->
<Input v-model="text" />
<!-- 多个 v-model -->
<Input v-model:name="name" v-model:email="email" />
插槽
<!-- 父组件 -->
<Layout>
<template #header>页眉</template>
<template #default>主内容</template>
<template #footer>页脚</template>
</Layout>
<!-- 子组件 -->
<slot name="header">默认内容</slot>
<slot>默认插槽</slot>
<!-- 作用域插槽 -->
<slot :item="item" :index="index" />
生命周期
组合式 API 钩子
| 选项式 API | 组合式 API |
|---|---|
| beforeCreate | 不需要 |
| created | 不需要 |
| beforeMount | onBeforeMount |
| mounted | onMounted |
| beforeUpdate | onBeforeUpdate |
| updated | onUpdated |
| beforeUnmount | onBeforeUnmount |
| unmounted | onUnmounted |
import { onMounted, onUnmounted } from 'vue'
onMounted(() => {
console.log('mounted')
})
onUnmounted(() => {
console.log('unmounted')
})
路由
Vue Router 4
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from './views/Home.vue'
import About from './views/About.vue'
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About },
{ path: '/user/:id', component: User }
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
createApp(App).use(router).mount('#app')
<!-- 路由视图 -->
<router-link to="/">首页</router-link>
<router-link to="/about">关于</router-link>
<router-view />
<!-- 编程式导航 -->
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
router.push('/home')
router.back()
</script>
状态管理 (Pinia)
// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
getters: {
doubled: (state) => state.count * 2
},
actions: {
increment() {
this.count++
}
}
})
// 使用
import { useCounterStore } from './stores/counter'
const store = useCounterStore()
store.increment()
console.log(store.count)
console.log(store.doubled)
常用工具函数
toRef / toRefs
import { reactive, toRef, toRefs } from 'vue'
const state = reactive({ count: 0, name: '张三' })
// toRef - 保持响应式连接
const count = toRef(state, 'count')
// toRefs - 转换为普通对象
const { count, name } = toRefs(state)
isRef
import { isRef } from 'vue'
isRef(count) // true / false
常用 CSS
scoped
<style scoped>
/* 只作用于当前组件 */
.button { /* ... */ }
</style>
CSS Modules
<style module>
/* 访问 $style.button */
</style>
深度选择器
<style scoped>
/* 穿透子组件 */
:deep(.child-class) { /* ... */ }
/* 穿透伪类 */
:hover { /* ... */ }
</style>
常见问题
访问 DOM
const el = ref(null)
onMounted(() => {
console.log(el.value)
})
</script>
<template>
<div ref="el"></div>
</template>
组件暴露方法
<!-- Child.vue -->
<script setup>
defineExpose({
method: () => console.log('exposed')
})
</script>
<!-- Parent.vue -->
<Child ref="child" />
<script setup>
child.value?.method()
</script>
异步组件
import { defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() =>
import('./HeavyComponent.vue')
)
快捷命令
# 创建项目
npm create vue@latest
# 安装依赖
npm install
# 开发服务器
npm run dev
# 构建生产版本
npm run build
# 预览构建结果
npm run preview
# 代码检查
npm run lint
参考资源
- Vue 3 官方文档
- Vue Router
- Pinia
- VueUse - Vue 组合式工具集