模板语法
文本与表达式
{{ message }} {{ count + 1 }} {{ ok ? 'Yes' : 'No' }}
指令
{{ expr }}文本插值
v-bind:attr / :attr将属性绑定到表达式
v-on:event / @event绑定事件监听器
v-model双向绑定(表单)
v-if / v-else-if / v-else条件渲染
v-show切换 display CSS(保留在 DOM 中)
v-for列表渲染
v-slot / #name具名插槽内容
属性绑定
响应式
ref(原始值)
import { ref } from 'vue' const count = ref(0) console.log(count.value) // 0 count.value++ // reactive update
reactive(对象)
import { reactive } from 'vue' const state = reactive({ count: 0, name: 'Vue' }) state.count++ // no .value needed
ref vs reactive
ref()支持任意类型;在 script 中通过 .value 访问
reactive()仅支持对象/数组;直接访问属性
Template两者在模板中均自动解包(无需 .value
Destructurereactive 解构后失去响应性;用 toRefs()
计算属性与侦听器
计算属性
import { ref, computed } from 'vue' const items = ref([1, 2, 3, 4, 5]) const evenItems = computed(() => items.value.filter(n => n % 2 === 0) )

计算属性会缓存,只在依赖变化时重新计算

侦听器
import { ref, watch, watchEffect } from 'vue' const query = ref('') // Watch specific source watch(query, (newVal, oldVal) => { console.log(`Changed: ${oldVal} → ${newVal}`) }) // Auto-track dependencies watchEffect(() => { console.log(`Query is: ${query.value}`) })
watch 选项
immediate: true创建时立即执行回调
deep: true深度侦听嵌套对象
flush: 'post'在 DOM 更新后执行
once: true只触发一次后停止
组件
单文件组件(SFC)
注册组件
SFC 块
<script setup>Composition API(推荐写法)
<template>HTML 模板
<style scoped>组件作用域 CSS
<style module>CSS Modules($style 对象)
Props 与事件
定义 Props
触发事件
父组件用法
组件上的 v-model
插槽
默认插槽

Custom content here

具名插槽

Main content

作用域插槽
Composition API
组合式函数
// useMouse.js import { ref, onMounted, onUnmounted } from 'vue' export function useMouse() { const x = ref(0) const y = ref(0) function update(e) { x.value = e.pageX y.value = e.pageY } onMounted(() => window.addEventListener('mousemove', update)) onUnmounted(() => window.removeEventListener('mousemove', update)) return { x, y } }
使用组合式函数
provide / inject
// Parent import { provide, ref } from 'vue' const theme = ref('dark') provide('theme', theme) // Descendant (any depth) import { inject } from 'vue' const theme = inject('theme', 'light') // default
路由(Vue Router)
路由定义
import { createRouter, createWebHistory } from 'vue-router' const router = createRouter({ history: createWebHistory(), routes: [ { path: '/', component: Home }, { path: '/about', component: About }, { path: '/user/:id', component: User }, ] })
模板导航
Home User 1
编程式导航
import { useRouter, useRoute } from 'vue-router' const router = useRouter() const route = useRoute() router.push('/about') router.push({ name: 'user', params: { id: 1 } }) console.log(route.params.id)
路由特性
/user/:id动态路由段(route.params.id
name: 'user'命名路由,用于编程式导航
children: [...]嵌套路由
beforeEnter单路由导航守卫
meta: { auth: true }守卫使用的自定义元数据
redirect: '/new-path'路由重定向
生命周期钩子
钩子执行顺序
onBeforeMount初始 DOM 渲染前
onMountedDOM 就绪(获取数据、绑定事件)
onBeforeUpdate响应式状态触发 DOM 更新前
onUpdatedDOM 重新渲染后
onBeforeUnmount组件销毁前
onUnmounted清理(移除事件监听、定时器)
用法
列表与条件
v-for
  • {{ item.name }}
  • {{ index }}: {{ item.name }}
  • {{ key }}: {{ val }}

    v-for 必须使用 :key 以确保高效的 DOM 更新

    v-if vs v-show
    v-if条件渲染(从 DOM 中添加/移除)
    v-else-ifelse-if 链
    v-else默认分支
    v-show切换 display: none(保留在 DOM 中)

    频繁切换用 v-show,少见变化用 v-if

    条件示例
    Loading...
    Error!
    {{ data }}
    表单处理
    v-model 基础
    v-model 修饰符
    v-model.lazychange 事件时同步(而非 input
    v-model.number自动转换为数字类型
    v-model.trim自动去除首尾空白
    事件修饰符
    @click.prevent调用 preventDefault()
    @click.stop调用 stopPropagation()
    @click.once最多触发一次
    @keyup.enter仅在按下 Enter 键时触发
    @submit.prevent阻止表单默认提交行为