文章目录
多组件共享数据(vuex版)
本例有两个组件,分别是,
- Count组件,详见Count.vue。
- Person组件,详见Person.vue。
Count组件和Person组件共享以下两个数据:
sum
personList
代码主要涉及如下3个文件,
- main.js,本例中不涉及变更。
- App.vue,本例不涉及变更。
- store/index.js,本例中,会发生多次变更。
- Person.vue,本例中,会发生多次变更。
- Count.vue,本例中,会发生多次变更。
main.js
import Vue from 'vue'
import App from './App.vue'
import store from "./store";
Vue.config.productionTip = false
const vm = new Vue({
render: h => h(App),
store
}).$mount('#app');
console.log(vm);
App.vue
<template>
<div id="app">
<Count/>
<hr>
<Person/>
</div>
</template>
<script>
import Count from './components/Count.vue';
import Person from './components/Person.vue';
export default {
name: 'App',
components: {
Count,
Person
}
}
</script>
store/index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const state = {
sum:0,
personList:[
{id:"001",name:"张三"}
]
};
const getters = {
bigSum(state){
return state.sum*10;
}
}
const actions = {
jiaOdd(context,value){
if(context.state.sum % 2){
context.commit("JIA",value);
}
},
jiaWait(context,value){
setTimeout(() => {
context.commit("JIA",value);
},500)
}
};
const mutations = {
JIA(state,value){
state.sum += value;
},
JIAN(state,value){
state.sum -= value;
},
ADD_PERSON(state,personObj){
state.personList.unshift(personObj);
}
};
export default new Vuex.Store({
state,
getters,
actions,
mutations
})
Person.vue
<template>
<div>
<h2>人员列表</h2>
<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>
<style scoped>
button{
margin-left: 5px;
}
</style>
Count.vue
<template>
<div class="count">
<h2>当前求和为{{sum}}</h2>
<h2>当前求和放大10倍为{{bigSum}}</h2>
<h3 style="color:red">Person组件的总人数为{{personList.length}}</h3>
<select v-model="num">
<option :value="1">1</option>
<option :value="2">2</option>
<option :value="3">3</option>
</select>
<button @click="increment(num)">+</button>
<button @click="decrement(num)">-</button>
<button @click="incrementOdd(num)">和为奇数时再加</button>
<button @click="incrementWait(num)"> 等一等再加</button>
</div>
</template>
<script>
import {mapState,mapGetters,mapActions,mapMutations} from "vuex";
export default {
name: 'Count',
data(){
return {
num:1
}
},
computed:{
...mapState(["sum","company","position","personList"]),
...mapGetters(["bigSum"])
},
methods: {
...mapActions({
incrementOdd:"jiaOdd",
incrementWait:"jiaWait"
}),
...mapMutations({
increment:"JIA",
decrement:"JIAN"
})
}
}
</script>
<style scoped>
button{
margin-left: 5px;
}
</style>
vuex的模块化
-
getters,照旧,不分模块。
this.$store.getters.bigSum
(✔)
(×)this.$store.getters.countAbout.bigSum
mapGetters(["bigSum"])
(✔) -
state,分模块。
this.$store.state.countAbout.sum
(✔)
this.$store.state.personAbout.personList
(✔)mapState({sum:state=>state.countAbout.sum,personList:state=>state.personAbout.personList})
(对象写法)(✔)mapState(["countAbout","personAbout"])
(数组写法)(✔) -
actions,照旧,不分模块。
incrementOdd(){ this.$store.dispatch("jiaOdd",this.num); }
(✔)
incrementWait(){ this.$store.dispatch("jiaWait",this.num); }
(✔)...mapActions({ incrementOdd:"jiaOdd", incrementWait:"jiaWait" })
(✔) -
mutations,照旧,不分模块。
increment(){ this.$store.commit("JIA",this.num); }
(✔)
decrement(){ this.$store.commit("JIAN",this.num); }
(✔)...mapMutations({ increment:"JIA", decrement:"JIAN" })
(✔)
store/person/index.js
store下新建文件夹:person,person下新建文件:index.js。
Person组件相关的state、getters、actions、mutations独立成模块并导出。
const state = {
personList:[
{id:"001",name:"张三"}
]
}
const getters = {}
const actions = {}
const mutations = {
ADD_PERSON(state,personObj){
state.personList.unshift(personObj);
}
}
export default {
state,
getters,
actions,
mutations
}
store/count/index.js
store下新建文件夹:count,count下新建文件:index.js。
Count组件相关的state、getters、actions、mutations独立成模块并导出。
const state = {
sum:0
}
const getters = {
bigSum(state){
return state.sum*10;
}
}
const actions = {
jiaOdd(context,value){
if(context.state.sum % 2){
context.commit("JIA",value);
}
},
jiaWait(context,value){
setTimeout(() => {
context.commit("JIA",value);
},500)
}
}
const mutations = {
JIA(state,value){
state.sum += value;
},
JIAN(state,value){
state.sum -= value;
}
}
export default {
state,
getters,
actions,
mutations
}
store/index.js
Count组件相关的state、getters、actions、mutations独立成模块store/count/index.js;
Person组件相关的state、getters、actions、mutations独立成模块store/person/index.js。
store/index.js中导入以上两个模块,并通过modules
聚合,即
new Vuex.Store({modules:{countAbout,personAbout}})
。
import Vue from "vue";
import Vuex from "vuex";
import countAbout from "./count";
import personAbout from "./person";
Vue.use(Vuex);
export default new Vuex.Store({
modules:{
countAbout,
personAbout
}
})
Person.vue
<template>
<div>
<h2>人员列表</h2>
<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.personAbout.personList;
},
sum(){
return this.$store.state.countAbout.sum;
}
},
methods: {
add(){
const personObj = {
id:nanoid(),
name:this.name
}
this.$store.commit("ADD_PERSON",personObj);
this.name = "";
}
},
}
</script>
<style scoped>
button{
margin-left: 5px;
}
</style>
Count.vue
mapState的对象写法
<template>
<div class="count">
<h2>当前求和为{{sum}}</h2>
<h2>当前求和放大10倍为{{bigSum}}</h2>
<h3 style="color:red">Person组件的总人数为{{personList.length}}</h3>
<select v-model="num">
<option :value="1">1</option>
<option :value="2">2</option>
<option :value="3">3</option>
</select>
<button @click="increment(num)">+</button>
<button @click="decrement(num)">-</button>
<button @click="incrementOdd(num)">和为奇数时再加</button>
<button @click="incrementWait(num)"> 等一等再加</button>
</div>
</template>
<script>
import {mapState,mapGetters,mapActions,mapMutations} from "vuex";
export default {
name: 'Count',
data(){
return {
num:1
}
},
computed:{
...mapState({
sum:state => state.countAbout.sum,
personList:state => state.personAbout.personList
}),
...mapGetters(["bigSum"])
},
methods: {
...mapActions({
incrementOdd:"jiaOdd",
incrementWait:"jiaWait"
}),
...mapMutations({
increment:"JIA",
decrement:"JIAN"
})
}
}
</script>
<style scoped>
button{
margin-left: 5px;
}
</style>
mapState的数组写法
<template>
<div class="count">
<h2>当前求和为{{countAbout.sum}}</h2>
<h2>当前求和放大10倍为{{bigSum}}</h2>
<h3 style="color:red">Person组件的总人数为{{personAbout.personList.length}}</h3>
<select v-model="num">
<option :value="1">1</option>
<option :value="2">2</option>
<option :value="3">3</option>
</select>
<button @click="increment(num)">+</button>
<button @click="decrement(num)">-</button>
<button @click="incrementOdd(num)">和为奇数时再加</button>
<button @click="incrementWait(num)"> 等一等再加</button>
</div>
</template>
<script>
import {mapState,mapGetters,mapActions,mapMutations} from "vuex";
export default {
name: 'Count',
data(){
return {
num:1
}
},
computed:{
...mapState(["countAbout","personAbout"]),
...mapGetters(["bigSum"])
},
methods: {
...mapActions({
incrementOdd:"jiaOdd",
incrementWait:"jiaWait"
}),
...mapMutations({
increment:"JIA",
decrement:"JIAN"
})
}
}
</script>
<style scoped>
button{
margin-left: 5px;
}
</style>
vuex的模块化+模块带命名空间
-
getters,分模块。
this.$store.getters["countAbout/bigSum"]
(✔)
(×)this.$store.getters.bigSum
(×)this.$store.getters.countAbout.bigSum
mapGetters("countAbout",["bigSum"])
(✔)
(×)mapGetters(["bigSum"])
-
state,分模块。
this.$store.state.countAbout.sum
(✔)
this.$store.state.personAbout.personList
(✔)...mapState("countAbout",["sum"])
(✔)
...mapState("personAbout",["personList"])
(✔)mapState({sum:state=>state.countAbout.sum,personList:state=>state.personAbout.personList})
(✔)mapState(["countAbout","personAbout"])
(✔) -
actions,分模块。
incrementOdd(){ this.$store.dispatch("countAbout/jiaOdd",this.num) }
(✔)
incrementWait(){ this.$store.dispatch("countAbout/jiaWait",this.num) }
(✔)(×)incrementOdd(){ this.$store.dispatch("jiaOdd",this.num); }
(×)incrementWait(){ this.$store.dispatch("jiaWait",this.num); }
...mapActions("countAbout",{ incrementOdd:"jiaOdd", incrementWait:"jiaWait" })
(✔)
(×)...mapActions({ incrementOdd:"jiaOdd", incrementWait:"jiaWait" })
-
mutations,分模块。
increment(){ this.$store.commit("countAbout/JIA",this.num); }
(✔)
decrement(){ this.$store.commit("countAbout/JIAN",this.num); }
(✔)
(×)increment(){ this.$store.commit("JIA",this.num); }
(×)decrement(){ this.$store.commit("JIAN",this.num); }
...mapMutations("countAbout",{ increment:"JIA", decrement:"JIAN" })
(✔)
(×)...mapMutations({ increment:"JIA", decrement:"JIAN" })
store/person/index.js
Person组件相关的state、getters、actions、mutations独立成模块:store/person/index.js,且该模块带命名空间:namespaced:true
。
const state = {
personList:[
{id:"001",name:"张三"}
]
}
const getters = {}
const actions = {}
const mutations = {
ADD_PERSON(state,personObj){
state.personList.unshift(personObj);
}
}
export default {
namespaced:true,
state,
getters,
actions,
mutations
}
store/count/index.js
Count组件相关的state、getters、actions、mutations独立成模块:store/count/index.js,且该模块带命令空间:namespaced:true
。
const state = {
sum:0
}
const getters = {
bigSum(state){
return state.sum*10;
}
}
const actions = {
jiaOdd(context,value){
if(context.state.sum % 2){
context.commit("JIA",value);
}
},
jiaWait(context,value){
setTimeout(() => {
context.commit("JIA",value);
},500)
}
}
const mutations = {
JIA(state,value){
state.sum += value;
},
JIAN(state,value){
state.sum -= value;
}
}
export default {
namespaced:true,
state,
getters,
actions,
mutations
}
store/index.js
带命名空间的模块:
- store/person/index.js
- store/count/index.js
通过modules
在store/index.js中聚合。
import Vue from "vue";
import Vuex from "vuex";
import countAbout from "./count";
import personAbout from "./person";
Vue.use(Vuex);
export default new Vuex.Store({
modules:{
countAbout,
personAbout
}
})
Person.vue
<template>
<div>
<h2>人员列表</h2>
<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.personAbout.personList;
},
sum(){
return this.$store.state.countAbout.sum;
}
},
methods: {
add(){
const personObj = {
id:nanoid(),
name:this.name
}
this.$store.commit("personAbout/ADD_PERSON",personObj)
this.name = "";
}
}
}
</script>
<style scoped>
button{
margin-left: 5px;
}
</style>
Count.vue
<template>
<div class="count">
<h2>当前求和为{{sum}}</h2>
<h2>当前求和放大10倍为{{bigSum}}</h2>
<h3 style="color:red">Person组件的总人数为{{personList.length}}</h3>
<select v-model="num">
<option :value="1">1</option>
<option :value="2">2</option>
<option :value="3">3</option>
</select>
<button @click="increment(num)">+</button>
<button @click="decrement(num)">-</button>
<button @click="incrementOdd(num)">和为奇数时再加</button>
<button @click="incrementWait(num)"> 等一等再加</button>
</div>
</template>
<script>
import {mapState,mapGetters,mapActions,mapMutations} from "vuex";
export default {
name: 'Count',
data(){
return {
num:1
}
},
computed:{
...mapState("countAbout",["sum"]),
...mapState("personAbout",["personList"]),
...mapGetters("countAbout",["bigSum"])
// ...mapState(["countAbout","personAbout"]),
// ...mapState({
// sum:state => state.countAbout.sum,
// personList:state => state.personAbout.personList
// }),
// sum(){
// return this.$store.state.countAbout.sum;
// },
// personList(){
// return this.$store.state.personAbout.personList;
// },
// bigSum(){
// return this.$store.getters["countAbout/bigSum"]
// }
},
methods: {
...mapActions("countAbout",{
incrementOdd:"jiaOdd",
incrementWait:"jiaWait"
}),
...mapMutations("countAbout",{
increment:"JIA",
decrement:"JIAN"
}),
// incrementOdd(){
// this.$store.dispatch("countAbout/jiaOdd",this.num)
// },
// incrementWait(){
// this.$store.dispatch("countAbout/jiaWait",this.num)
// },
// increment(){
// this.$store.commit("countAbout/JIA",this.num);
// },
// decrement(){
// this.$store.commit("countAbout/JIAN",this.num);
// }
}
}
</script>
<style scoped>
button{
margin-left: 5px;
}
</style>