Vue 2.0->3.0学习笔记(第五章 Vuex)

1. 理解Vuex

1.1 Vuex是什么

笔记

  1. 概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件。对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
  2. Github 地址:Vuex

1.2 什么时候使用Vuex

  1. 多个组件依赖于同一状态
  2. 来自不同组件的行为需要变更同一状态

1.3 多组件共享数据 ---- 全局事件总线实现

在这里插入图片描述

1.4 多组件共享数据 ---- Vuex实现

在这里插入图片描述

2. 求和案例

笔记
在这里插入图片描述

2.1 求和案例_纯vue版

笔记

  • 目录
    在这里插入图片描述
  • 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 {
        // eslint-disable-next-line vue/multi-word-component-names
        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>
  • App.vue
<template>
	<div>
		<Count/>
	</div>
</template>

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

  • 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.2 求和案例_vuex版

笔记

  • 创建Vuex环境
  1. 创建文件:src/store/index.js
//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)

//准备actions对象——响应组件中用户的动作
const actions = {}
//准备mutations对象——修改state中的数据
const mutations = {}
//准备state对象——保存具体的数据
const state = {}

//创建并暴露store
export default new Vuex.Store({
	actions,
	mutations,
	state
})
  1. main.js中创建vm时传入store配置项
......
//引入store
import store from './store'
......

//创建vm
new Vue({
	el:'#app',
	render: h => h(App),
	store
})
  • 目录
    在这里插入图片描述
  • 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 {
        // eslint-disable-next-line vue/multi-word-component-names
        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)
            }
        }
    }
</script>

<style lang="css">
    button{
        margin-left: 5px;
    }

</style>
  • index.js
//该文件用于创建Vuex中最为核心的store

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//准备actions -- 用于响应组件中的动作
const actions = {
    // jia(context,value){
    //     console.log('actions中的jia被调用了',context,value)
    //     context.commit('JIA',value)
    // },
    // jian(context,value){
    //     console.log('actions中的jian被调用了',context,value)
    //     context.commit('JIAN',value)
    // },
    jiaOdd(context,value){
        if(context.state.sum % 2){
            console.log('actions中的jiaOdd被调用了',context,value)
            context.commit('JIA',value)
        }
    },
    jiaWait(context,value){
        console.log('actions中的jiaWait被调用了',context,value)
        setTimeout(()=>{
            context.commit('JIA',value)
        },500)
    },
}
//准备mutations -- 用于操作数据(state)
const mutations = {
    JIA(state,value){
        console.log('mutations中的JIA被调用了',state,value)
        state.sum += value
    },
    JIAN(state,value){
        console.log('mutations中的JIAN被调用了',state,value)
        state.sum -= value
    }
}
//准备state -- 用于存储数据
const state = {
    sum:0//当前的和
    }

//创建并暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state,
})


  • App.vue
<template>
	<div>
		<Count/>
	</div>
</template>

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

  • 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
	},
})

2.3 求和案例_getters

笔记

  1. 概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。
  2. store.js中追加getters配置
......

const getters = {
	bigSum(state){
		return state.sum * 10
	}
}

//创建并暴露store
export default new Vuex.Store({
	......
	getters
})
  1. 组件中读取数据:$store.getters.bigSum
  • 目录
    在这里插入图片描述
  • 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 {
        // eslint-disable-next-line vue/multi-word-component-names
        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)
            }
        }
    }
</script>

<style lang="css">
    button{
        margin-left: 5px;
    }

</style>
  • index.js
//该文件用于创建Vuex中最为核心的store

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//准备actions -- 用于响应组件中的动作
const actions = {
    // jia(context,value){
    //     console.log('actions中的jia被调用了',context,value)
    //     context.commit('JIA',value)
    // },
    // jian(context,value){
    //     console.log('actions中的jian被调用了',context,value)
    //     context.commit('JIAN',value)
    // },
    jiaOdd(context,value){
        if(context.state.sum % 2){
            console.log('actions中的jiaOdd被调用了',context,value)
            context.commit('JIA',value)
        }
    },
    jiaWait(context,value){
        console.log('actions中的jiaWait被调用了',context,value)
        setTimeout(()=>{
            context.commit('JIA',value)
        },500)
    },
}
//准备mutations -- 用于操作数据(state)
const mutations = {
    JIA(state,value){
        console.log('mutations中的JIA被调用了',state,value)
        state.sum += value
    },
    JIAN(state,value){
        console.log('mutations中的JIAN被调用了',state,value)
        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
})


  • App.vue
<template>
	<div>
		<Count/>
	</div>
</template>

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

  • 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
	},
})

2.4 求和案例_mapState与mapGetters

笔记

  1. mapState方法:用于帮助我们映射state中的数据为计算属性
computed: {
    //借助mapState生成计算属性:sum、school、subject(对象写法)
     ...mapState({sum:'sum',school:'school',subject:'subject'}),
         
    //借助mapState生成计算属性:sum、school、subject(数组写法)
    ...mapState(['sum','school','subject']),
},
  1. mapGetters方法:用于帮助我们映射getters中的数据为计算属性
computed: {
    //借助mapGetters生成计算属性:bigSum(对象写法)
    ...mapGetters({bigSum:'bigSum'}),

    //借助mapGetters生成计算属性:bigSum(数组写法)
    ...mapGetters(['bigSum'])
},
  • 目录
    在这里插入图片描述
  • 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 { mapGetters, mapState } from 'vuex';
    export default {
        // eslint-disable-next-line vue/multi-word-component-names
        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)
            }
        }
    }
</script>

<style lang="css">
    button{
        margin-left: 5px;
    }

</style>
  • index.js
//该文件用于创建Vuex中最为核心的store

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//准备actions -- 用于响应组件中的动作
const actions = {
    // jia(context,value){
    //     console.log('actions中的jia被调用了',context,value)
    //     context.commit('JIA',value)
    // },
    // jian(context,value){
    //     console.log('actions中的jian被调用了',context,value)
    //     context.commit('JIAN',value)
    // },
    jiaOdd(context,value){
        if(context.state.sum % 2){
            console.log('actions中的jiaOdd被调用了',context,value)
            context.commit('JIA',value)
        }
    },
    jiaWait(context,value){
        console.log('actions中的jiaWait被调用了',context,value)
        setTimeout(()=>{
            context.commit('JIA',value)
        },500)
    },
}
//准备mutations -- 用于操作数据(state)
const mutations = {
    JIA(state,value){
        console.log('mutations中的JIA被调用了',state,value)
        state.sum += value
    },
    JIAN(state,value){
        console.log('mutations中的JIAN被调用了',state,value)
        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
})


  • App.vue
<template>
	<div>
		<Count/>
	</div>
</template>

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

  • 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
	},
})

2.5 求和案例_mapMutations与mapActions

笔记

  1. mapActions方法:用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数
methods:{
    //靠mapActions生成:incrementOdd、incrementWait(对象形式)
    ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})

    //靠mapActions生成:incrementOdd、incrementWait(数组形式)
    ...mapActions(['jiaOdd','jiaWait'])
}
  1. mapMutations方法:用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数
methods:{
    //靠mapActions生成:increment、decrement(对象形式)
    ...mapMutations({increment:'JIA',decrement:'JIAN'}),
    
    //靠mapMutations生成:JIA、JIAN(对象形式)
    ...mapMutations(['JIA','JIAN']),
}

备注:mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象

  • 目录
    在这里插入图片描述
  • 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 {
        // eslint-disable-next-line vue/multi-word-component-names
        name:'Count',
        data() {
            return {
                n:1,//用户选择的数字
                
            }
        },
        computed:{
            //借助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)
            },*/

            //借助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'])
        }
    }
</script>

<style lang="css">
    button{
        margin-left: 5px;
    }

</style>
  • index.js
//该文件用于创建Vuex中最为核心的store

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//准备actions -- 用于响应组件中的动作
const actions = {
    // jia(context,value){
    //     console.log('actions中的jia被调用了',context,value)
    //     context.commit('JIA',value)
    // },
    // jian(context,value){
    //     console.log('actions中的jian被调用了',context,value)
    //     context.commit('JIAN',value)
    // },
    jiaOdd(context,value){
        if(context.state.sum % 2){
            console.log('actions中的jiaOdd被调用了',context,value)
            context.commit('JIA',value)
        }
    },
    jiaWait(context,value){
        console.log('actions中的jiaWait被调用了',context,value)
        setTimeout(()=>{
            context.commit('JIA',value)
        },500)
    },
}
//准备mutations -- 用于操作数据(state)
const mutations = {
    JIA(state,value){
        console.log('mutations中的JIA被调用了',state,value)
        state.sum += value
    },
    JIAN(state,value){
        console.log('mutations中的JIAN被调用了',state,value)
        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
})


  • App.vue
<template>
	<div>
		<Count/>
	</div>
</template>

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

  • 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
	},
})

2.6 求和案例_多组件共享数据

笔记

  • 目录
    在这里插入图片描述
  • 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 {
        // eslint-disable-next-line vue/multi-word-component-names
        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'}),
        }
    }
</script>

<style lang="css">
    button{
        margin-left: 5px;
    }

</style>
  • 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 {
        // eslint-disable-next-line vue/multi-word-component-names
        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>

</style>
  • index.js
//该文件用于创建Vuex中最为核心的store

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
//准备actions -- 用于响应组件中的动作
const actions = {
    // jia(context,value){
    //     console.log('actions中的jia被调用了',context,value)
    //     context.commit('JIA',value)
    // },
    // jian(context,value){
    //     console.log('actions中的jian被调用了',context,value)
    //     context.commit('JIAN',value)
    // },
    jiaOdd(context,value){
        if(context.state.sum % 2){
            console.log('actions中的jiaOdd被调用了',context,value)
            context.commit('JIA',value)
        }
    },
    jiaWait(context,value){
        console.log('actions中的jiaWait被调用了',context,value)
        setTimeout(()=>{
            context.commit('JIA',value)
        },500)
    },
}
//准备mutations -- 用于操作数据(state)
const mutations = {
    JIA(state,value){
        console.log('mutations中的JIA被调用了',state,value)
        state.sum += value
    },
    JIAN(state,value){
        console.log('mutations中的JIAN被调用了',state,value)
        state.sum -= value
    },
    ADD_PERSON(state,value){
        console.log('mutations中的ADD_PERSPM被调用了',state,value)
        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
})


  • 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},
	}
</script>

  • 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
	},
})

2.7 求和案例_vuex模块化编码

笔记

  • 模块化+命名空间
  1. 目的:让代码更好维护,让多种数据分类更加明确。
  2. 修改index.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
  }
})
  1. 开启命名空间后,组件中读取state数据:
//方式一:自己直接读取
this.$store.state.personAbout.list
//方式二:借助mapState读取:
...mapState('countAbout',['sum','school','subject']),
  1. 开启命名空间后,组件中读取getters数据:
//方式一:自己直接读取
this.$store.getters['personAbout/firstPersonName']
//方式二:借助mapGetters读取:
...mapGetters('countAbout',['bigSum'])
  1. 开启命名空间后,组件中调用dispatch
//方式一:自己直接dispatch
this.$store.dispatch('personAbout/addPersonWang',person)
//方式二:借助mapActions:
...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
  1. 开启命名空间后,组件中调用commit
//方式一:自己直接commit
this.$store.commit('personAbout/ADD_PERSON',person)
//方式二:借助mapMutations:
...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
  • 目录
    在这里插入图片描述
  • 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 {
        // eslint-disable-next-line vue/multi-word-component-names
        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'}),
        }
    }
</script>

<style lang="css">
    button{
        margin-left: 5px;
    }

</style>
  • 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 {
        // eslint-disable-next-line vue/multi-word-component-names
        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>

<style>

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

}
  • index.js
//该文件用于创建Vuex中最为核心的store

//引入Vue核心库
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
    }
})


  • 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://v1.hitokoto.cn/?c=f&encode=text').then(
                response =>{
                    context.commit('ADD_PERSON',{id:nanoid(),name:response.data})
                },
                error => {
                    alert(error.message)
                }
            )
        }
    },
    mutations:{
        ADD_PERSON(state,value){
            console.log('mutations中的ADD_PERSPM被调用了',state,value)
            state.personList.unshift(value)
    }
    },
    state:{
        personList:[{
            id:'001',name:'张三'
                }]
    },
    getters:{
        firstPersonName(state){
            return state.personList[0].name
        }
    }
}


  • 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},
	}
</script>

  • 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
	},
})
  • 本文仅作个人学习笔记使用,无商业用途。
  • 上述内容笔记大部分摘自“B站尚硅谷”
  • 如若转载,请先声明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值