Vue.js框架
基础概念
Vue.js是一套用于构建用户界面的渐进式框架,易于上手,可以与其他库或现有项目整合。
核心特性
- 响应式数据绑定: 数据变化自动更新视图
- 组件化: 可复用的UI组件
- 虚拟DOM: 高效的DOM更新机制
- 渐进式: 可以逐步采用,从简单应用到复杂应用
基础语法
模板语法
vue
<template>
<div id="app">
<!-- 文本插值 -->
<h1>{{ message }}</h1>
<!-- 属性绑定 -->
<img :src="imageSrc" :alt="imageAlt">
<!-- 条件渲染 -->
<div v-if="isVisible">显示内容</div>
<div v-else>隐藏内容</div>
<!-- 列表渲染 -->
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
<!-- 事件处理 -->
<button @click="handleClick">点击我</button>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
message: 'Hello Vue!',
imageSrc: '/logo.png',
imageAlt: 'Vue Logo',
isVisible: true,
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
]
}
},
methods: {
handleClick() {
console.log('Button clicked!')
}
}
}
</script>
<style scoped>
#app {
text-align: center;
margin-top: 60px;
}
</style>
组件系统
vue
<!-- 子组件 -->
<template>
<div class="child-component">
<h2>{{ title }}</h2>
<p>{{ content }}</p>
<button @click="$emit('update', newValue)">
更新父组件
</button>
</div>
</template>
<script>
export default {
name: 'ChildComponent',
props: {
title: {
type: String,
required: true
},
content: {
type: String,
default: '默认内容'
}
},
data() {
return {
newValue: '新值'
}
}
}
</script>
<!-- 父组件 -->
<template>
<div>
<child-component
:title="parentTitle"
:content="parentContent"
@update="handleUpdate"
/>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
data() {
return {
parentTitle: '父组件标题',
parentContent: '父组件内容'
}
},
methods: {
handleUpdate(value) {
this.parentContent = value
}
}
}
</script>
生命周期
javascript
export default {
name: 'LifecycleDemo',
// 创建阶段
beforeCreate() {
console.log('beforeCreate: 实例初始化之前')
},
created() {
console.log('created: 实例创建完成')
},
// 挂载阶段
beforeMount() {
console.log('beforeMount: 挂载开始之前')
},
mounted() {
console.log('mounted: 挂载完成')
},
// 更新阶段
beforeUpdate() {
console.log('beforeUpdate: 数据更新时')
},
updated() {
console.log('updated: 数据更新完成')
},
// 销毁阶段
beforeDestroy() {
console.log('beforeDestroy: 实例销毁之前')
},
destroyed() {
console.log('destroyed: 实例销毁完成')
}
}
计算属性和侦听器
计算属性
javascript
export default {
data() {
return {
firstName: 'John',
lastName: 'Doe',
items: [1, 2, 3, 4, 5]
}
},
computed: {
// 基本计算属性
fullName() {
return this.firstName + ' ' + this.lastName
},
// 带缓存的复杂计算
filteredItems() {
return this.items.filter(item => item > 2)
},
// 计算属性的getter和setter
fullNameWithSetter: {
get() {
return this.firstName + ' ' + this.lastName
},
set(value) {
const names = value.split(' ')
this.firstName = names[0]
this.lastName = names[1]
}
}
}
}
侦听器
javascript
export default {
data() {
return {
message: 'Hello',
user: {
name: 'John',
age: 25
}
}
},
watch: {
// 简单侦听
message(newVal, oldVal) {
console.log('message changed:', oldVal, '->', newVal)
},
// 深度侦听对象
user: {
handler(newVal, oldVal) {
console.log('user changed:', newVal)
},
deep: true
},
// 立即执行
immediate: true,
// 侦听特定属性
'user.name'(newVal, oldVal) {
console.log('user.name changed:', oldVal, '->', newVal)
}
}
}
Vue 3 Composition API
基础用法
vue
<template>
<div>
<h1>{{ title }}</h1>
<p>Count: {{ count }}</p>
<button @click="increment">增加</button>
<button @click="decrement">减少</button>
</div>
</template>
<script>
import { ref, reactive, computed, onMounted } from 'vue'
export default {
setup() {
// 响应式数据
const title = ref('Vue 3 Composition API')
const count = ref(0)
const state = reactive({
firstName: 'John',
lastName: 'Doe'
})
// 计算属性
const fullName = computed(() => {
return state.firstName + ' ' + state.lastName
})
// 方法
const increment = () => {
count.value++
}
const decrement = () => {
count.value--
}
// 生命周期
onMounted(() => {
console.log('Component mounted')
})
return {
title,
count,
fullName,
increment,
decrement
}
}
}
</script>
组合函数
javascript
// useCounter.js
import { ref, computed } from 'vue'
export function useCounter(initialValue = 0) {
const count = ref(initialValue)
const doubleCount = computed(() => count.value * 2)
const increment = () => count.value++
const decrement = () => count.value--
const reset = () => count.value = initialValue
return {
count,
doubleCount,
increment,
decrement,
reset
}
}
// 在组件中使用
import { useCounter } from './useCounter'
export default {
setup() {
const { count, doubleCount, increment, decrement, reset } = useCounter(10)
return {
count,
doubleCount,
increment,
decrement,
reset
}
}
}
路由管理
Vue Router基础
javascript
// 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'),
props: true
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
路由导航
vue
<template>
<div>
<!-- 声明式导航 -->
<router-link to="/">首页</router-link>
<router-link to="/about">关于</router-link>
<router-link :to="{ name: 'User', params: { id: 123 }}">
用户页面
</router-link>
<!-- 编程式导航 -->
<button @click="goToHome">去首页</button>
<button @click="goToUser(456)">去用户页面</button>
<!-- 路由出口 -->
<router-view />
</div>
</template>
<script>
export default {
methods: {
goToHome() {
this.$router.push('/')
},
goToUser(id) {
this.$router.push({
name: 'User',
params: { id }
})
}
}
}
</script>
状态管理
Vuex基础
javascript
// store/index.js
import { createStore } from 'vuex'
export default createStore({
state: {
count: 0,
user: null
},
mutations: {
increment(state) {
state.count++
},
setUser(state, user) {
state.user = user
}
},
actions: {
async fetchUser({ commit }, userId) {
const user = await api.getUser(userId)
commit('setUser', user)
}
},
getters: {
doubleCount: state => state.count * 2,
isLoggedIn: state => !!state.user
}
})
在组件中使用
vue
<template>
<div>
<p>Count: {{ count }}</p>
<p>Double Count: {{ doubleCount }}</p>
<button @click="increment">增加</button>
<button @click="fetchUser(123)">获取用户</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
computed: {
...mapState(['count']),
...mapGetters(['doubleCount'])
},
methods: {
...mapMutations(['increment']),
...mapActions(['fetchUser'])
}
}
</script>
最佳实践
性能优化
- 懒加载: 使用动态导入减少初始包大小
- 虚拟滚动: 处理大量数据时使用虚拟滚动
- keep-alive: 缓存组件状态
- v-show vs v-if: 频繁切换使用v-show
代码组织
- 组件命名: 使用PascalCase命名组件
- 文件结构: 按功能组织文件
- 类型检查: 使用TypeScript提高代码质量
- 测试: 编写单元测试和集成测试