Vue 基础理论 & API 使用

Vue 基础理论 & API 使用

本文主要记录 Vue 的基础理论、核心概念与常用 API 使用方法,面向面试和日常开发参考。


原文地址

墨渊书肆/Vue 基础理论 & API 使用


Vue 简介

Vue 是一个渐进式 JavaScript 框架,由尤雨溪于 2014 年创建。Vue 核心库聚焦于视图层,易于学习和集成,同时能够驱动复杂的单页应用程序(SPA)开发。

核心特点

  • 响应式数据绑定 (MVVM 模式)
  • 组件化开发
  • 虚拟 DOM
  • 指令系统
  • 渐进式架构

安装与项目创建

Vite(推荐)

bash 复制代码
# 创建 Vue3 项目
npm create vue@latest

# 或使用 Vite 直接创建
npm create vite@latest my-vue-app -- --template vue

Vue CLI

bash 复制代码
npm install -g @vue/cli
vue create my-project

基础指令

v-model 双向绑定

v-modelVue 中用于表单输入和数据双向绑定的核心指令,本质是 v-bind + v-on语法糖

基本用法

html 复制代码
<input v-model="message">
<p>{{ message }}</p>

修饰符

修饰符 说明
.lazy 在 change 事件时更新,而非 input
.number 自动转换为数值
.trim 去除首尾空白

自定义 v-model(Vue 3.4+):

javascript 复制代码
// 子组件
defineProps(['modelValue'])
defineEmits(['update:modelValue'])

// 父组件
<MyInput v-model:title="title" />

v-if / v-show 条件渲染

特性 v-if v-show
DOM 操作 创建/销毁 display: none
初始渲染 惰性 立即渲染
切换性能
适用场景 很少切换 频繁切换
html 复制代码
<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else>C</div>

v-for 列表渲染

html 复制代码
<li v-for="(item, index) in items" :key="item.id">
  {{ index }} - {{ item.name }}
</li>

注意事项

  • 必须使用 :key 绑定唯一标识
  • 不建议使用数组索引作为 key
  • Vue2 中 v-for 优先级高于 v-if,Vue3 中相反

v-bind / v-on 属性与事件

html 复制代码
<!-- 绑定属性 -->
<img :src="url">

<!-- 绑定多个属性 -->
<img v-bind="attrs">

<!-- 事件监听 -->
<button @click="handleClick">Click</button>

<!-- 事件修饰符 -->
<button @click.stop="handle">阻止冒泡</button>
<button @click.prevent="handle">阻止默认行为</button>

组件选项

data

组件的响应式数据源,必须返回纯对象:

javascript 复制代码
export default {
  data() {
    return {
      count: 0,
      user: { name: 'Vue' }
    }
  }
}

props

父子组件通信的重要方式,支持类型校验默认值

javascript 复制代码
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

javascript 复制代码
const props = defineProps({
  title: String,
  count: { type: Number, default: 0 }
})

computed 计算属性

缓存计算结果,只在依赖变化时重新计算:

javascript 复制代码
export default {
  data() { return { count: 1 } },
  computed: {
    // 只读
    doubled() { return this.count * 2 },
    // 可写
    plusOne: {
      get() { return this.count + 1 },
      set(val) { this.count = val - 1 }
    }
  }
}

methods 方法

处理业务逻辑,每次渲染都会重新创建:

javascript 复制代码
export default {
  methods: {
    handleClick() { /* ... */ }
  }
}

watch 监听器

监听数据变化并执行回调:

javascript 复制代码
export default {
  data() { return { count: 0 } },
  watch: {
    count(newVal, oldVal) {
      console.log(`变化: ${oldVal} → ${newVal}`)
    },
    // 深度监听
    'obj.data': {
      handler() { /* ... */ },
      deep: true
    },
    // 立即执行
    name: {
      handler() { /* ... */ },
      immediate: true
    }
  }
}

Composition API

Vue3 引入的组合式 API,提供了更灵活的逻辑组织方式。

ref / reactive 响应式

javascript 复制代码
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 | 直接属性 | | 重新赋值 | 响应式 | 替换整个对象 |

toRefs / toRef

将 reactive 对象解构为独立的 ref:

javascript 复制代码
import { reactive, toRefs } from 'vue'

const state = reactive({ name: 'Vue', age: 25 })
const { name, age } = toRefs(state)

// 或创建单个 ref
const nameRef = toRef(state, 'name')

computed() 计算属性

javascript 复制代码
import { ref, computed } from 'vue'

const count = ref(0)
const doubled = computed(() => count.value * 2)

watch / watchEffect

javascript 复制代码
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:同步执行

生命周期钩子

javascript 复制代码
import { 
  onMounted, 
  onUpdated, 
  onUnmounted 
} from 'vue'

export default {
  setup() {
    onMounted(() => { console.log('mounted') })
    onUpdated(() => { console.log('updated') })
    onUnmounted(() => { console.log('unmounted') })
  }
}

组件通信

Props / $emit

javascript 复制代码
// 父组件
<Child :count="count" @update="handleUpdate" />

// 子组件
const props = defineProps({ count: Number })
const emit = defineEmits(['update'])
emit('update', props.count + 1)

Provide / Inject

祖先向后代跨级传值

javascript 复制代码
// 祖先组件
provide('key', 'value')

// 后代组件
const value = inject('key')

响应式

javascript 复制代码
// 祖先
const count = ref(0)
provide('count', count)

// 后代 - 修改会影响所有后代
const count = inject('count')

a t t r s / attrs / attrs/listeners

透传属性和事件:

html 复制代码
<!-- 透传所有 -->
<Child v-bind="$attrs" v-on="$listeners" />

Pinia 状态管理

Vue3 推荐的状态管理方案:

javascript 复制代码
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  getters: {
    doubled: (state) => state.count * 2
  },
  actions: {
    increment() { this.count++ }
  }
})

内置组件

Transition

为元素添加过渡动画

html 复制代码
<Transition name="fade">
  <div v-if="show">Content</div>
</Transition>
css 复制代码
.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

缓存组件实例:

html 复制代码
<KeepAlive include="A,B" exclude="C">
  <component :is="current" />
</KeepAlive>

生命周期

  • activated:激活时
  • deactivated:停用时

Teleport

渲染到指定 DOM 位置:

html 复制代码
<Teleport to="#modal-root">
  <div class="modal">Content</div>
</Teleport>

Suspense

处理异步组件(实验性):

html 复制代码
<Suspense>
  <template #default>
    <AsyncComponent />
  </template>
  <template #fallback>
    Loading...
  </template>
</Suspense>

生命周期

Options API

阶段 钩子 说明
初始化 beforeCreate 实例创建前
初始化 created 数据观测完成
挂载 beforeMount 模板编译完成
挂载 mounted DOM 挂载完成
更新 beforeUpdate 数据变化,DOM 未更新
更新 updated DOM 更新完成
销毁 beforeUnmount 实例销毁前
销毁 unmounted 实例已销毁

父子组件执行顺序

挂载:父 created → 子 created → 子 mounted → 父 mounted

更新:父 beforeUpdate → 子 beforeUpdate → 子 updated → 父 updated

销毁:父 beforeUnmount → 子 beforeUnmount → 子 unmounted → 父 unmounted


常用技巧

动态类名

html 复制代码
<div :class="{ active: isActive, 'text-center': isCenter }">
<div :class="[activeClass, errorClass]">

条件类名

html 复制代码
<div :class="[isActive && 'active']">

动态绑定 style

html 复制代码
<div :style="{ color: textColor, fontSize: fontSize + 'px' }">

函数式组件

javascript 复制代码
export default {
  functional: true,
  props: { msg: String },
  render(h, context) {
    return h('div', context.props.msg)
  }
}

异步组件

javascript 复制代码
import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent({
  loader: () => import('./Async.vue'),
  loadingComponent: Loading,
  errorComponent: Error,
  delay: 200,
  timeout: 3000
})

面试常见问题

1. v-model 的原理?

本质是 v-bind:value + @input语法糖,监听 input 事件并更新数据。

2. v-for 中 key 的作用?

帮助 Vue 识别节点身份,实现高效的 DOM 复用。推荐使用数据唯一 ID,避免使用数组索引

3. computed 和 watch 的区别?

  • computed:计算属性,依赖变化自动计算,缓存结果
  • watch:监听器,监听数据变化,执行异步或复杂逻辑

4. Vue2 和 Vue3 的区别?

  • 响应式:Object.defineProperty → Proxy
  • API:Options API → Composition API
  • 多根节点:不支持 → 支持
  • 生命周期:beforeDestroy → beforeUnmount

5. 组件通信方式有哪些?

  • props / $emit:父子
  • provide / inject:祖先-后代
  • a t t r s / attrs / attrs/listeners:透传
  • 事件总线:兄弟/任意
  • Pinia/Vuex:全局状态

6. Vue 的响应式原理?

通过 Proxy/Object.defineProperty 劫持数据访问,在 getter 中收集依赖 ,setter 中触发更新


总结

Vue 以其简洁的 API 和渐进式的设计理念,成为前端开发的主流框架。掌握 Vue 的基础理论、常用 API 以及组件通信方式,是 Vue 开发者的必备技能。Vue3Composition API 提供了更现代化的开发范式,建议在实际项目中优先使用。

相关推荐
Apifox5 分钟前
Apifox 6 月更新|Apifox CLI 全面升级、导入导出优化、OAuth 2.0 支持自动刷新令牌
前端·后端·测试
CodingSpace15 分钟前
TypeScript 装饰器
前端
宸翰18 分钟前
解决 uni-app App 端 vue-i18n 占位符丢失:封装跨端可用的 tf 格式化方法
前端·vue.js·uni-app
systemPro25 分钟前
光储充系统数据流全解析:PV / ESS / GRID 数据怎么流转,线损怎么算
前端
古茗前端团队2 小时前
急招!前端|测试|后端|产品(名额多,速来)
前端·后端·架构
Lsx_3 小时前
不只是 Prompt:用 Superpowers Skill 给 AI 编程装上工程化工作流
前端·ai编程·claude
小碗细面3 小时前
前端 Prompt 工程实战:如何搭建场景化 Prompt 库
前端·ai编程
阿瑞IT3 小时前
2026年 AI Agent 生产化落地全景:四大高频故障根因分析与工程解法
前端
木木剑光3 小时前
我开源了一个 React 组件库,沉淀了多个高频组件和实用 Hooks
前端·javascript·react.js
kyriewen3 小时前
DeepSeek API 高峰时段涨价 2 倍,便宜大碗的时代要结束了?
前端·ai编程·deepseek