【前言】本部落格系統的講訴了Vuex的安裝、搭建。以及Actions、Mutations、State、Getters的使用,為什麼使用mapState、mapGetters以及一些細節的解釋
Vuex原理講解
編輯
Actions:詞義是 動作行為
Mutations:詞義是加工、維護
State:詞義是 狀态和資料
Dispatch:詞義是派遣、發出
Commit:送出
Render: 渲染
Mutate:轉變
從這些單詞中,大體上可以概括整個圖的流程。
VC派發(Dispatch)消息到Actions,Actions送出(Commit)到Mutation,Mutation轉變(Mutate)state,然後重新渲染整個頁面。
1、安裝vuex元件
注意:vue3隻能用vuex4版本,vue2隻能用vuex3版本。2022年2月7日之後,vue3成了預設版本,vuex4相應的也成了預設版本。是以對于vue2,要注明vuex的版本 @3
編輯
在package.json裡看到vuex就說明安裝成功了
編輯
2、使用Vuex
首先需要建立一個Store。
在Src中,建立一個名為store的檔案夾,裡面包含一個index.js的檔案
編輯
由上面那個原理圖可以看出來,store裡面至少包含Actions,Mutations,State。
如下圖
(建立Store執行個體,需要用到Vuex.Store是以需要引用Vuex)
Vue.use(Vuex)的作用就是讓vue承認store這個屬性,否則初始化Vc的時候,vue不會解析store這個屬性
編輯
main.js配置如下
其中store相當于store:store。根據ES6文法規則,如果key和value一樣,可以簡寫成key的形式
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
import store from './store'
new Vue({
render: h => h(App),
store
}).$mount('#app')
這樣Vuex的架子就搭好了,實戰演練一下,并借此機會深入的介紹一下Vuex裡面的屬性。
【求和案例】
流程講解:點選button按鈕,觸發點選事件,派發消息去Actions裡面找addSum,并且攜帶參數1。在Actions裡面,接受參數,向Mutation送出,攜帶參數1。Mutation裡改變state裡的sum的值,vue檢測到sum改變,重新渲染整個頁面。
效果圖:
編輯
Coute.vue
<template>
<div>
<h1>目前的值是:{{sum}}</h1>
<button @click="addSum">點我加1</button>
<button>點我減1</button>
</div>
</template>
<script>
export default {
name:"Coute",
methods:{
addSum()
{
this.$store.dispatch('addSum',1);
}
},
computed:{
sum()
{
return this.$store.state.sum;
}
}
}
</script>
<style>
button{
margin-right: 2px;
}
</style>
store.js
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)
const state = {
sum:1
};
const mutations={
ADDSUM(state,value)
{
state.sum+=value;
}
};
const actions={
addSum(context,value)
{
context.commit('ADDSUM',value);
}
};
export default new Vuex.Store({
state,
mutations,
actions
})
詳細看一下Action和Mutations裡面的可以攜帶參數
Actions
設定四個參數,并列印一下。
編輯
編輯
結果隻輸出了兩個參數,第一個參數是一個對象,裡面包含了commit,dispatch等屬性,第二個參數就是要攜帶的值;
其中第二個參數叫做value,第一個參數通常叫做Context,裡面最常用的是Commit。如果隻想獲得Commit也可以寫成這種形式
編輯
Mutations
編輯
編輯
同樣Mutations裡面也是隻有兩個參數,其中第一個是state(看到了sum),第二個就是攜帶的、值。Mutations最大的作用就是可以改變state的值。
疑問:為什麼需要一個Actions,求和案例之中,我把參數傳給Actions,Actions原封不動的又傳給了Mutations,為什麼我不直接傳給Mutations呢?
答:确實是這樣子。如果參數确定的話,可以跳過Actions,直接commit到Mutations裡面。但是如果參數不确定的話,比如我需要向伺服器要資料,這時候就必須用到Actions發送Ajax。
getters的使用:
如果多個元件都用到一個對state裡資料處理過的值,比如求和案例中sum的20倍。通過getters僅處理一次,就可以讓多個元件同時使用。
store
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)
const state = {
sum:1
};
const mutations={
ADDSUM(state,value)
{
state.sum+=value
}
};
const actions={
addSum({commit},value)
{
commit('ADDSUM',value)
}
};
const getters = {
bigSum(state)
{
return state.sum*20
}
}
export default new Vuex.Store({
state,
mutations,
actions,
getters
})
編輯
Store倉庫資料的使用:
編輯
現在我們有多個資料,怎麼樣在任意元件裡面通路的到呢?為了表現出元件之間的通信。建立一個元件Information
答案就是在Computed裡面獲得
<template>
<div>
<h1>姓名:{{name}}</h1>
<h1>學校:{{school}}</h1>
<h1>爵位:{{Marquis}}</h1>
</div>
</template>
<script>
export default {
name:'Information',
computed:{
school()
{
return this.$store.state.school;
},
sum()
{
return this.$store.state.sum;
},
name()
{
return this.$store.state.name;
},
Marquis()
{
return this.$store.state.Marquis;
}
}
}
</script>
<style>
</style>
效果圖
編輯
GetState 的引入
編輯
由上圖所示,這樣一個一個的寫,雖然可以寫出來,但是實在是太麻煩了。幹的都是一樣的工作。是以Vue給我們提供了一個方法。mapState和mapGetters。這兩個一個是簡化State裡的屬性,一個是簡化getters裡面的屬性。
第一種方法可以簡寫成下面這種形式。(對象寫法。函數的名字可以随意)
編輯
為什麼要用...mapState。
原因:mapState報錯
編輯
為什麼報錯呢?
輸出一下mapState()來看看。
編輯
mapState裡面是一個對象。computed本身也是一個對象。{}裡面再加一個{},是肯定會報錯的。
那為什麼用...呢,ES6用法中,一個對象t1,一個對象t2,t1{...t2}就相當于,把t2中的屬性全拿出來一個個放到t1裡面。
第二種方法:數組方法(state裡面的屬性是什麼就必須寫什麼)
編輯
效果都是可以的
編輯
mapGetters同理,就不贅述了
【錯誤示範--使用Vuex時】
Vue.use(Vuex)在main.js裡面使用
main.js
import Vue from 'vue'
import App from './App.vue'
import Vuex from 'vuex'
Vue.use(Vuex)
Vue.config.productionTip = false
import store from './store'
new Vue({
render: h => h(App),
store
}).$mount('#app')
import Vuex from 'vuex'
const state = {
};
const mutations={
};
const actions={
};
const getters = {
}
export default new Vuex.Store({
state,
mutations,
actions,
getters
})
編輯
你發現報了一個這樣的錯誤(Vue.use(Vuex)應該在建立store之前執行),然後仔細檢查了一遍,确認Vue.use(Vuex)寫在了引入store之前。為什麼還報錯呢?這裡我想說的就是Vue在解析代碼的時候,會按順序首先執行所有的import的語句,是以Vue.use(Vuex)隻能寫在store裡面
【報錯】
編輯
文法校驗不過關,在vue.config.js加上這句lintOnSave:false(關閉文法校驗)