Vue入门
Vue入门
1. Vue 是什么?为什么后端也要学?
- Vue 是一个渐进式前端框架,专门用来构建用户界面(View层)。
- 核心特点:声明式渲染
- 组件化
- 响应式系统。
- 组件化
- 和你熟悉的后端不同,前端关注“数据变化 → 页面自动更新”,Vue 把这部分做得非常简单。
- 学习Vue后,你能快速做出交互丰富的管理后台、单页应用(SPA)。
推荐直接看官方文档(中文极好): Vue 3 官方文档
2. 快速起步(10分钟搭建第一个项目)
使用 Vite(官方推荐,最快最现代的构建工具):
# 1. 创建项目
npm create vite@latest my-vue-app -- --template vue
# 2. 进入目录并安装依赖
cd my-vue-app
npm install
# 3. 启动开发服务器
npm run dev打开 http://localhost:5173,就能看到“Hello Vue”页面。
项目结构重点看:
src/App.vue:根组件(单文件组件,.vue文件集成了HTML、JS、CSS)src/main.js:入口文件,创建Vue应用实例
3. 单文件组件(.vue文件)结构
每个.vue文件分为三部分:
<template>
<!-- HTML模板,只能有一个根元素 -->
<div>
<h1>{{ title }}</h1>
<button @click="count++">计数:{{ count }}</button>
</div>
</template>
<script setup>
// 这里是脚本,使用 Composition API(推荐)
import { ref } from 'vue'
const title = ref('Hello Vue')
const count = ref(0)
</script>
<style scoped>
/* CSS,scoped表示只作用于当前组件 */
h1 { color: blue; }
</style>这就是Vue最常见的写法,后面所有例子都基于<script setup>。
4. 核心概念
4.1 响应式数据(ref / reactive)
Vue 最牛的地方:数据变了,页面自动更新。
<script setup>
import { ref, reactive } from 'vue'
// 基本类型用 ref
const count = ref(0)
// 对象/数组用 reactive(更方便)
const state = reactive({
name: '张三',
list: [1, 2, 3]
})
</script>
<template>
<p>计数:{{ count }}</p>
<p>姓名:{{ state.name }}</p>
<button @click="count++">+1</button>
<button @click="state.list.push(4)">添加</button>
</template>4.2 模板语法
- 插值:
{{ expression }} - 指令(以v-开头):
v-bind(缩写:)绑定属性:<img :src="imgUrl">v-on(缩写@)绑定事件:<button @click="handleClick">v-model双向绑定表单:<input v-model="searchText">v-if / v-else条件渲染v-for列表渲染(必须加:key)
<template>
<div v-if="loggedIn">欢迎回来!</div>
<div v-else>请登录</div>
<ul>
<li v-for="item in list" :key="item.id">{{ item.name }}</li>
</ul>
</template>4.3 计算属性(computed)
当你需要基于响应式数据做计算时用,避免在模板里写复杂逻辑。
<script setup>
import { ref, computed } from 'vue'
const list = ref([1, 2, 3, 4])
const evenList = computed(() => list.value.filter(n => n % 2 === 0))
</script>
<template>
<p>偶数:{{ evenList }}</p>
</template>4.4 事件处理
<script setup>
const handleClick = () => {
alert('点击了!')
}
</script>
<template>
<button @click="handleClick">点我</button>
<!-- 传参 -->
<button @click="add($event, 5)">加5</button>
</template>4.5 生命周期
组件的生命周期大致流程:
创建阶段 → 挂载阶段 → 更新阶段 → 销毁阶段- 创建阶段:实例被创建,data/props 初始化(适合初始化数据)
- 挂载阶段:模板编译、DOM 插入(适合发请求、操作 DOM)
- 更新阶段:数据变化触发(适合处理副作用)
- 销毁阶段:组件移除(适合清理定时器、事件监听)
4.5.2. 完整钩子对比表(Vue 3)
| 阶段 | Options API(旧写法) | Composition API(新写法,) | 常见用途 |
|---|---|---|---|
| 创建前 | beforeCreate | setup() 开始 | 几乎不用(实例还没创建) |
| 创建后 | created | setup() 结束 | 初始化数据、发初始请求(不能操作 DOM) |
| 挂载前 | beforeMount | onBeforeMount | 模板已编译,但还没插入 DOM |
| 挂载后 | mounted | onMounted | 最常用:发请求、操作 DOM、启动定时器 |
| 更新前 | beforeUpdate | onBeforeUpdate | 数据变了,即将重新渲染(可访问旧 DOM) |
| 更新后 | updated | onUpdated | 渲染完成(慎用,容易无限循环) |
| 销毁前 | beforeUnmount | onBeforeUnmount | 即将移除,清理资源 |
| 销毁后 | unmounted | onUnmounted | 常用:清理定时器、事件监听、订阅 |
| 错误捕获 | errorCaptured | onErrorCaptured | 子组件报错时捕获 |
| keep-alive 激活 | activated | onActivated | 缓存组件被激活时 |
| keep-alive 失活 | deactivated | onDeactivated | 缓存组件被停用时 |
4.5.3. 代码示例对比
Options API 写法(传统对象式,很多老教程用这个)
<script>
export default {
data() {
return { count: 0 }
},
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created:数据已初始化,可以发请求')
// 常见:this.axios.get(...)
},
beforeMount() {
console.log('beforeMount')
},
mounted() {
console.log('mounted:DOM 已插入,可以操作 DOM')
// 常见:获取 DOM 元素、第三方库初始化
},
beforeUpdate() {
console.log('beforeUpdate')
},
updated() {
console.log('updated')
},
beforeUnmount() {
console.log('beforeUnmount')
},
unmounted() {
console.log('unmounted:彻底清理')
// 常见:clearInterval、removeEventListener
}
}
</script>Composition API 写法(Vue 3 推荐, 最简洁)
<script setup>
import {
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted
} from 'vue'
onBeforeMount(() => console.log('onBeforeMount'))
onMounted(() => {
console.log('onMounted:最常用,发请求、操作 DOM')
// 这里发 axios 请求
})
onBeforeUpdate(() => console.log('onBeforeUpdate'))
onUpdated(() => console.log('onUpdated(慎用)'))
onBeforeUnmount(() => console.log('onBeforeUnmount'))
onUnmounted(() => {
console.log('onUnmounted:清理资源')
// 清理定时器、订阅等
})
</script>5. 组件化(Vue的灵魂)
- 所有页面都是组件嵌套而成。
- 创建组件:新建一个.vue文件即可。
父组件 → 子组件传值(props)
子组件 Child.vue:
<script setup>
defineProps({
msg: String,
count: Number
})
</script>
<template>
<p>收到:{{ msg }},数字:{{ count }}</p>
</template>父组件使用:
<template>
<Child msg="hello" :count="123" />
</template>子组件 → 父组件通信(emit)
子组件:
<script setup>
const emit = defineEmits(['update'])
const send = () => emit('update', '新数据')
</script>
<template>
<button @click="send">发送</button>
</template>父组件:
<Child @update="handleUpdate" />6. 常用进阶
6.1 Vue Router(路由)
安装:npm install vue-router@4
基本配置(src/router/index.js):
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: Home },
{ path: '/about', component: About }
]
})
export default routermain.js 中使用:
import router from './router'
app.use(router)模板中使用:
<router-link to="/about">去关于页</router-link>
<router-view /> <!-- 这里渲染对应组件 -->6.2 Pinia(状态管理,Vue官方推荐,替代Vuex)
安装:npm install pinia
创建 store(src/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 counter = useCounterStore()
// 直接用
counter.increment()
</script>
<template>
<p>计数:{{ counter.count }},双倍:{{ counter.double }}</p>
</template>推荐UI组件库(省大量CSS时间):
- Element Plus(最流行)
- Naive UI