Vue.js 从入门到实战,这些高频问题帮你少踩坑
Vue.js 是什么,适合哪些场景?
Vue 是一套用于构建用户界面的渐进式 JavaScript 框架。“渐进式”意味着它能按需集成:简单页面用 CDN 引入写几个组件就能跑;复杂项目用 CLI/Vite 搭工程化架构,再结合路由、状态管理形成完整生态。
和 React、Angular 比,Vue 更轻量化,API 友好易上手;React 侧重函数式编程和生态灵活性,Angular 偏向企业级重型框架。
Vue 适合的场景特别广:中小型前端项目快速迭代(比如后台管理系统、官网);需要强交互的页面(电商购物车、表单验证);甚至能和原生 App 结合做 Hybrid 开发(借助 Weex 等方案),要是你想快速出效果,又不想被框架过度约束,Vue 是稳选。
怎么快速搭建第一个 Vue 项目?
想跑通第一个 Vue demo,有三种常见方式,难度从低到高:
CDN 快速体验
不用装任何工具,新建 HTML 文件,引入 CDN 链接就能写代码:
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<div id="app">{{ message }}</div>
<script>
const { createApp } = Vue
createApp({
data() { return { message: 'Hello Vue!' } }
}).mount('#app')
</script>
保存后用浏览器打开,页面会渲染出 Hello Vue!,适合体验基础语法。
Vue CLI 构建工程化项目
如果电脑装了 Node.js(建议 v14+),打开终端执行:
npm install -g @vue/cli vue create my-vue-project
跟着命令行提示选预设(比如默认 Vue 3),等依赖装完后,进入项目目录 cd my-vue-project,再跑 npm run serve,浏览器访问 http://localhost:8080 就能看到默认项目模板,这种方式适合需要 Webpack 配置、插件生态的中大型项目。
Vite 极速启动(推荐 Vue 3 项目)
Vite 是 Vue 作者尤雨溪开发的前端工具,启动和热更新比 CLI 快很多,终端执行:
npm create vite@latest my-vite-project -- --template vue cd my-vite-project npm install npm run dev
访问 http://localhost:5173 就能看到项目,Vite 更适合追求开发效率、想用 Vue 3 最新特性的项目,现在很多新项目都优先选它。
响应式数据原理是啥,日常开发怎么用?
Vue 能自动更新页面,核心靠响应式系统——数据变了,页面自动跟着变。
原理层面(Vue 2 vs Vue 3)
- Vue 2 用
Object.defineProperty拦截对象属性的读取和修改(getter/setter),但对数组下标、对象新增属性监测不友好,得用$set这类 API 手动触发更新。 - Vue 3 换成
Proxy,能直接监听整个对象,数组、对象新增属性都能自动响应,还支持 Map、Set 这些复杂数据结构,性能和灵活性都更强。
日常开发怎么用?
写组件时,data 里返回的对象、ref/reactive 包裹的变量都是响应式的,举个例子:
<script setup>
import { ref, computed } from 'vue'
const count = ref(0) // ref 让基本类型变响应式
const double = computed(() => count.value * 2) // 计算属性自动依赖追踪
function increment() {
count.value++ // 修改响应式数据,页面自动更新
}
</script>
<template>
<button @click="increment">{{ count }} → {{ double }}</button>
</template>
watch 能监听数据变化做异步操作(比如接口请求);watchEffect 会自动收集依赖,适合处理副作用,要注意:Vue 2 里直接修改数组下标(如 arr[0] = 1)不触发更新,Vue 3 用 Proxy 就没这问题,所以新项目优先用 Vue 3 更省心。
组件化开发要注意哪些关键点?
组件化是 Vue 开发的核心——把页面拆成小组件,维护起来更轻松,这几个点要重点关注:
组件的定义与复用
用单文件组件(.vue 文件),一个组件包含 <template>(结构)、<script>(逻辑)、<style>(样式),比如写个 <Button> 组件,多处复用按钮样式和逻辑,减少重复代码。
Props 与 Emits:父子通信
父组件给子组件传数据用 props,子组件触发父组件方法用 emits,示例:
<!-- 子组件 Button.vue -->
<script setup>
const props = defineProps(['label'])
const emit = defineEmits(['click'])
</script>
<template><button @click="emit('click')">{{ label }}</button></template>
<!-- 父组件 -->
<script setup>
function handleClick() { console.log('按钮被点了') }
</script>
<template><Button label="提交" @click="handleClick" /></template>
Props 要注意类型验证(defineProps({ label: String })),避免传错数据类型。
插槽(Slot):内容分发
想让组件更灵活(比如弹窗的标题、内容由父组件决定),用插槽,分默认插槽、具名插槽、作用域插槽,示例具名插槽:
<!-- 子组件 Modal.vue -->
<template>
<div class="modal">
<header><slot name="title">默认标题</slot></header>
<main><slot>默认内容</slot></main>
</div>
</template>
<!-- 父组件使用 -->
<template>
<Modal>
<template #title><h1>自定义标题</h1></template>
<p>这是自定义内容</p>
</Modal>
</template>
跨组件通信(非父子)
兄弟组件、隔多层的组件通信,可选方案:
- Provide / Inject:祖先组件用
provide提供数据,后代组件用inject接收,适合深层嵌套场景。 - 事件总线(Event Bus):Vue 2 常用,Vue 3 可自己实现(比如用
mitt库),但项目大了容易乱,不如用状态管理。 - Pinia / Vuex:全局状态管理(后面单独讲)。
Vue Router 怎么上手,路由守卫有啥用?
单页应用(SPA)要实现页面跳转,得用路由工具 Vue Router。
基础配置(以 Vue 3 + Vue Router 4 为例)
先装依赖 npm install vue-router,然后新建 router/index.js:
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
const routes = [
{ path: '/', name: 'Home', component: Home },
{ path: '/about', name: 'About', component: About },
{
path: '/user/:id',
name: 'User',
component: () => import('../views/User.vue') // 动态路由 + 懒加载
}
]
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-view> 显示匹配的组件。
路由守卫(导航守卫)
跳转前、后做权限判断、加载动画、埋点等,常用的有:
- 全局守卫:
router.beforeEach((to, from, next) => { ... }),每次路由跳转前触发,比如判断用户是否登录,没登录跳登录页:router.beforeEach((to, from) => { if (to.meta.requiresAuth && !isLogin()) { return { name: 'Login' } // 没登录跳登录页 } }) - 组件内守卫:
onBeforeRouteEnter、onBeforeRouteUpdate、onBeforeRouteLeave(Vue 3 组合式 API),在组件里写更内聚。 - 独享守卫:在路由配置里加
beforeEnter,只对当前路由生效。
Vuex/Pinia 状态管理该选哪个,怎么用?
当组件间共享数据(比如用户信息、购物车),用状态管理库更高效。
Vuex vs Pinia:怎么选?
- Vuex 是 Vue 官方传统状态管理,分
state、mutations(同步)、actions(异步)、getters,适合 Vue 2 项目或大型团队严格流程,但写法繁琐,TS 支持一般。 - Pinia 是 Vue 官方推荐的新一代状态管理,API 更简洁,天生支持 TS,去掉了
mutations,只有state、getters、actions,体积更小,Vue 3 项目优先选它。
Pinia 快速上手
装依赖 npm install pinia,在 main.js 注册:
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
新建 stores/counter.js:
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
getters: {
double: (state) => state.count * 2
},
actions: {
increment() { this.count++ }
}
})
组件里使用:
<script setup>
import { useCounterStore } from '../stores/counter'
const store = useCounterStore()
</script>
<template>{{ store.count }} → {{ store.double }} <button @click="store.increment">+</button></template>
异步操作直接在 actions 里写 async 函数(比如请求接口更新 state),比 Vuex 简洁太多。
Vue 3 新特性(Composition API)怎么学?
Vue 3 推出的 Composition API(组合式 API),和之前的 Options API(选项式)并行,解决了大型组件逻辑分散、复用难的问题。
核心语法:setup 与响应式 API
用 <script setup> 语法糖(推荐),不用写 export default,更简洁,响应式 API 包括:
ref:处理基本类型(string/number/boolean),访问要.value,模板里不用。reactive:处理对象/数组,返回 Proxy 代理对象,深度响应式。computed、watch、watchEffect:功能和之前一致,用法更灵活。
示例:
<script setup>
import { ref, reactive, computed, watch } from 'vue'
// 基本类型响应式
const count = ref(0)
// 对象响应式
const user = reactive({ name: '小明', age: 18 })
// 计算属性
const isAdult = computed(() => user.age >= 18)
// 监听
watch(count, (newVal) => { console.log('count 变了:', newVal) })
watchEffect(() => { console.log('user 变化时触发:', user.name) })
function increment() {
count.value++
user.age++
}
</script>
<template>{{ count }} | {{ user.name }} {{ isAdult ? '成年' : '未成年' }}</template>
生命周期钩子
组合式 API 里的钩子要导入,onMounted、onUpdated,和 Options API 的生命周期对应:
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
console.log('组件挂载完成,请求接口')
})
</script>
自定义 Hook:逻辑复用
把重复逻辑抽成自定义 Hook,比如封装接口请求:
// hooks/useFetch.js
import { ref, onMounted } from 'vue'
export function useFetch(url) {
const data = ref(null)
const error = ref(null)
onMounted(async () => {
try {
const res = await fetch(url)
data.value = await res.json()
} catch (e) {
error.value = e
}
})
return { data, error }
}
// 组件里用
<script setup>
import { useFetch } from '../hooks/useFetch'
const { data, error } = useFetch('https://api.example.com/data')
</script>
这种方式比 Options API 的 mixin 更清晰,不会有命名冲突,逻辑溯源更简单。
项目开发中遇到性能问题怎么优化?
Vue 项目越做越大,难免遇到加载慢、渲染卡,这些优化技巧能救命:
路由懒加载
不用把所有组件打包到一个 JS 文件,用动态 import 拆分代码:
{ path: '/about', component: () => import('../views/About.vue') }
访问 /about 时才加载对应的 JS,首屏加载更快。
Keep-Alive 缓存组件
列表页→详情页→返回列表,用 <keep-alive> 缓存列表组件实例,避免重复请求和渲染:
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
虚拟列表(长列表优化)
渲染 thousands 条数据时,DOM 太多会卡死,用虚拟列表只渲染可视区域的 DOM,可以用 vue-virtual-scroller 库,原理是计算滚动位置,动态替换显示的列表项。
减少不必要的响应式
有些数据不需要响应式(比如纯展示的静态数据),用 shallowRef(浅响应式,只监听 .value 的变化)、markRaw(标记对象永远不是响应式):
import { shallowRef, markRaw } from 'vue'
const staticData = markRaw({ list: [1,2,3] }) // 永远不响应式
const shallowData = shallowRef({ count: 0 }) // 只有.count 变化才触发更新
打包优化
- 用 Vite 的话,默认 Tree Shaking 很高效,去掉没用到的代码。
- 第三方库用 CDN 加速(比如把 axios、element-plus 放到
index.html的 CDN 链接,vite.config.js里配置external)。 - 压缩图片、开启 gzip(服务器配置或 Vite 插件)。
UI 组件库(Element Plus、Ant Design Vue)怎么选和用?
做后台管理系统、表单页面,直接用 UI 组件库能省大量时间,主流选择:
Element Plus
原 Element UI 的 Vue 3 版本,组件丰富(表格、表单、弹窗等),文档友好,中文社区活跃,适合中后台项目。按需引入能减小打包体积:
// vite.config.js 配置按需引入
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
plugins: [
AutoImport({ resolvers: [ElementPlusResolver()] }),
Components({ resolvers: [ElementPlusResolver()] })
]
})
然后直接用组件:<el-button>按钮</el-button>,不用手动 import。
Ant Design Vue
阿里系的 UI 库,设计风格更现代,组件功能强大(ProTable 带查询表单),TS 支持好,适合对设计和扩展性要求高的项目,用法类似,也支持按需引入。
选择建议
团队熟悉 Element 就选 Element Plus;喜欢 Ant Design 风格或需要更复杂的企业级组件(比如流程设计、可视化)选 Ant Design Vue,小项目也可以用 Naive UI(轻量、TS 优先)、Vuetify(Material Design 风格)等。
测试和部署 Vue 项目要注意什么?
项目开发完,得测试稳了再上线,部署也有讲究:
测试:单元测试 + E2E 测试
-
单元测试:测组件、函数逻辑,用 Vue Test Utils + Jest/Vitest,比如测 Button 组件的点击事件:
import { mount } from '@vue/test-utils' import Button from '../Button.vue' test('Button click emits event', () => { const wrapper = mount(Button,
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网


