Skip to content

Vue 3 核心概念

一、Vue 是什么

Vue 是一个渐进式前端框架。核心思想一句话:数据驱动视图——你只管改数据,Vue 自动更新页面。

js
const app = Vue.createApp({
  data() { return { count: 0 } }
})

Vue 3 最大的变化是引入了组合式 API(Composition API),把相关逻辑聚合在一起,替代旧版"选项式 API"分散的写法。本教程全部采用组合式 API + <script setup>

二、响应式:ref 与 reactive

ref(推荐,处理基本类型和对象)

vue
<script setup lang="ts">
import { ref } from 'vue'

const count = ref(0)
const product = ref({ name: '手机', price: 3999 })

function add() {
  count.value++        // 修改 ref 必须加 .value(模板中自动解包)
  product.value.price = 2999
}
</script>

<template>
  <p>当前数量:{{ count }}</p>
  <p>{{ product.name }} ¥{{ product.price }}</p>
  <button @click="add">+1</button>
</template>

reactive(只适用于对象/数组)

ts
import { reactive } from 'vue'
const state = reactive({ count: 0, list: [] as string[] })
state.count++          // 不用 .value

经验法则:能用 ref 用 ref。reactive 在解构/展开时会丢失响应性,容易踩坑。

三、模板语法与指令

指令作用例子
双花括号文本插值把商品价格渲染到页面(见下方示例)
v-if / v-else条件渲染<p v-if="stock > 0">有货</p>
v-for列表渲染<li v-for="p in products" :key="p.id">
v-model表单双向绑定<input v-model="keyword" />
:属性动态绑定属性:src="product.image"
@click事件绑定<button @click="addCart(product)">

商品列表卡片,一行 v-for 全搞定:

vue
<div class="product-grid">
  <div v-for="p in products" :key="p.id" class="card">
    <img :src="p.image" :alt="p.name" />
    <h3>{{ p.name }}</h3>
    <p class="price">¥{{ p.price }}</p>
    <button @click="addToCart(p)">加入购物车</button>
  </div>
</div>

四、计算属性与侦听器

ts
import { computed, watch } from 'vue'

// 计算属性:依赖变化才重算(有缓存)
const totalPrice = computed(() =>
  cartItems.value.reduce((sum, item) => sum + item.price * item.count, 0)
)

// 侦听器:数据变化后做副作用
watch(keyword, (newVal) => {
  console.log('搜索词变了:', newVal)
})

五、组件通信

组件是 Vue 的基本单元。父子组件通过 props(父传子)和 emit(子传父)通信:

vue
<!-- 子组件 ProductCard.vue -->
<script setup lang="ts">
const props = defineProps<{ product: Product }>()
const emit = defineEmits<{ (e: 'add', id: number): void }>()
</script>

<template>
  <div class="card">
    <h3>{{ props.product.name }}</h3>
    <button @click="emit('add', props.product.id)">加购</button>
  </div>
</template>
vue
<!-- 父组件 -->
<script setup lang="ts">
import ProductCard from './ProductCard.vue'
const products = ref<Product[]>([])
</script>

<template>
  <ProductCard v-for="p in products" :key="p.id" :product="p"
               @add="handleAdd" />
</template>

六、生命周期

组件从创建到销毁的钩子,最常用两个:

ts
import { onMounted, onUnmounted } from 'vue'

onMounted(() => {
  // 组件挂载后:发请求、初始化
  fetchProducts()
})
钩子时机
onMounted组件挂载后(发请求的最佳位置)
onBeforeUnmount销毁前(清理定时器/事件)

七、完整小例子:商品列表页

vue
<script setup lang="ts">
import { ref, onMounted } from 'vue'

interface Product { id: number; name: string; price: number; stock: number }

const products = ref<Product[]>([])
const loading = ref(false)

async function fetchProducts() {
  loading.value = true
  try {
    const res = await fetch('/api/product/list')
    const data = await res.json()
    products.value = data.data.records
  } finally {
    loading.value = false
  }
}

onMounted(fetchProducts)
</script>

<template>
  <div v-if="loading">加载中...</div>
  <div class="grid">
    <div v-for="p in products" :key="p.id">{{ p.name }} ¥{{ p.price }}</div>
  </div>
</template>

本章小结

记住四个关键词:ref(响应数据)、v-for(列表)、v-model(表单)、onMounted(发请求)。这四个占了商城前端八成代码。

基于 MIT 协议发布,可自由学习与修改