

文章目录
正文
1. Vue简介
Vue.js是一个用于构建用户界面的渐进式JavaScript框架。与其他大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,易于上手,便于与第三方库或既有项目整合。
1.1 Vue的特点
- 响应式系统:自动追踪依赖关系并更新DOM
- 组件化开发:可复用的组件系统
- 虚拟DOM:高效的DOM操作
- 轻量级:压缩后大小约33KB
- 易学易用:上手快,文档完善
1.2 Vue的发展历程
- Vue 1.0:2015年发布
- Vue 2.0:2016年发布,重写了响应式系统
- Vue 3.0:2020年发布,使用Proxy重写响应式系统,提供Composition API
2. 安装与使用
2.1 直接引入
<!-- 开发环境版本 -->
<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.js"></script>
<!-- 生产环境版本 -->
<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
2.2 使用npm安装
# 最新稳定版
npm install vue@next
2.3 使用Vue CLI
# 安装Vue CLI
npm install -g @vue/cli
# 创建项目
vue create my-project
3. Vue基础语法
3.1 创建Vue实例
// Vue 3
const app = Vue.createApp({
data() {
return {
message: 'Hello Vue!'
}
}
})
app.mount('#app')
<div id="app">
{{ message }}
</div>
3.2 数据绑定
3.2.1 文本插值
<span>{{ message }}</span>
3.2.2 HTML属性绑定
<div v-bind:id="dynamicId"></div>
<!-- 简写 -->
<div :id="dynamicId"></div>
3.3 条件渲染
<div v-if="seen">现在你看到我了</div>
<div v-else-if="condition">条件成立时显示</div>
<div v-else>否则显示我</div>
<!-- v-show只是切换元素的CSS display属性 -->
<div v-show="seen">使用v-show的元素始终会被渲染</div>
3.4 列表渲染
<ul>
<li v-for="(item, index) in items" :key="item.id">
{{ index }} - {{ item.text }}
</li>
</ul>
data() {
return {
items: [
{ id: 1, text: '学习 JavaScript' },
{ id: 2, text: '学习 Vue' },
{ id: 3, text: '整个牛项目' }
]
}
}
4. 事件处理
4.1 监听事件
<button v-on:click="counter += 1">增加 1</button>
<!-- 简写 -->
<button @click="counter += 1">增加 1</button>
4.2 方法事件处理器
<button @click="greet">打招呼</button>
data() {
return {
name: '张三'
}
},
methods: {
greet() {
alert('Hello ' + this.name + '!')
}
}
4.3 事件修饰符
<!-- 阻止单击事件继续传播 -->
<a @click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form @submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a @click.stop.prevent="doThat"></a>
<!-- 只有在 event.target 是元素本身时才触发处理函数 -->
<div @click.self="doThat">...</div>
5. 表单输入绑定
5.1 基础用法
<input v-model="message" placeholder="编辑我...">
<p>消息是: {{ message }}</p>
5.2 不同输入类型
<!-- 文本 -->
<input v-model="message">
<!-- 多行文本 -->
<textarea v-model="message"></textarea>
<!-- 复选框 -->
<input type="checkbox" v-model="checked">
<!-- 单选按钮 -->
<input type="radio" value="One" v-model="picked">
<input type="radio" value="Two" v-model="picked">
<!-- 选择框 -->
<select v-model="selected">
<option disabled value="">请选择</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
6. 组件基础
6.1 组件注册
// 全局注册
const app = Vue.createApp({})
app.component('my-component', {
template: '<div>组件内容</div>'
})
// 局部注册
const ComponentA = {
template: '<div>组件A</div>'
}
const app = Vue.createApp({
components: {
'component-a': ComponentA
}
})
6.2 组件通信
6.2.1 Props向下传递
// 子组件
app.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
<!-- 父组件使用 -->
<blog-post title="Vue学习笔记"></blog-post>
6.2.2 事件向上传递
// 子组件
app.component('button-counter', {
template: `
<button @click="incrementCounter">
点击了 {{ count }} 次
</button>
`,
data() {
return {
count: 0
}
},
methods: {
incrementCounter() {
this.count++
this.$emit('increment')
}
}
})
<!-- 父组件监听事件 -->
<button-counter @increment="total++"></button-counter>
7. Vue生命周期
7.1 生命周期钩子
const app = Vue.createApp({
data() {
return {
message: 'Hello'
}
},
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
beforeMount() {
console.log('beforeMount')
},
mounted() {
console.log('mounted')
},
beforeUpdate() {
console.log('beforeUpdate')
},
updated() {
console.log('updated')
},
beforeUnmount() {
console.log('beforeUnmount')
},
unmounted() {
console.log('unmounted')
}
})
7.2 生命周期图示
Vue生命周期图示
Vue实例从创建到销毁的整个过程被称为生命周期。Vue提供了多个生命周期钩子函数,让开发者可以在特定阶段添加自己的代码。以下是Vue生命周期的详细图示:
创建阶段 → 挂载阶段 → 更新阶段 → 卸载阶段
Vue 3生命周期图示
beforeCreate → created → beforeMount → mounted → beforeUpdate → updated → beforeUnmount → unmounted
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
初始化事件和生命周期 → 初始化注入和响应式 → 创建DOM → 挂载DOM → 虚拟DOM重新渲染 → 更新DOM → 移除事件监听器 → 销毁组件实例
生命周期钩子详解
-
beforeCreate: 实例初始化之后,数据观测和事件配置之前被调用
- 此时无法访问data和methods
-
created: 实例创建完成后被调用
- 可以访问data和methods
- 还未挂载DOM,无法访问$el
-
beforeMount: 挂载开始之前被调用
- 模板已编译,但还未渲染到页面
-
mounted: 挂载完成后调用
- 可以访问DOM元素
- 适合执行DOM操作和发送API请求
-
beforeUpdate: 数据更新时,DOM更新之前调用
- 可以在DOM更新前访问现有DOM
-
updated: DOM更新完成后调用
- 避免在此钩子中更改状态,可能导致无限循环
-
beforeUnmount: 组件卸载前调用
- 实例仍然可用
-
unmounted: 组件卸载后调用
- 所有子组件也已卸载
- 所有响应式效果已停止
Vue 2与Vue 3生命周期对比
| Vue 2 | Vue 3 | 描述 |
|---|---|---|
| beforeCreate | beforeCreate | 实例初始化之前 |
| created | created | 实例创建完成 |
| beforeMount | beforeMount | DOM挂载前 |
| mounted | mounted | DOM挂载后 |
| beforeUpdate | beforeUpdate | 数据更新前 |
| updated | updated | 数据更新后 |
| beforeDestroy | beforeUnmount | 实例销毁前 |
| destroyed | unmounted | 实例销毁后 |
Composition API中的生命周期钩子
Vue 3的Composition API提供了等效的生命周期钩子函数:
import {
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted
} from 'vue'
export default {
setup() {
// beforeCreate和created钩子在setup函数本身内部
console.log('setup - 相当于beforeCreate和created')
onBeforeMount(() => {
console.log('onBeforeMount')
})
onMounted(() => {
console.log('onMounted')
})
onBeforeUpdate(() => {
console.log('onBeforeUpdate')
})
onUpdated(() => {
console.log('onUpdated')
})
onBeforeUnmount(() => {
console.log('onBeforeUnmount')
})
onUnmounted(() => {
console.log('onUnmounted')
})
}
}
8. Vue Router基础
8.1 安装
npm install vue-router@4
8.2 基本配置
// 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
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router)
app.mount('#app')
8.3 路由导航
<router-link to="/">首页</router-link>
<router-link to="/about">关于</router-link>
<!-- 路由出口 -->
<router-view></router-view>
9. Vuex状态管理
9.1 安装
npm install vuex@next
9.2 基本配置
// store/index.js
import { createStore } from 'vuex'
export default createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
},
getters: {
doubleCount(state) {
return state.count * 2
}
}
})
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
const app = createApp(App)
app.use(store)
app.mount('#app')
9.3 在组件中使用
<template>
<div>
<p>Count: {{ count }}</p>
<p>Double Count: {{ doubleCount }}</p>
<button @click="increment">+1</button>
<button @click="incrementAsync">Async +1</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
computed: {
...mapState(['count']),
...mapGetters(['doubleCount'])
},
methods: {
...mapMutations(['increment']),
...mapActions(['incrementAsync'])
}
}
</script>
10. Composition API
10.1 基本用法
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">+1</button>
</div>
</template>
<script>
import { ref, onMounted } from 'vue'
export default {
setup() {
// 响应式状态
const count = ref(0)
// 方法
function increment() {
count.value++
}
// 生命周期钩子
onMounted(() => {
console.log('组件已挂载')
})
// 返回需要暴露给模板的内容
return {
count,
increment
}
}
}
</script>
10.2 响应式API
import { ref, reactive, computed, watch } from 'vue'
// ref: 适用于基本类型
const count = ref(0)
console.log(count.value) // 0
// reactive: 适用于对象
const state = reactive({
count: 0,
name: 'Vue'
})
console.log(state.count) // 0
// computed: 计算属性
const doubleCount = computed(() => count.value * 2)
// watch: 侦听变化
watch(count, (newValue, oldValue) => {
console.log(`count从${oldValue}变为${newValue}`)
})
11. 实战项目:待办事项应用
11.1 项目结构
todo-app/
├── public/
│ └── index.html
└── src/
├── assets/
├── components/
│ ├── TodoForm.vue
│ ├── TodoItem.vue
│ └── TodoList.vue
├── App.vue
└── main.js
11.2 组件实现
<!-- App.vue -->
<template>
<div class="container">
<h1>Vue待办事项</h1>
<todo-form @add-todo="addTodo"></todo-form>
<todo-list
:todos="todos"
@toggle-todo="toggleTodo"
@delete-todo="deleteTodo"
></todo-list>
</div>
</template>
<script>
import TodoForm from './components/TodoForm.vue'
import TodoList from './components/TodoList.vue'
export default {
components: {
TodoForm,
TodoList
},
data() {
return {
todos: [
{ id: 1, text: '学习Vue基础', completed: true },
{ id: 2, text: '完成待办事项应用', completed: false }
]
}
},
methods: {
addTodo(text) {
this.todos.push({
id: Date.now(),
text,
completed: false
})
},
toggleTodo(id) {
const todo = this.todos.find(todo => todo.id === id)
if (todo) {
todo.completed = !todo.completed
}
},
deleteTodo(id) {
this.todos = this.todos.filter(todo => todo.id !== id)
}
}
}
</script>
<!-- TodoForm.vue -->
<template>
<form @submit.prevent="handleSubmit">
<input
v-model="newTodo"
placeholder="添加新待办..."
required
>
<button type="submit">添加</button>
</form>
</template>
<script>
export default {
data() {
return {
newTodo: ''
}
},
methods: {
handleSubmit() {
if (this.newTodo.trim()) {
this.$emit('add-todo', this.newTodo.trim())
this.newTodo = ''
}
}
}
}
</script>
<!-- TodoList.vue -->
<template>
<ul class="todo-list">
<todo-item
v-for="todo in todos"
:key="todo.id"
:todo="todo"
@toggle="$emit('toggle-todo', todo.id)"
@delete="$emit('delete-todo', todo.id)"
></todo-item>
</ul>
</template>
<script>
import TodoItem from './TodoItem.vue'
export default {
components: {
TodoItem
},
props: {
todos: {
type: Array,
required: true
}
}
}
</script>
<!-- TodoItem.vue -->
<template>
<li :class="{ completed: todo.completed }">
<input
type="checkbox"
:checked="todo.completed"
@change="$emit('toggle')"
>
<span>{{ todo.text }}</span>
<button @click="$emit('delete')">删除</button>
</li>
</template>
<script>
export default {
props: {
todo: {
type: Object,
required: true
}
}
}
</script>
<style scoped>
.completed {
text-decoration: line-through;
color: gray;
}
</style>
12. 性能优化
12.1 优化策略
- 使用key:在v-for中始终使用key
- 避免过度监听:合理使用computed和watch
- 懒加载组件:使用动态导入
- 保持数据简单:避免过深的响应式对象嵌套
- 虚拟滚动:处理大列表
12.2 代码分割
// 路由懒加载
const routes = [
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
}
]
12.3 性能分析工具
- Vue Devtools
- Chrome Performance面板
- Lighthouse
13. Vue 3新特性总结
13.1 主要变化
- Composition API:更好的代码组织和逻辑复用
- Teleport:将内容渲染到DOM树的其他位置
- Fragments:组件可以有多个根节点
- Suspense:处理异步组件
- 更好的TypeScript支持:类型推断改进
13.2 性能提升
- 更小的包体积
- 更快的渲染速度
- 更低的内存占用
结语
感谢您的阅读!期待您的一键三连!欢迎指正!

1502

被折叠的 条评论
为什么被折叠?



