一、基础语法与指令
1. 插值表达式
插值表达式是 Vue 中最基础的数据绑定方式,使用双大括号{``{ }}
将数据包裹起来,例如{``{ message }}
,它会将 Vue 实例中的message
属性的值渲染到页面相应位置。这种方式可以方便地在页面中展示动态数据,如从后端获取的数据或者用户输入的信息。
2. 指令
Vue 提供了一系列指令来增强 HTML 的功能。
v-bind
:用于动态绑定 HTML 属性,缩写为:
。例如<img v-bind:src="imageSrc">
,可以根据imageSrc
变量的值动态改变图片的源地址。v-on
:用于绑定事件监听器,缩写为@
。比如<button v-on:click="handleClick">点击我</button>
,当按钮被点击时,会触发handleClick
方法。v-model
:实现双向数据绑定,常用于表单元素。例如<input v-model="inputValue">
,用户在输入框中输入的值会自动同步到inputValue
变量,反之亦然。v-if
和v-show
:用于控制元素的显示与隐藏。v-if
是真正的条件渲染,会根据条件决定元素是否被添加到 DOM 中;v-show
则是通过 CSS 的display
属性来控制元素的可见性,元素始终在 DOM 中存在。
二、组件化开发
1. 组件的创建与注册
在 Vue 中,组件是构建应用的核心单元。可以使用Vue.component
方法全局注册组件,或者在单文件组件(.vue
文件)中局部注册。一个简单的全局组件示例如下:
javascript
Vue.component('my-component', {
template: '<div>这是一个自定义组件</div>'
})
在单文件组件中,结构更加清晰:
vue
<template>
<div>这是一个局部组件</div>
</template>
<script>
export default {
name: 'MyLocalComponent'
}
</script>
2. 组件通信
组件之间的通信是项目开发中常见的需求。
- 父子组件通信 :父组件可以通过
props
向子组件传递数据,子组件通过$emit
触发自定义事件向父组件传递消息。例如,父组件:
vue
<template>
<div>
<child-component :message="parentMessage" @child-event="handleChildEvent"></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
data() {
return {
parentMessage: '来自父组件的消息'
}
},
methods: {
handleChildEvent(payload) {
console.log('收到子组件消息:', payload)
}
}
}
</script>
子组件:
vue
<template>
<div>
<p>{{ message }}</p>
<button @click="sendMessageToParent">向父组件发送消息</button>
</div>
</template>
<script>
export default {
props: ['message'],
methods: {
sendMessageToParent() {
this.$emit('child-event', '这是子组件发送的消息')
}
}
}
</script>
- 非父子组件通信 :可以使用 Vuex 状态管理库或者事件总线(
Event Bus
)来实现。事件总线的实现方式如下:
首先创建一个事件总线实例:
javascript
// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
然后在组件中使用:
组件 A 发送事件:
vue
<template>
<div>
<button @click="sendMessage">发送消息</button>
</div>
</template>
<script>
import { EventBus } from './event-bus.js'
export default {
methods: {
sendMessage() {
EventBus.$emit('global-event', '这是组件 A 发送的消息')
}
}
}
</script>
组件 B 接收事件:
vue
<template>
<div>接收消息的组件 B</div>
</template>
<script>
import { EventBus } from './event-bus.js'
export default {
mounted() {
EventBus.$on('global-event', (message) => {
console.log('组件 B 收到消息:', message)
})
},
beforeDestroy() {
EventBus.$off('global-event')
}
}
</script>
三、Vue 路由
Vue Router 是 Vue.js 的官方路由管理器,用于实现单页面应用(SPA)的页面导航。
1. 路由的基本配置
首先安装 Vue Router:
bash
npm install vue-router
然后在main.js
中引入并使用:
javascript
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
import Home from './views/Home.vue'
import About from './views/About.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
]
const router = new VueRouter({
routes
})
new Vue({
router,
render: h => h(App)
}).$mount('#app')
在组件中通过<router-link>
和<router-view>
来实现页面跳转和视图渲染:
vue
<template>
<div>
<router-link to="/">首页</router-link>
<router-link to="/about">关于</router-link>
<router-view></router-view>
</div>
</template>
2. 动态路由与路由参数
可以在路由路径中定义动态参数,例如:
javascript
const routes = [
{
path: '/user/:id',
name: 'User',
component: User
}
]
在组件中通过$route.params
获取路由参数:
vue
<template>
<div>用户 ID:{{ $route.params.id }}</div>
</template>
3. 路由导航守卫
路由导航守卫可以用于在路由跳转前进行权限验证、页面加载前的数据获取等操作。例如:
javascript
const router = new VueRouter({
routes
})
router.beforeEach((to, from, next) => {
// 检查用户是否登录
const isLoggedIn = false
if (to.meta.requiresAuth &&!isLoggedIn) {
next('/login')
} else {
next()
}
})
在路由配置中可以设置meta
字段来指定是否需要权限验证:
javascript
const routes = [
{
path: '/admin',
name: 'Admin',
component: Admin,
meta: {
requiresAuth: true
}
}
]
四、Vuex 状态管理
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
1. Vuex 的核心概念
- State:存储应用的状态数据,是单一数据源。例如:
javascript
const store = new Vuex.Store({
state: {
count: 0
}
})
- Mutations:用于修改 State 的唯一途径,是同步函数。例如:
javascript
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
}
})
- Actions:用于处理异步操作,如发送 AJAX 请求等,通过提交 Mutations 来间接修改 State。例如:
javascript
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
})
- Getters:类似于计算属性,用于从 State 中派生出一些新的数据。例如:
javascript
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '学习 Vue', done: false },
{ id: 2, text: '做项目', done: true }
]
},
getters: {
doneTodos(state) {
return state.todos.filter(todo => todo.done)
}
}
})
2. 在组件中使用 Vuex
在组件中可以通过this.$store
访问 Vuex 实例,从而获取 State、触发 Actions 等。例如:
vue
<template>
<div>
<p>计数:{{ count }}</p>
<button @click="increment">加 1</button>
<button @click="incrementAsync">异步加 1</button>
</div>
</template>
<script>
export default {
computed: {
count() {
return this.$store.state.count
}
},
methods: {
increment() {
this.$store.commit('increment')
},
incrementAsync() {
this.$store.dispatch('incrementAsync')
}
}
}
</script>
五、生命周期钩子
Vue 组件在创建、更新和销毁的过程中会经历一系列的生命周期钩子函数,开发者可以在这些钩子函数中执行特定的操作。
beforeCreate
:在实例初始化之后,数据观测(data observer
)和event/watcher
事件配置之前被调用。此时,组件的选项对象还未初始化,this
指向当前组件实例,但无法访问到data
、methods
等属性。created
:在实例创建完成后被立即调用。此时,实例已完成以下配置:数据观测(data observer
)、属性和方法的运算、watch/event
事件回调。然而,挂载阶段还未开始,$el
属性目前不可见。beforeMount
:在挂载开始之前被调用:相关的render
函数首次被调用。此时,模板编译成渲染函数,但尚未挂载到页面上,this.$el
还未生成。mounted
:el
被新创建的vm.$el
替换,并挂载到实例上去之后调用该钩子。此时,组件已经渲染到页面上,可以进行 DOM 操作,获取this.$el
等。beforeUpdate
:数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。updated
:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。此时,组件的 DOM 已经更新,适合执行依赖于 DOM 的操作。beforeDestroy
:实例销毁之前调用。在这一步,实例仍然完全可用。可以在这个钩子中清除定时器、解绑事件监听器等。destroyed
:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
例如:
vue
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
data() {
return {
message: '初始消息'
}
},
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')
}
}
</script>
当组件的数据发生变化或者组件被销毁时,相应的生命周期钩子函数会被触发。
六、过渡与动画
Vue 提供了内置的过渡效果和动画支持,可以让页面元素的切换更加平滑和生动。
1. 单元素 / 组件的过渡
使用<transition>
组件包裹需要过渡的元素或组件,并定义过渡类名。例如:
vue
<transition name="fade">
<p v-if="show">这是一个过渡效果示例</p>
</transition>
<button @click="show =!show">切换显示</button>
在 CSS 中定义过渡类名对应的样式:
css
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
2. 列表过渡
对于列表元素的过渡,可以使用<transition-group>
组件。例如:
vue
<transition-group name="list" tag="ul">
<li v-for="(item, index) in list" :key="index">{{ item }}</li>
</transition-group>
<button @click="addItem">添加项目</button>
在 CSS 中定义列表过渡类名的样式:
css
.list-enter-active,
.list-leave-active {
transition: all 0.5s;
}
.list-enter,
.list-leave-to {
opacity: 0;
transform: translateX(30px);
}
在 JavaScript 中定义添加项目的方法:
javascript
export default {
data() {
return {
list: ['项目 1', '项目 2']
}
},
methods: {
addItem() {
this.list.push('新项目')
}
}
}
七、网络请求
在 Vue 项目中,通常使用axios
库来进行网络请求。
首先安装axios
:
bash
npm install axios
然后在组件中使用:
vue
<template>
<div>
<ul>
<li v-for="user in users">{{ user.name }}</li>
</ul>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
users: []
}
},
mounted() {
axios.get('https://jsonplaceholder.typicode.com/users')
.then(response => {
this.users = response.data
})
.catch(error => {
console.log(error)
})
}
}
</script>
axios
支持多种请求方式,如GET
、POST
、PUT
、DELETE
等,并可以设置请求头、请求参数等。
八、错误处理
在 Vue 项目中,错误处理是确保应用稳定性的重要环节。
1. 组件内错误处理
可以在组件的生命周期钩子函数或者方法中使用try...catch
语句来捕获错误。例如:
vue
<template>
<div>
<button @click="fetchData">获取数据</button>
</div>
</template>
<script>
export default {
methods: {
fetchData() {
try {
// 可能出错的代码
const result = someFunctionThatMayThrowError()
console.log(result)
} catch (error) {
console.log('组件内错误:', error)
}
}
}
}
</script>
2. 全局错误处理
使用Vue.config.errorHandler
可以设置全局的错误处理函数,用于捕获所有组件渲染和生命周期钩子函数中的错误。例如:
javascript
Vue.config.errorHandler = function (err, vm, info) {
// 处理错误
console.log('全局错误:', err, vm, info)
}
3. 路由导航错误处理
在 Vue Router 中,可以通过路由的onError
方法来处理路由导航过程中的错误。例如:
javascript
const router = new VueRouter({
routes
})
router.onError((error) => {
console.log('路由导航错误:', error)
})