第5章:vuex

第5章:vuex

  • 1 求和案例 純vue版
  • 2 vuex工作原理圖
  • 3 vuex案例
    • 3.1 搭建vuex環境
      • 錯誤寫法
      • 正確寫法
    • 3.2 求和案例vuex版
      • 細節分析
      • 源代碼
  • 4 getters配置項
    • 4.1 細節
    • 4.2 源代碼
  • 5 mapState與mapGetters
    • 5.1 總結
    • 5.2 細節分析
    • 5.3 源代碼
  • 6 mapActions與mapMutations
    • 6.1 總結
    • 6.2 細節
    • 6.3 源代碼
  • 7 多組件共享數據
    • 7.1 細節
    • 7.2 源代碼
  • 8 vuex模塊化 + namespace
    • 8.1 總結
    • 8.2 第一部分
      • 細節問題
    • 8.3 第二部分
      • 細節問題
    • 8.4 源代碼

1 求和案例 純vue版

這里只需要住一個問題,就是Count組件的v-model.number=“n”,如果沒有number,這個n就是個字符串。
src/components/Count.vue

<template><div><h1>當前求和為:{{sum}}</h1><select v-model.number="n"><option value="1">1</option><option value="2">2</option><option value="3">3</option></select><button @click="increment">+</button><button @click="decrement">-</button><button @click="incrementOdd">當前求和為奇數再加</button><button @click="incrementWait">等一等再加</button></div>
</template><script>export default {name:'Count',data() {return {n:1, //用戶選擇的數字sum:0 //當前的和}},methods: {increment(){this.sum += this.n},decrement(){this.sum -= this.n},incrementOdd(){if(this.sum % 2){this.sum += this.n}},incrementWait(){setTimeout(()=>{this.sum += this.n},500)},},}
</script><style lang="css">button{margin-left: 5px;}
</style>

src/App.vue

<template><div><Count/></div>
</template><script>import Count from './components/Count'export default {name:'App',components:{Count},}
</script>

src/main.js

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入插件
import vueResource from 'vue-resource'
//關閉Vue的生產提示
Vue.config.productionTip = false
//使用插件
Vue.use(vueResource)//創建vm
new Vue({el:'#app',render: h => h(App),beforeCreate() {Vue.prototype.$bus = this}
})

2 vuex工作原理圖

以求和案例為例,用sum來表示當前的和,vuex會交時state保管,此時sum為0。

  • State是一個Object類型對象,可以存儲很多數據,例如todos,sum等。

接下來過程如下:

  • Count組件調用dispatch,它是一個函數,要傳兩個參數,一個是進行的動作類型,一個是數據,即dispatch(‘jia’,2)。
  • Actions也是一個Object類型對象,此時Actions對象里面必然有一組key value為jia:function,此時函數被調用,就收到了2,function函數里面就會調用commit(‘jia’,2)。
  • Mutations也是一個Object類型對象,此時Mutations對象里面必然有一組key value為jia:function,function會拿到兩個東西,一個是state,一個是2,隨后function里面就寫state.sum += 2即可,然后底層就自動走了Mutate。
  • 最終state里面保存的sum的值就變為了2。
  • vuex會重新解析組件,再重新渲染頁面,于是頁面的sum也變成了2

在這里插入圖片描述
Actions設計的目的是為了和后端交互的,例如dispatch(‘chu’),有動作類型,但沒有所對應的值,此時就要問后端了,后端服務器返回9,如下:
在這里插入圖片描述
如果你并不需要和后端交互,就可以直接和Mutations交互,如下:
在這里插入圖片描述
注意到Devtools即開發者工具是和Mutations進行交互的。

Actions、Mutations和State統一經過一個東西的管理,如下:
在這里插入圖片描述
也就是說調用dispatch等方法時,是由store提供的,如下:
在這里插入圖片描述

3 vuex案例

3.1 搭建vuex環境

2022年2月7日,Vue3已經成為了默認版本,vuex也同時更新到4版本,即執行命令:npm i vuex,安裝的是vuex的4版本,而vuex的4版本只能在vue3使用。

  • Vue2中,要用vuex的3版本,執行命令:npm i vuex@3
  • Vue3中,要用vuex的4版本

錯誤寫法

首先在src下面創建一個store文件夾,如下:
在這里插入圖片描述
index里面代碼如下:
在這里插入圖片描述
緊接著在main.js引入store,由于文件名稱是index.js,所以可以直接省略名字,腳手架認識,如下:
在這里插入圖片描述
此時好像環境搭建完畢,但這樣會出錯,如下:創建store實例之前就要使用Vue.use(Vuex)
在這里插入圖片描述
回到main.js代碼分析,首先得把綠色框文件里得代碼執行完了,我才能收到store,隨后才走粉色框代碼。

  • 這樣就導致了先創建store實例,因為綠色框文件即index.js創建了一個store實例。

在這里插入圖片描述
哪怕換順序也沒用,import語句有優先級,會優先執行,不管順序。

  • 即首先掃描所有import語句,按照import語句代碼順序,全部先執行import語句。
    在這里插入圖片描述

正確寫法

首先在src下面創建一個store文件夾,如下:
在這里插入圖片描述
index里面代碼如下:
在這里插入圖片描述
緊接著在main.js引入store,由于文件名稱是index.js,所以可以直接省略名字,腳手架認識,如下:

在這里插入圖片描述

3.2 求和案例vuex版

細節分析

一般來說共享是由兩個及以上的組件才叫共享,如下:
在這里插入圖片描述
但在這個案例中僅僅使用了Count組件,主要是為了學習vuex的開發流程。

細節一:actions
在這里插入圖片描述
actions中函數的第一個參數是context,稱之為miniStore,其內容如下:
在這里插入圖片描述
actions中函數的第二個參數就是所傳遞的值。
一般commit的時候會大寫JIA,目的是做個區分,一看到大寫JIA,就知道是mutations里的。

細節一:mutations
在這里插入圖片描述
mutations中函數的第一個參數是state,并且進行了加工,加上了get和set,如下:
在這里插入圖片描述
mutations中函數的第二個參數就是所傳遞的值。

細節三
如下所示,綠色框函數要作一些判斷,它是有存在意義的,而紅色框函數沒有任何存在意義,因此刪掉
在這里插入圖片描述
刪掉之后,直接調用commit即可,如下:
在這里插入圖片描述

源代碼

src/components/Count.vue

<template><div><h1>當前求和為:{{$store.state.sum}}</h1><select v-model.number="n"><option value="1">1</option><option value="2">2</option><option value="3">3</option></select><button @click="increment">+</button><button @click="decrement">-</button><button @click="incrementOdd">當前求和為奇數再加</button><button @click="incrementWait">等一等再加</button></div>
</template><script>export default {name:'Count',data() {return {n:1, //用戶選擇的數字}},methods: {increment(){this.$store.commit('JIA',this.n)},decrement(){this.$store.commit('JIAN',this.n)},incrementOdd(){this.$store.dispatch('jiaOdd',this.n)},incrementWait(){this.$store.dispatch('jiaWait',this.n)},},mounted() {console.log('Count',this)},}
</script><style lang="css">button{margin-left: 5px;}
</style>

src/store/index.js

//該文件用于創建Vuex中最為核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//應用Vuex插件
Vue.use(Vuex)//準備actions——用于響應組件中的動作
const actions = {/* jia(context,value){console.log('actions中的jia被調用了')context.commit('JIA',value)},jian(context,value){console.log('actions中的jian被調用了')context.commit('JIAN',value)}, */jiaOdd(context,value){console.log('actions中的jiaOdd被調用了')if(context.state.sum % 2){context.commit('JIA',value)}},jiaWait(context,value){console.log('actions中的jiaWait被調用了')setTimeout(()=>{context.commit('JIA',value)},500)}
}
//準備mutations——用于操作數據(state)
const mutations = {JIA(state,value){console.log('mutations中的JIA被調用了')state.sum += value},JIAN(state,value){console.log('mutations中的JIAN被調用了')state.sum -= value}
}
//準備state——用于存儲數據
const state = {sum:0 //當前的和
}//創建并暴露store
export default new Vuex.Store({actions,mutations,state,
})

src/App.vue

<template><div><Count/></div>
</template><script>import Count from './components/Count'export default {name:'App',components:{Count},mounted() {// console.log('App',this)},}
</script>

src/main.js

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入插件
import vueResource from 'vue-resource'
//引入store
import store from './store'//關閉Vue的生產提示
Vue.config.productionTip = false
//使用插件
Vue.use(vueResource)//創建vm
new Vue({el:'#app',render: h => h(App),store,beforeCreate() {Vue.prototype.$bus = this}
})

4 getters配置項

4.1 細節

當前有一個新需求:還要顯示當前求和放大十倍后的結果。

最好不要像如下這樣寫,考慮一下,假設程序員要對state的sum進行一些加工,而且是一些很復雜的數學運算,而且很多程序員要使用這樣的功能,這樣就不適合像如下這樣寫。

  • 使用計算屬性也不行,它不能跨組件

在這里插入圖片描述
直接在store的index文件夾進行配置,如下:

  • state就如同data,而getters就如同computed一樣

在這里插入圖片描述
組件中讀取數據:$store.getters.bigSum。直接看代碼即可

4.2 源代碼

在求和案例vuex版基礎上,要修改的代碼有:
src/components/Count.vue

<template><div><h1>當前求和為:{{$store.state.sum}}</h1><h3>當前求和放大10倍為:{{$store.getters.bigSum}}</h3><select v-model.number="n"><option value="1">1</option><option value="2">2</option><option value="3">3</option></select><button @click="increment">+</button><button @click="decrement">-</button><button @click="incrementOdd">當前求和為奇數再加</button><button @click="incrementWait">等一等再加</button></div>
</template><script>export default {name:'Count',data() {return {n:1, //用戶選擇的數字}},methods: {increment(){this.$store.commit('JIA',this.n)},decrement(){this.$store.commit('JIAN',this.n)},incrementOdd(){this.$store.dispatch('jiaOdd',this.n)},incrementWait(){this.$store.dispatch('jiaWait',this.n)},},mounted() {console.log('Count',this.$store)},}
</script><style lang="css">button{margin-left: 5px;}
</style>

src/store/index.js

//該文件用于創建Vuex中最為核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//應用Vuex插件
Vue.use(Vuex)//準備actions——用于響應組件中的動作
const actions = {/* jia(context,value){console.log('actions中的jia被調用了')context.commit('JIA',value)},jian(context,value){console.log('actions中的jian被調用了')context.commit('JIAN',value)}, */jiaOdd(context,value){console.log('actions中的jiaOdd被調用了')if(context.state.sum % 2){context.commit('JIA',value)}},jiaWait(context,value){console.log('actions中的jiaWait被調用了')setTimeout(()=>{context.commit('JIA',value)},500)}
}
//準備mutations——用于操作數據(state)
const mutations = {JIA(state,value){console.log('mutations中的JIA被調用了')state.sum += value},JIAN(state,value){console.log('mutations中的JIAN被調用了')state.sum -= value}
}
//準備state——用于存儲數據
const state = {sum:0 //當前的和
}
//準備getters——用于將state中的數據進行加工
const getters = {bigSum(state){return state.sum*10}
}//創建并暴露store
export default new Vuex.Store({actions,mutations,state,getters
})

5 mapState與mapGetters

5.1 總結

在這里插入圖片描述

5.2 細節分析

我們多配置兩個數據,分別為school和subject,如下:當使用state的很多數據時候,會多次調用store.state.xxx,這樣很麻煩。
在這里插入圖片描述
最簡單的方式是用計算屬性解決,但是要程序員一次一次的配置,也會很麻煩。
在這里插入圖片描述
vuex的設計者提供了mapState方法,它可以幫我們批量生成粉色框的代碼,因為它們共同點都是從state讀取數據。
在這里插入圖片描述
首先要引入mapState,如下:在這里插入圖片描述
看看mapState輸出是什么
比如要生成state的sum相對應函數,如下:
在這里插入圖片描述
我們可以寫簡寫形式,即前面的’he’去掉’',但sum不行,它是一個表達式,其余的也同理,如下:

在這里插入圖片描述
輸出x,可以看到,它為我們生成了函數,如下:
在這里插入圖片描述
在computed里面配置mapstate
在這里插入圖片描述
我們會發現,像上述這樣配置,會發生報錯,這是因為mapState本身是一個對象,computed又是對象,不可能直接在對象里面寫對象。
在對象里面寫對象的方法
先看一個例子

直接在對象前面加三個點,意思是把obj2里面的每一組key和value展開放入到obj里面
在這里插入圖片描述
最終輸出如下:
在這里插入圖片描述

因此我們要在mapState加三個點,如下:
在這里插入圖片描述

還有一種數組寫法,并且要求同名,如下:
在這里插入圖片描述
由于同名可以簡寫,簡寫的時候必須要’',以sum:'sum’為例,如果簡寫成sum,最終含義就是sum:sum,進而去讀取sum變量,這就報錯了。

舉個例子,只有是變量的時候,簡寫才能直接不要’‘,如下:
由于a是變量,所以簡寫不需要’’
在這里插入圖片描述
所以最終簡寫形式如下:
在這里插入圖片描述
對于getters同理也有mapGetters,一樣的用法,直接看代碼即可。

5.3 源代碼

在求和案例vuex版基礎上,要修改的代碼有:
src/components/Count.vue

<template><div><h1>當前求和為:{{sum}}</h1><h3>當前求和放大10倍為:{{bigSum}}</h3><h3>我在{{school}},學習{{subject}}</h3><select v-model.number="n"><option value="1">1</option><option value="2">2</option><option value="3">3</option></select><button @click="increment">+</button><button @click="decrement">-</button><button @click="incrementOdd">當前求和為奇數再加</button><button @click="incrementWait">等一等再加</button></div>
</template><script>import {mapState,mapGetters} from 'vuex'export default {name:'Count',data() {return {n:1, //用戶選擇的數字}},computed:{//靠程序員自己親自去寫計算屬性/* sum(){return this.$store.state.sum},school(){return this.$store.state.school},subject(){return this.$store.state.subject}, *///借助mapState生成計算屬性,從state中讀取數據。(對象寫法)// ...mapState({he:'sum',xuexiao:'school',xueke:'subject'}),//借助mapState生成計算屬性,從state中讀取數據。(數組寫法)...mapState(['sum','school','subject']),/* ******************************************************************** *//* bigSum(){return this.$store.getters.bigSum}, *///借助mapGetters生成計算屬性,從getters中讀取數據。(對象寫法)// ...mapGetters({bigSum:'bigSum'})//借助mapGetters生成計算屬性,從getters中讀取數據。(數組寫法)...mapGetters(['bigSum'])},methods: {increment(){this.$store.commit('JIA',this.n)},decrement(){this.$store.commit('JIAN',this.n)},incrementOdd(){this.$store.dispatch('jiaOdd',this.n)},incrementWait(){this.$store.dispatch('jiaWait',this.n)},},mounted() {const x = mapState({he:'sum',xuexiao:'school',xueke:'subject'})console.log(x)},}
</script><style lang="css">button{margin-left: 5px;}
</style>

src/store/index.js

//該文件用于創建Vuex中最為核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//應用Vuex插件
Vue.use(Vuex)//準備actions——用于響應組件中的動作
const actions = {/* jia(context,value){console.log('actions中的jia被調用了')context.commit('JIA',value)},jian(context,value){console.log('actions中的jian被調用了')context.commit('JIAN',value)}, */jiaOdd(context,value){console.log('actions中的jiaOdd被調用了')if(context.state.sum % 2){context.commit('JIA',value)}},jiaWait(context,value){console.log('actions中的jiaWait被調用了')setTimeout(()=>{context.commit('JIA',value)},500)}
}
//準備mutations——用于操作數據(state)
const mutations = {JIA(state,value){console.log('mutations中的JIA被調用了')state.sum += value},JIAN(state,value){console.log('mutations中的JIAN被調用了')state.sum -= value}
}
//準備state——用于存儲數據
const state = {sum:0, //當前的和school:'尚硅谷',subject:'前端'
}
//準備getters——用于將state中的數據進行加工
const getters = {bigSum(state){return state.sum*10}
}//創建并暴露store
export default new Vuex.Store({actions,mutations,state,getters
})

6 mapActions與mapMutations

6.1 總結

在這里插入圖片描述

6.2 細節

我們需要優化的是方法,如下:
在這里插入圖片描述
首先使用mapMutations修改,如下:
在這里插入圖片描述
但當點擊+1之后,發生如下錯誤:
在這里插入圖片描述
我們讓JIA輸出value看看什么情況,如下:
在這里插入圖片描述
可以看到,這個value是一個事件,如下:
在這里插入圖片描述
可以看到,mapMutations生成的函數,需要傳遞參數。
在這里插入圖片描述
可以看到,我們調用函數時,并沒有傳遞參數,所以默認傳的參數是event,如下:
在這里插入圖片描述
因此在調用函數時,要傳入參數,如下:
在這里插入圖片描述
如果不想在函數里面傳參,還可以用下面這個方法(但我覺得復雜了):
在這里插入圖片描述
我們采取函數傳參的方法,此時mapMutations還可以使用數組方法,并使用簡寫形式,如下:
在這里插入圖片描述
此時調用函數處為:
在這里插入圖片描述
mapActions同理,不再過多說明,直接看源代碼。

6.3 源代碼

在求和案例vuex版基礎上,要修改的代碼有:
src/components/Count.vue

<template><div><h1>當前求和為:{{sum}}</h1><h3>當前求和放大10倍為:{{bigSum}}</h3><h3>我在{{school}},學習{{subject}}</h3><select v-model.number="n"><option value="1">1</option><option value="2">2</option><option value="3">3</option></select><button @click="increment(n)">+</button><button @click="decrement(n)">-</button><button @click="incrementOdd(n)">當前求和為奇數再加</button><button @click="incrementWait(n)">等一等再加</button></div>
</template><script>import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'export default {name:'Count',data() {return {n:1, //用戶選擇的數字}},computed:{//借助mapState生成計算屬性,從state中讀取數據。(對象寫法)// ...mapState({he:'sum',xuexiao:'school',xueke:'subject'}),//借助mapState生成計算屬性,從state中讀取數據。(數組寫法)...mapState(['sum','school','subject']),/* ******************************************************************** *///借助mapGetters生成計算屬性,從getters中讀取數據。(對象寫法)// ...mapGetters({bigSum:'bigSum'})//借助mapGetters生成計算屬性,從getters中讀取數據。(數組寫法)...mapGetters(['bigSum'])},methods: {//程序員親自寫方法/* increment(){this.$store.commit('JIA',this.n)},decrement(){this.$store.commit('JIAN',this.n)}, *///借助mapMutations生成對應的方法,方法中會調用commit去聯系mutations(對象寫法)...mapMutations({increment:'JIA',decrement:'JIAN'}),//借助mapMutations生成對應的方法,方法中會調用commit去聯系mutations(數組寫法)// ...mapMutations(['JIA','JIAN']),/* ************************************************* *///程序員親自寫方法/* incrementOdd(){this.$store.dispatch('jiaOdd',this.n)},incrementWait(){this.$store.dispatch('jiaWait',this.n)}, *///借助mapActions生成對應的方法,方法中會調用dispatch去聯系actions(對象寫法)...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})//借助mapActions生成對應的方法,方法中會調用dispatch去聯系actions(數組寫法)// ...mapActions(['jiaOdd','jiaWait'])},mounted() {const x = mapState({he:'sum',xuexiao:'school',xueke:'subject'})console.log(x)},}
</script><style lang="css">button{margin-left: 5px;}
</style>

src/store/index.js

//該文件用于創建Vuex中最為核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//應用Vuex插件
Vue.use(Vuex)//準備actions——用于響應組件中的動作
const actions = {/* jia(context,value){console.log('actions中的jia被調用了')context.commit('JIA',value)},jian(context,value){console.log('actions中的jian被調用了')context.commit('JIAN',value)}, */jiaOdd(context,value){console.log('actions中的jiaOdd被調用了')if(context.state.sum % 2){context.commit('JIA',value)}},jiaWait(context,value){console.log('actions中的jiaWait被調用了')setTimeout(()=>{context.commit('JIA',value)},500)}
}
//準備mutations——用于操作數據(state)
const mutations = {JIA(state,value){console.log('mutations中的JIA被調用了')state.sum += value},JIAN(state,value){console.log('mutations中的JIAN被調用了')state.sum -= value}
}
//準備state——用于存儲數據
const state = {sum:0, //當前的和school:'尚硅谷',subject:'前端'
}
//準備getters——用于將state中的數據進行加工
const getters = {bigSum(state){return state.sum*10}
}//創建并暴露store
export default new Vuex.Store({actions,mutations,state,getters
})

7 多組件共享數據

7.1 細節

看如下需求:sum和persons可以同時共享
在這里插入圖片描述
細節一
首先是創建Person組件,并在App引入。
緊接著在vuex添加person數據,如下:
在這里插入圖片描述
緊接著在Person組件引入數據,如下:

  • 這里有兩種寫法,但我們使用紅色框的寫法,如果我們使用綠色框的寫法,就避免了一個問題,不利于學習
  • 因此在Person組件不使用簡寫方式,而在Count組件使用簡寫方式,這樣利于學習

在這里插入圖片描述
細節二
現在看看PersonList是怎么進行共享的,先看Count組件,借助mapState讀取。
在這里插入圖片描述
而Person組件是利用計算屬性讀取的,如下:
在這里插入圖片描述
sum屬性也同理,可以去看看。

7.2 源代碼

在求和案例vuex版基礎上,要修改的代碼有:
src/components/Count.vue

<template><div><h1>當前求和為:{{sum}}</h1><h3>當前求和放大10倍為:{{bigSum}}</h3><h3>我在{{school}},學習{{subject}}</h3><h3 style="color:red">Person組件的總人數是:{{personList.length}}</h3><select v-model.number="n"><option value="1">1</option><option value="2">2</option><option value="3">3</option></select><button @click="increment(n)">+</button><button @click="decrement(n)">-</button><button @click="incrementOdd(n)">當前求和為奇數再加</button><button @click="incrementWait(n)">等一等再加</button></div>
</template><script>import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'export default {name:'Count',data() {return {n:1, //用戶選擇的數字}},computed:{//借助mapState生成計算屬性,從state中讀取數據。(數組寫法)...mapState(['sum','school','subject','personList']),//借助mapGetters生成計算屬性,從getters中讀取數據。(數組寫法)...mapGetters(['bigSum'])},methods: {//借助mapMutations生成對應的方法,方法中會調用commit去聯系mutations(對象寫法)...mapMutations({increment:'JIA',decrement:'JIAN'}),//借助mapActions生成對應的方法,方法中會調用dispatch去聯系actions(對象寫法)...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})},mounted() {// const x = mapState({he:'sum',xuexiao:'school',xueke:'subject'})// console.log(x)},}
</script><style lang="css">button{margin-left: 5px;}
</style>

src/components/Person.vue

<template><div><h1>人員列表</h1><h3 style="color:red">Count組件求和為:{{sum}}</h3><input type="text" placeholder="請輸入名字" v-model="name"><button @click="add">添加</button><ul><li v-for="p in personList" :key="p.id">{{p.name}}</li></ul></div>
</template><script>import {nanoid} from 'nanoid'export default {name:'Person',data() {return {name:''}},computed:{personList(){return this.$store.state.personList},sum(){return this.$store.state.sum}},methods: {add(){const personObj = {id:nanoid(),name:this.name}this.$store.commit('ADD_PERSON',personObj)this.name = ''}},}
</script>

src/store/index.js

//該文件用于創建Vuex中最為核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//應用Vuex插件
Vue.use(Vuex)//準備actions——用于響應組件中的動作
const actions = {/* jia(context,value){console.log('actions中的jia被調用了')context.commit('JIA',value)},jian(context,value){console.log('actions中的jian被調用了')context.commit('JIAN',value)}, */jiaOdd(context,value){console.log('actions中的jiaOdd被調用了')if(context.state.sum % 2){context.commit('JIA',value)}},jiaWait(context,value){console.log('actions中的jiaWait被調用了')setTimeout(()=>{context.commit('JIA',value)},500)}
}
//準備mutations——用于操作數據(state)
const mutations = {JIA(state,value){console.log('mutations中的JIA被調用了')state.sum += value},JIAN(state,value){console.log('mutations中的JIAN被調用了')state.sum -= value},ADD_PERSON(state,value){console.log('mutations中的ADD_PERSON被調用了')state.personList.unshift(value)}
}
//準備state——用于存儲數據
const state = {sum:0, //當前的和school:'尚硅谷',subject:'前端',personList:[{id:'001',name:'張三'}]
}
//準備getters——用于將state中的數據進行加工
const getters = {bigSum(state){return state.sum*10}
}//創建并暴露store
export default new Vuex.Store({actions,mutations,state,getters
})

src/App.vue

<template><div><Count/><hr><Person/></div>
</template><script>import Count from './components/Count'import Person from './components/Person'export default {name:'App',components:{Count,Person},mounted() {// console.log('App',this)},}
</script>

8 vuex模塊化 + namespace

8.1 總結

在這里插入圖片描述在這里插入圖片描述

8.2 第一部分

細節問題

細節一 配置store
一開始我們是怎么配置store的,如下:
在這里插入圖片描述
但現在有個問題,以mutation為例,假設是一個電商系統,我們已經實現了求和模塊、人員模塊,那還要繼續寫訂單模塊,商品模塊等,這樣mutation內容就很多了,很難維護,還有就是所有程序員都操作一個mutation,也容易造成git版本控制沖突。
在這里插入圖片描述
因此分類整理,相當于分別管理求和的store和人員的store,如下:
在這里插入圖片描述
緊接著使用配置,如下:
在這里插入圖片描述
還可以使用簡寫形式,如下:
在這里插入圖片描述

細節二 Count組件讀取store
由于是初學者,暴露時不使用簡寫形式,便于學習,如下:
在這里插入圖片描述
mapstate
第一種讀取數據方式如下,會發現比較復雜,如下:
在這里插入圖片描述
第二種就是利用mapstate的語法,先不管personList,如下:
在這里插入圖片描述
但這樣寫會報錯,因為沒使用namespace,所以要加上,如下:當添加上namespace后,就可以了。
在這里插入圖片描述
接下來考慮personList(也要加上namespace)如下:
在這里插入圖片描述
mapmutation mapaction mapgetters
同理,如下:
在這里插入圖片描述

8.3 第二部分

細節問題

細節一 Person組件讀取store
之前Person組件不使用簡寫方式,就是因為在這里要學習不使用map方法時如何讀取store。

讀取state
可以看到,用如下的讀取方式:
在這里插入圖片描述
commit
不用簡寫形式調用Mutations時使用commit,在這里的語法形式如下:
在這里插入圖片描述
增加一些功能
我們還需要練習getters和dispatch的調用方法,因此在actions和getters上添加一些功能。如下:
在這里插入圖片描述
getters
在內容添加firstPersonName,如下:
在這里插入圖片描述
因此需要使用計算屬性,這里的寫法很獨特。
這里有一個方法,就是輸出store看看它究竟是什么寫法,如下:
在這里插入圖片描述
所以應該這樣寫,如下:
在這里插入圖片描述

dispatch
在這里插入圖片描述
然后調用dispatch,和getters類似的寫法,如下:
在這里插入圖片描述

細節二 store配置管理問題
直接將person和count拆分管理,如下:
在這里插入圖片描述
然后在index里面引入就行,如下:在這里插入圖片描述

細節三 發請求
在person中添加actions,這個api可以返回一個小語錄,這個小語錄作為名字,如下:
在這里插入圖片描述

緊接著在person組件配置,如下:
在這里插入圖片描述
在這里插入圖片描述

8.4 源代碼

在求和案例vuex版基礎上,要修改的代碼有:
src/components/Count.vue

<template><div><h1>當前求和為:{{sum}}</h1><h3>當前求和放大10倍為:{{bigSum}}</h3><h3>我在{{school}},學習{{subject}}</h3><h3 style="color:red">Person組件的總人數是:{{personList.length}}</h3><select v-model.number="n"><option value="1">1</option><option value="2">2</option><option value="3">3</option></select><button @click="increment(n)">+</button><button @click="decrement(n)">-</button><button @click="incrementOdd(n)">當前求和為奇數再加</button><button @click="incrementWait(n)">等一等再加</button></div>
</template><script>import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'export default {name:'Count',data() {return {n:1, //用戶選擇的數字}},computed:{//借助mapState生成計算屬性,從state中讀取數據。(數組寫法)...mapState('countAbout',['sum','school','subject']),...mapState('personAbout',['personList']),//借助mapGetters生成計算屬性,從getters中讀取數據。(數組寫法)...mapGetters('countAbout',['bigSum'])},methods: {//借助mapMutations生成對應的方法,方法中會調用commit去聯系mutations(對象寫法)...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),//借助mapActions生成對應的方法,方法中會調用dispatch去聯系actions(對象寫法)...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})},mounted() {console.log(this.$store)},}
</script><style lang="css">button{margin-left: 5px;}
</style>

src/components/Person.vue

<template><div><h1>人員列表</h1><h3 style="color:red">Count組件求和為:{{sum}}</h3><h3>列表中第一個人的名字是:{{firstPersonName}}</h3><input type="text" placeholder="請輸入名字" v-model="name"><button @click="add">添加</button><button @click="addWang">添加一個姓王的人</button><button @click="addPersonServer">添加一個人,名字隨機</button><ul><li v-for="p in personList" :key="p.id">{{p.name}}</li></ul></div>
</template><script>import {nanoid} from 'nanoid'export default {name:'Person',data() {return {name:''}},computed:{personList(){return this.$store.state.personAbout.personList},sum(){return this.$store.state.countAbout.sum},firstPersonName(){return this.$store.getters['personAbout/firstPersonName']}},methods: {add(){const personObj = {id:nanoid(),name:this.name}this.$store.commit('personAbout/ADD_PERSON',personObj)this.name = ''},addWang(){const personObj = {id:nanoid(),name:this.name}this.$store.dispatch('personAbout/addPersonWang',personObj)this.name = ''},addPersonServer(){this.$store.dispatch('personAbout/addPersonServer')}},}
</script>

src/store/count.js

//求和相關的配置
export default {namespaced:true,actions:{jiaOdd(context,value){console.log('actions中的jiaOdd被調用了')if(context.state.sum % 2){context.commit('JIA',value)}},jiaWait(context,value){console.log('actions中的jiaWait被調用了')setTimeout(()=>{context.commit('JIA',value)},500)}},mutations:{JIA(state,value){console.log('mutations中的JIA被調用了')state.sum += value},JIAN(state,value){console.log('mutations中的JIAN被調用了')state.sum -= value},},state:{sum:0, //當前的和school:'尚硅谷',subject:'前端',},getters:{bigSum(state){return state.sum*10}},
}

src/store/index.js

//該文件用于創建Vuex中最為核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
import countOptions from './count'
import personOptions from './person'
//應用Vuex插件
Vue.use(Vuex)//創建并暴露store
export default new Vuex.Store({modules:{countAbout:countOptions,personAbout:personOptions}
})

src/store/person.js

//人員管理相關的配置
import axios from 'axios'
import { nanoid } from 'nanoid'
export default {namespaced:true,actions:{addPersonWang(context,value){if(value.name.indexOf('王') === 0){context.commit('ADD_PERSON',value)}else{alert('添加的人必須姓王!')}},addPersonServer(context){axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(response => {context.commit('ADD_PERSON',{id:nanoid(),name:response.data})},error => {alert(error.message)})}},mutations:{ADD_PERSON(state,value){console.log('mutations中的ADD_PERSON被調用了')state.personList.unshift(value)}},state:{personList:[{id:'001',name:'張三'}]},getters:{firstPersonName(state){return state.personList[0].name}},
}

src/App.vue

<template><div><Count/><hr><Person/></div>
</template><script>import Count from './components/Count'import Person from './components/Person'export default {name:'App',components:{Count,Person},mounted() {// console.log('App',this)},}
</script>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/897081.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/897081.shtml
英文地址,請注明出處:http://en.pswp.cn/news/897081.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

迷你世界腳本對象庫接口:ObjectLib

對象庫接口&#xff1a;ObjectLib 迷你世界 更新時間: 2023-04-26 20:21:09 具體函數名及描述如下: 序號 函數名 函數描述 1 getAreaData(...) 獲取區域數據 2 getPositionData(...) 獲取位置數據 3 getLivingData(...) 獲取生物數據 4 getItemDat…

測試是如何跟進和管理 bug

測試在跟進和管理 Bug定位精確、問題反饋及時、修復閉環高效 三大關鍵環節中起到了至關重要的作用。Bug定位精確 是整個流程的基礎&#xff0c;通過詳細記錄和復現問題&#xff0c;可以幫助開發團隊迅速找出缺陷根源&#xff1b;而及時有效的反饋機制則確保問題不會被遺漏&…

運動控制卡--固高實用

目錄 組件 配置參數 編程控制 組件 我手頭有固高卡&#xff0c;記錄使用。 用運動控制卡 伺服&#xff08;步進&#xff09;電機搭建一個運動控制系統&#xff0c;主要包括&#xff1a;1、控制器 2、端子板 1、控制器 2、端子板 3、伺服&#xff08;步進&#xff09;…

2025年能源工作指導意見

2025年是“十四五”規劃收官之年&#xff0c;做好全年能源工作意義重大。為深入貫徹落實黨中央、國務院決策部署&#xff0c;以能源高質量發展和高水平安全助力我國經濟持續回升向好&#xff0c;滿足人民群眾日益增長的美好生活用能需求&#xff0c;制定本意見。 一、總體要求…

鍵值對(C++實現)

目錄 鍵值對的定義 鍵值對的底層實現 鍵值對的作用 鍵值對的使用 對鍵值對中的值的搜索 一、鍵值對的定義 鍵值對&#xff08;Key-Value Pair&#xff09;是一種數據結構&#xff0c;用于存儲和表示兩個相關聯的值。在鍵值對中&#xff0c;一個值被關聯到一個唯一的鍵上&…

使用 Docker 部署 RabbitMQ 并實現數據持久化

非常好&#xff01;以下是一份完整的 Docker 部署 RabbitMQ 的博客文檔&#xff0c;包含從安裝到問題排查的詳細步驟。你可以直接將其發布到博客中。 使用 Docker 部署 RabbitMQ 并實現數據持久化 RabbitMQ 是一個開源的消息隊列系統&#xff0c;廣泛應用于分布式系統中。使用…

springboot429-基于springboot的教務管理系統(源碼+數據庫+純前后端分離+部署講解等)

&#x1f495;&#x1f495;作者&#xff1a; 愛笑學姐 &#x1f495;&#x1f495;個人簡介&#xff1a;十年Java&#xff0c;Python美女程序員一枚&#xff0c;精通計算機專業前后端各類框架。 &#x1f495;&#x1f495;各類成品Java畢設 。javaweb&#xff0c;ssm&#xf…

my學習網址

文章目錄 1.軟件版本管控GIT學習網站大全1官方文檔類2在線教程類3互動學習類4問答社區類 Linux學習網址1、 Linux命令行與shell腳本編程大全 1.軟件版本管控 GIT學習網站大全 廖雪峰網站 以下為你推薦不同類型的學習Git的網站&#xff1a; 1官方文檔類 Git官方文檔 網址&am…

Best practice-生產環境中加鎖的最佳實踐

什么是死鎖&#xff1f; 場景&#xff1a;圖書館有兩個相鄰的儲物柜&#xff08;柜子A和柜子B&#xff09;&#xff0c;小明和小紅需要同時使用這兩個柜子才能完成借書流程。 互斥資源 每個柜子只有一把鑰匙&#xff0c;且一次只能被一人使用&#xff08;資源不可共享&#x…

極狐GitLab 17.9 正式發布,40+ DevSecOps 重點功能解讀【四】

GitLab 是一個全球知名的一體化 DevOps 平臺&#xff0c;很多人都通過私有化部署 GitLab 來進行源代碼托管。極狐GitLab 是 GitLab 在中國的發行版&#xff0c;專門為中國程序員服務。可以一鍵式部署極狐GitLab。 學習極狐GitLab 的相關資料&#xff1a; 極狐GitLab 官網極狐…

黃昏時間戶外街拍人像Lr調色教程,手機濾鏡PS+Lightroom預設下載!

調色介紹 黃昏時分有著獨特而迷人的光線&#xff0c;使此時拍攝的人像自帶一種浪漫、朦朧的氛圍 。通過 Lr 調色&#xff0c;可以進一步強化這種特質并根據不同的風格需求進行創作。Lr&#xff08;Lightroom&#xff09;作為專業的圖像后期處理軟件&#xff0c;提供了豐富的調色…

Spring Boot 項目中 Redis 常見問題及解決方案

目錄 緩存穿透緩存雪崩緩存擊穿Redis 連接池耗盡Redis 序列化問題總結 1. 緩存穿透 問題描述 緩存穿透是指查詢一個不存在的數據&#xff0c;由于緩存中沒有該數據&#xff0c;請求會直接打到數據庫上&#xff0c;導致數據庫壓力過大。 解決方案 緩存空值&#xff1a;即使…

信息系統項目管理師--整合管理

信息系統項目管理師–整合管理

關于tomcat使用中瀏覽器打開index.jsp后中文顯示不正常是亂碼,但英文正常的問題

如果是jsp文件就在首行加 “<% page language"java" contentType"text/html; charsetUTF-8" pageEncoding"UTF-8" %>” 如果是html文件 在head標簽加入&#xff1a; <meta charset"UTF-8"> 以jsp為例子&#xff0c;我們…

微服務的春天:基于Spring Boot的架構設計與實踐

微服務的春天:基于Spring Boot的架構設計與實踐 在如今的技術領域,微服務架構儼然成為了解決復雜系統開發與運維挑戰的關鍵利器。作為一名資深運維和自媒體創作者,筆名Echo_Wish,我將深入探討基于Spring Boot的微服務架構設計,結合實例代碼說明觀點,希望能為大家帶來啟發…

JVM參數調整

一、內存相關參數 1. 堆內存控制 -Xmx&#xff1a;最大堆內存&#xff08;如 -Xmx4g&#xff0c;默認物理內存1/4&#xff09;。-Xms&#xff1a;初始堆內存&#xff08;建議與-Xmx相等&#xff0c;避免動態擴容帶來的性能波動&#xff09;。-Xmn&#xff1a;新生代大小&…

AVM 環視拼接 魚眼相機

https://zhuanlan.zhihu.com/p/651306620 AVM 環視拼接方法介紹 從內外參推導IPM變換方程及代碼實現&#xff08;生成AVM環視拼接圖&#xff09;_avm拼接-CSDN博客 經典文獻閱讀之--Extrinsic Self-calibration of the Surround-view System: A Weakly... (環視系統的外參自…

【哇! C++】類和對象(三) - 構造函數和析構函數

目錄 一、構造函數 1.1 構造函數的引入 1.2 構造函數的定義和語法 1.2.1 無參構造函數&#xff1a; 1.2.2 帶參構造函數 1.3 構造函數的特性 1.4 默認構造函數 二、析構函數 2.1 析構函數的概念 2.2 特性 如果一個類中什么成員都沒有&#xff0c;簡稱為空類。 空類中…

【五.LangChain技術與應用】【11.LangChain少樣本案例模板:小數據下的AI訓練】

深夜的創業孵化器里,你盯著屏幕上的醫療AI項目,手里攥著僅有的97條標注數據——這是某三甲醫院心內科攢了三年的罕見病例。投資人剛剛發來最后通牒:“下周demo要是還分不清心肌炎和感冒,就撤資!” 這時你需要掌握的不是更多數據,而是讓每個樣本都變成會復制的孫悟空的毫毛…

2005-2019年各省城鎮人口數據

2005-2019年各省城鎮人口數據 1、時間&#xff1a;2005-2019年 2、來源&#xff1a;國家統計局、統計年鑒 3、指標&#xff1a;地區、年份、城鎮人口(萬人) 4、范圍&#xff1a;31省 5、指標解釋&#xff1a;?城鎮人口是指居住在城市、集鎮的人口&#xff0c;主要依據人群…