Vue笔记_05_vuex
第五章 vuex
vuex是什么?
- 概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式管理(读/写),也是组件间通信的方式,且适用于任意组件间通信
- Github地址:Vuex
什么时候用Vuex
- 多个组件依赖于同一状态
- 来自不同组件的行为需要变更同一状态
搭建vuex环境
- vuex的工作原理图
-
安装vuex:
npm install --save vuex
-
创建文件:
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 })
-
在
main.js
中创建vm时传入store
配置项import Vue from 'vue' import App from './App.vue' // 引入store import store from './store/index' Vue.config.productionTip = false // 创建vm的时候注册store new Vue({ render: h => h(App), store, }).$mount('#app')
-
组件中读取vuex中的数据:
$store.state.sum
-
组件中修改vuex中的数据:
$store.dispatch('action中的方法名',数据)
或者$store.commit('mutations中的方法名',数据)
案例
vue版本
在App.vue文件里:
<template>
<div>
<Count/>
</div>
</template>
<script>
import Count from './components/Count.vue'
export default {
name:'App',
components:{Count}
}
</script>
<style>
body {
background-color: #e0e0e0;
}
</style>
在Count.vue文件中:
<template>
<div id="Count">
<h1>当前求和为{{sum}}</h1>
<!-- 用v-model绑定n的值,用number限定词来限定n的值为数字 -->
<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
},
// 当sum的值为奇数的时候才加,不然就不加
incrementOdd() {
if (this.sum % 2) {
this.sum += this.n
}
},
// 等一等再加
incrementWait() {
setTimeout(()=>{
this.sum += this.n
}, 500)
}
},
}
</script>
<style scoped>
#Count {
margin: 0 auto;
width: 80%;
}
button {
margin-left: 5px;
}
button:hover,
select:hover {
cursor: pointer;
}
</style>
vuex版本
在main.js文件里:
import Vue from 'vue'
import App from './App.vue'
// 引入store
import store from './store/index'
Vue.config.productionTip = false
// 创建vm的时候注册store
new Vue({
render: h => h(App),
store,
}).$mount('#app')
在src/store/index.js
里:(重点)
// 引入Vue核心库
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 应用Vuex
Vue.use(Vuex)
// 准备actions对象--响应组件中用户的动作
const actions = {
// 奇数的时候加
incOdd(context, value) {
if (context.state.sum % 2) {
context.commit('INC', value)
}
},
// 等一等再加
incWait(context, value) {
setTimeout(()=>{
context.commit('INC', value)
}, 500)
}
}
// 准备mutations对象--修改state中的数据
const mutations = {
// 加法的实现
INC(state, value) {
state.sum += value
},
// 减法的实现
DEC(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.vue'
export default {
name:'App',
components:{Count}
}
</script>
<style>
body {
background-color: #e0e0e0;
}
</style>
在Count.vue文件里:
<template>
<div id="Count">
<h1>当前求和为{{$store.state.sum}}</h1>
<!-- 用v-model绑定n的值,用number限定词来限定n的值为数字 -->
<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() {
// 这里不走Actions,而是直接走Mutetions
this.$store.commit('INC', this.n)
},
// 减法
decrement() {
// 这里不走Actions,而是直接走Mutetions
this.$store.commit('DEC', this.n)
},
// 当sum的值为奇数的时候才加,不然就不加
incrementOdd() {
this.$store.dispatch('incOdd', this.n)
},
// 等一等再加
incrementWait() {
this.$store.dispatch('incWait', this.n)
}
},
}
</script>
<style scoped>
#Count {
margin: 0 auto;
width: 80%;
}
button {
margin-left: 5px;
}
button:hover,
select:hover {
cursor: pointer;
}
</style>
getter的使用
-
概念:当state中的数据是需要加工后再使用的时候,可以使用getter加工
-
在
store.js中
追加getter
配置... const getter = { bigSum(state) { return state.sum * 10 } } // 创建并暴露store export default new Vuex.Store({ ... getters })
-
组件中读取数据:
$store.getters.bigSum
四个map的使用
mapState方法
用于帮助我们映射state
中的数据为计算属性
computed: {
// 借助mapState方法生成计算属性:sum, school, subject(对象写法)
...mapState({sum:'sum', school:'school', subject:'subject'})
// 借助mapState方法生成计算属性:sum, school, subject(数组写法)
...mapState(['sum', 'school', 'subject'])
}
mapGetters方法
用于帮助我们映射getter
中的数据为计算属性
computed: {
// 借助mapGetters生成计算属性:bigSum(对象写法)
...mapGetters({bigSum:'bigSum'})
// 借助mapGetters生成基色属性:bigSum(数组写法)、
...mapGetters(['bigSum'])
}
mapActions方法
用于帮助我们生成actions
对话的方法,即包含$store.dispatch(xx)
的函数
methods: {
// 靠mapActions方法生成:increment, decrement, incrementWait(对象形式)
...mapActions({increment:'increment', decrement:'decrement', incrementWait:'incrementWait'})
// 靠mapActions方法生成:increment, decrement, incrementWait(数组形式)
...mapActions(['increment', 'decrement', 'incrementWait'])
}
mapMutations方法
用于帮助我们生成与mutations
对话的方法, 即包含$store.commit(xxx)
的函数
methods: {
// 靠mapMutations生成:increment, decrement(对象形式)
...mapMutations({increment:'JIA', decrement:'JIAN'})
// 靠mapMutations生成:increment, decrement(数组形式)
...mapMutations(['JIA', 'JIAN'])
}
备注:mapActions和mapMutations方法在使用的时候,若需要传递参数,需要:在模板中绑定事件时传递好参数,否则参数是事件对象
模块化+命名空间
-
目的:让代码更好维护,让多种数据分类更加明确
-
修改
store.js
const countAbout = { namespace: true, // 开启命名空间 state: {sum: 0}, mutations: {...}, actions: {...}, getters: { bigSum(state) { return state.sum * 10 } } } const personAbout = { namespace: true, state: {...}, mutations: {...}, actions: {...}, } const store = new Vuex.Store({ modules: { countAbout, personAbout } })
-
开启命名空间后,组件中访问state数据:
// 方式一:自己直接读取 this.$store.state.personAbout.list // 方式二:借助mapState读取 ...mapState('countAbout', ['sum', 'school', 'subject'])
-
开启命名空间后:组件中读取getters数据
// 方式一:自己直接读取 this.$store.getters['personAbout/firstPersonName'] // 方式二:借助mapGetters读取 ...mapGetters('countAbout', ['bigSum'])
-
开启命名空间后,组件中调用dispatch
// 方式一:自己直接dispatch this.$store.dispatch('personAbout/addPersonWang', person) // 方式二:借助mapActions ...mapActions('countAbout', {increment: 'jiaOdd', incrementWait: 'jiaWait'})
-
开启命名空间后,组件是调用commit
// 方式一:自己直接调用commit this.$store.commit('personAbout/ADD_PERSON', person) // 方式二:借助mapMutations ...mapMutations('countAbout', {increment: 'JIA', decrement: 'J'})