文章目錄
vue-router 和 vuex 是官方提供的Vue插件,主要解決路由和狀態管理兩個問題
一、vue-router
1.基本概念
解決什麼問題?vue-router解決了路由與組件的對應關係
2.vue-router的基本使用方法
- 安裝vue-router依賴
cnpm i -S vue-router
- 使用vue-router插件
import Route from 'vue-router'
Vue.use(Route)
- 初始化vue-router對象
const routes = [
{ path: '/a', component: A },
{ path: '/b', component: B },
{ path: '/hello-world', component: HelloWorld }
]
const router = new Route({
routes
})
注:這裏省略了定義A組件和B組件的過程,這兩個組件與普通組件無異
- 實例化Vue對象,傳入router參數
new Vue({
router,
render: h => h(App)
})
- 使用router-view和router-link
router-view和router-link是vue-router官方提供的兩個組件,router-view會替換爲路由對應的組件,router-link相當於a標籤,點擊後會加載to屬性中路由對應的組件
<div>
<div>
<router-link to="/a">a</router-link>
</div>
<div>
<router-link to="/b">b</router-link>
</div>
<div>
<router-link to="/hello-world">hello-world</router-link>
</div>
</div>
<router-view />
3.路由嵌套
上面是一個非常簡單的vue-router case,實際項目開發過程中,需求往往不會這麼簡單,比如我們希望實現/a/aa路由,並且/aa對應的組件嵌套在/a之下,這時我們需要修改路由的配置文件:
const routes = [{
path: '/a',
component: A,
redirect: '/a/aa',
children: [
{
path: '/a/aa',
component: AA,
}]
}]
並修改A組件的內容:
<template>
<div>
<div>a</div>
<router-view />
</div>
</template>
由於A組件是父級路由,所以也需要添加router-view組件,動態匹配子路由
4.重定向
將一個路由重定向到另一個路由,實際開發過程中非常實用,修改配置文件即可:
const routes = [{
path: '/a',
component: A,
redirect: '/a/aa',
children: [{
path: '/a/aa',
component: AA,
}]
}]
5.動態路由
爲了支持restful形式路由以及更復雜的場景時,我們可以使用動態路由,定義路由時,在路由前加上冒號即可,我們先添加AA2組件,動態路由部分通過this.$route.params進行接收:
<template>
<div>
aa2
<div>{{id}}</div>
</div>
</template>
<script>
export default {
data() {
return {
id: null
}
},
created() {
this.id = this.$route.params.id
}
}
</script>
修改路由配置後生效:
const routes = [
{
path: '/a',
component: A,
redirect: '/a/aa',
children: [
{
path: '/a/aa',
component: AA,
},
{
path: '/a/:id',
component: AA2,
},
]
}
]
動態路由的優先級低於普通路由,所以我們訪問/a/aa時會匹配到AA組件,而輸入其他路由時會匹配到AA2組件
6.路由參數
參數傳遞是我們開發過程中必不可少的步驟,vue-router支持參數傳遞,通過this.$route.query進行接收,我們修改AA組件進行測試
<template>
<div>
aa
<div>{{message}}</div>
</div>
</template>
<script>
export default {
data() {
return {
message: ''
}
},
created() {
this.message = this.$route.query.message || ''
}
}
</script>
7.編程式路由
有很多時候我們需要手動操作路由的跳轉,這時我們需要使用this.$router,以下是一些常用的操作:
- 路由跳轉
this.$router.push('/a/aa')
- 帶參數路由跳轉
this.$router.push({
path: '/a/aa',
query: {
message: 'hello'
}
})
- 不向history插入記錄
this.$router.replace('/a/123')
- 回退
this.$router.go(-1)
二、vuex
1.基本概念
解決什麼問題?vuex解決了狀態管理問題,通過集中管理狀態,使得state、action和view實現鬆耦合,從而讓代碼更易維護
可簡單理解爲:action≈method;state≈data;view≈templete
2.vuex的基本使用方法
- 安裝vuex依賴
cnpm i -S vuex
- 使用vuex插件
import Store from 'vuex'
Vue.use(Store)
- 初始化vuex對象
const store = new Vuex.Store({
state: {
data: 'this is data'
},
mutations: {
SET_DATA(state, data) {
state.data = data
}
},
actions: {
setData({ commit }, data) {
commit('SET_DATA', data)
}
}
})
- 實例化Vue對象,傳入store參數
new Vue({
render: h => h(App),
router,
store
})
- 讀取vuex狀態
<div>{{$store.state.data}}</div>
- 更新vuex狀態
update() {
this.$store.dispatch('setData', 'this is update data')
}
3.vuex模塊化
實際項目開發中,狀態衆多,如果全部混在一起,則難以分辨,而且容易相互衝突,爲了解決問題,vuex引入模塊化的概念,解決這個問題,下面我們定義a和b兩個模塊:
const moduleA = {
state: {
data: 'this is a'
},
mutations: {
SET_DATA(state, data) {
state.data = data
}
},
actions: {
setData({ commit }, data) {
commit('SET_DATA', data)
}
}
}
const moduleB = {
state: {
data: 'this is b'
},
mutations: {
SET_DATA(state, data) {
state.data = data
}
},
actions: {
setData({ commit }, data) {
commit('SET_DATA', data)
}
}
}
修改store的初始化代碼:
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
修改獲取狀態的代碼,此時需要加入模塊進行區分:
<div>{{$store.state.a.data}}</div>
<div>{{$store.state.b.data}}</div>
<button @click="update('a')">update a</button>
<button @click="update('b')">update b</button>
修改update方法:
update(ns) {
this.$store.dispatch(`setData`, `update ${ns}`)
}
4.vuex命名空間
上述代碼在執行過程中,獲取狀態沒有問題,但是修改狀態會出現問題,因爲兩個模塊出現同名actions,所以此時需要使用命名空間來解決這個問題:
const moduleA = {
namespaced: true,
// ...
}
const moduleB = {
namespaced: true,
// ...
}
修改update方法:
update(ns) {
this.$store.dispatch(`${ns}/setData`, `update ${ns}`)
}