多組件共享數(shù)據(jù)
我們現(xiàn)在想實(shí)現(xiàn)這種情況:
Person組件的總?cè)藬?shù)就是Person中列表的長(zhǎng)度
br上的是Count組件,br下的是Person組件。
我們通過(guò)vuex中的state實(shí)現(xiàn)一些數(shù)據(jù)的多組件共享:
代碼實(shí)現(xiàn)
Person.vue
<template>
<div>
<h1>人員列表</h1>
<h3 style="color:red">Count組件求和為:{{sum}}</h3>
<input type="text" placeholder="請(qǐng)輸入名字" 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>
注意點(diǎn):
這里使用了id生成類nanoid,如果要使用先安裝包
yarn add nanoid
或者
npm install nanoid
使用方法:
import { nanoid } from 'nanoid'
const person = {name:'張三', age:18}
// 最后用nanoid給它添加一個(gè)id
person.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT"
Count.vue
<template>
<div>
<h1>當(dāng)前求和為:{{sum}}</h1>
<h3>當(dāng)前求和放大10倍為:{{bigSum}}</h3>
<h3>我在{{school}},學(xué)習(xí){{subject}}</h3>
<h3 style="color:red">Person組件的總?cè)藬?shù)是:{{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)">當(dāng)前求和為奇數(shù)再加</button>
<button @click="incrementWait(n)">等一等再加</button>
</div>
</template>
<script>
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
export default {
name:'Count',
data() {
return {
n:1, //用戶選擇的數(shù)字
}
},
computed:{
//借助mapState生成計(jì)算屬性,從state中讀取數(shù)據(jù)。(數(shù)組寫法)
...mapState(['sum','school','subject','personList']),
//借助mapGetters生成計(jì)算屬性,從getters中讀取數(shù)據(jù)。(數(shù)組寫法)
...mapGetters(['bigSum'])
},
methods: {
//借助mapMutations生成對(duì)應(yīng)的方法,方法中會(huì)調(diào)用commit去聯(lián)系mutations(對(duì)象寫法)
...mapMutations({increment:'JIA',decrement:'JIAN'}),
//借助mapActions生成對(duì)應(yīng)的方法,方法中會(huì)調(diào)用dispatch去聯(lián)系actions(對(duì)象寫法)
...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>
store
//該文件用于創(chuàng)建Vuex中最為核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//應(yīng)用Vuex插件
Vue.use(Vuex)
//準(zhǔn)備actions——用于響應(yīng)組件中的動(dòng)作
const actions = {
/* jia(context,value){
console.log('actions中的jia被調(diào)用了')
context.commit('JIA',value)
},
jian(context,value){
console.log('actions中的jian被調(diào)用了')
context.commit('JIAN',value)
}, */
jiaOdd(context,value){
console.log('actions中的jiaOdd被調(diào)用了')
if(context.state.sum % 2){
context.commit('JIA',value)
}
},
jiaWait(context,value){
console.log('actions中的jiaWait被調(diào)用了')
setTimeout(()=>{
context.commit('JIA',value)
},500)
}
}
//準(zhǔn)備mutations——用于操作數(shù)據(jù)(state)
const mutations = {
JIA(state,value){
console.log('mutations中的JIA被調(diào)用了')
state.sum += value
},
JIAN(state,value){
console.log('mutations中的JIAN被調(diào)用了')
state.sum -= value
},
ADD_PERSON(state,value){
console.log('mutations中的ADD_PERSON被調(diào)用了')
state.personList.unshift(value)
}
}
//準(zhǔn)備state——用于存儲(chǔ)數(shù)據(jù)
const state = {
sum:0, //當(dāng)前的和
school:'尚硅谷',
subject:'前端',
personList:[
{id:'001',name:'張三'}
]
}
//準(zhǔn)備getters——用于將state中的數(shù)據(jù)進(jìn)行加工
const getters = {
bigSum(state){
return state.sum*10
}
}
//創(chuàng)建并暴露store
export default new Vuex.Store({
actions,
mutations,
state,
getters
})
Vuex模塊化
我們查看我們前面的代碼不難發(fā)現(xiàn)一個(gè)問(wèn)題:那就是多個(gè)組件的代碼都放在了唯一的actions、mutations、state、getters中,我們前面的案例中只涉及到了兩個(gè)組件,但是如果我們有幾百個(gè)幾千個(gè)組件,這些代碼全部堆積到一起,會(huì)非常的繁雜。所以我們想對(duì)他進(jìn)行一個(gè)分類,將各組件的代碼分離開來(lái)。
原來(lái)我們是這樣:
現(xiàn)在我們變成這樣:
每個(gè)配置里面都有其各自的actions、mutations、state、getters。
也就是說(shuō)現(xiàn)在的store結(jié)構(gòu)發(fā)生了變化:
當(dāng)然這個(gè)a,b起的有點(diǎn)隨便,我們稍微語(yǔ)義化一下:
因?yàn)榻涌诒┞兜男问桨l(fā)生了變化,接下來(lái)我們的組件里面就要發(fā)生一些變化。
先來(lái)看看Count.vue:
原來(lái)是這樣:
現(xiàn)在變成了這樣:
還有一種方法:
最后我們還有最重要的一步:給配置的命名空間打開。
如果我們?nèi)笔Я诉@一步,這些map的第一個(gè)參數(shù),countAbout、personAbout這些是識(shí)別不出來(lái)的!
computed:{
//借助mapState生成計(jì)算屬性,從state中讀取數(shù)據(jù)。(數(shù)組寫法)
...mapState('countAbout',['sum','school','subject']),
...mapState('personAbout',['personList']),
//借助mapGetters生成計(jì)算屬性,從getters中讀取數(shù)據(jù)。(數(shù)組寫法)
...mapGetters('countAbout',['bigSum'])
},
methods: {
//借助mapMutations生成對(duì)應(yīng)的方法,方法中會(huì)調(diào)用commit去聯(lián)系mutations(對(duì)象寫法)
...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
//借助mapActions生成對(duì)應(yīng)的方法,方法中會(huì)調(diào)用dispatch去聯(lián)系actions(對(duì)象寫法)
...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
},
接下來(lái)我們修改Person.vue,這里我們不使用map方法,而是使用原生的方法看看怎么修改:
我們上面的firstPersonName這樣寫是因?yàn)椋?br> 我們?cè)瓉?lái)store里的state是長(zhǎng)這樣的:
但是現(xiàn)在我們store里的getters是長(zhǎng)這樣的:
也就是他的key變成了這種形式,但是我們?cè)谑褂玫膶?duì)象的屬性的時(shí)候如果使用的是.
這種語(yǔ)法那么這個(gè)/
是不能使用的,憑借js語(yǔ)法的特性我們可以使用[]
語(yǔ)法去訪問(wèn)它的屬性。
最后我們還可以對(duì)最后一次優(yōu)化,那就是把分類后的代碼分文件放置:
我們來(lái)看看這幾個(gè)文件:
count.js
//求和相關(guān)的配置
export default {
namespaced:true,
actions:{
jiaOdd(context,value){
console.log('actions中的jiaOdd被調(diào)用了')
if(context.state.sum % 2){
context.commit('JIA',value)
}
},
jiaWait(context,value){
console.log('actions中的jiaWait被調(diào)用了')
setTimeout(()=>{
context.commit('JIA',value)
},500)
}
},
mutations:{
JIA(state,value){
console.log('mutations中的JIA被調(diào)用了')
state.sum += value
},
JIAN(state,value){
console.log('mutations中的JIAN被調(diào)用了')
state.sum -= value
},
},
state:{
sum:0, //當(dāng)前的和
school:'尚硅谷',
subject:'前端',
},
getters:{
bigSum(state){
return state.sum*10
}
},
}
person.js
//人員管理相關(guān)的配置
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被調(diào)用了')
state.personList.unshift(value)
}
},
state:{
personList:[
{id:'001',name:'張三'}
]
},
getters:{
firstPersonName(state){
return state.personList[0].name
}
},
}
index.js
//該文件用于創(chuàng)建Vuex中最為核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
import countOptions from './count'
import personOptions from './person'
//應(yīng)用Vuex插件
Vue.use(Vuex)
//創(chuàng)建并暴露store
export default new Vuex.Store({
modules:{
countAbout:countOptions,
personAbout:personOptions
}
})
總結(jié)
模塊化+命名空間
-
目的:讓代碼更好維護(hù),讓多種數(shù)據(jù)分類更加明確。
-
修改
store.js
const countAbout = { namespaced:true,//開啟命名空間 state:{x:1}, mutations: { ... }, actions: { ... }, getters: { bigSum(state){ return state.sum * 10 } } } const personAbout = { namespaced:true,//開啟命名空間 state:{ ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { countAbout, personAbout } })
-
開啟命名空間后,組件中讀取state數(shù)據(jù):
//方式一:自己直接讀取 this.$store.state.personAbout.list //方式二:借助mapState讀?。?/span> ...mapState('countAbout',['sum','school','subject']),
-
開啟命名空間后,組件中讀取getters數(shù)據(jù):
//方式一:自己直接讀取 this.$store.getters['personAbout/firstPersonName'] //方式二:借助mapGetters讀取: ...mapGetters('countAbout',['bigSum'])
-
開啟命名空間后,組件中調(diào)用dispatch文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-415394.html
//方式一:自己直接dispatch this.$store.dispatch('personAbout/addPersonWang',person) //方式二:借助mapActions: ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
-
開啟命名空間后,組件中調(diào)用commit文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-415394.html
//方式一:自己直接commit this.$store.commit('personAbout/ADD_PERSON',person) //方式二:借助mapMutations: ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
到了這里,關(guān)于Vuex④(多組件共享數(shù)據(jù)、Vuex模塊化+namespace)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!