1.Vuex API 补充内容
2.getters 配置项
3.四个Map方法的使用
4.多组件共享数据
5.Vux模块化和命名空间
一.Vuex API补充内容
① 在actions中,如果一个函数处理不完,可以继续调dispatch处理
② 开发者工具是跟mutations中的数据进行交互的,所以数据处理最好写在mutations中
二. getters 配置项
① 用于将state中的数据进行加工
② 使用
③ 结果展示
三. 四个Map方法的使用
引入:import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
3.1 mapState
① mapState是Vue帮我们映射state中的数据为计算属性
② 映射state中的数据为计算属性
- mapState得到的是一个对象,...把这个对象展开
- 对象写法和数组写法两种方式
- 对象写法:属性名代表在模板中使用的名字,属性值代表在state中的数据
...mapState({ he: 'sum', xuexiao: 'school', xueke: 'subject' })
- 数组写法:模板的数据和state中的数据名相同时使用这种写法
...mapState(['sum', 'school', 'subject'])
3.2 mapGetters
① mapGetters 是Vue帮助我们映射getter中的数据为计算属性
② 映射getter中的数据为计算属性
- 对象写法
...mapGetters({ bigSum: 'bigSum' })
- 数组写法
...mapGetters(['bigSum'])
在模板中的使用
3.3 mapActions
借助mapActions生成对应的方法,方法中调用dispatch 去联系mutation
- 对象写法
...mapActions({ incrementOdd: 'addOdd', incrementWait: 'addWait' })
- 模板中调用
- 数组写法
...mapActions(['addOdd', 'addWait'])
- 模板中调用
3.4 mapMutations
借助mapMutations对应的方法,方法中调用commit去联系mutation
- 对象写法
...mapMutations({ increment: 'ADD', decrement: 'MINUS' })
- 模板中调用
- 数组写法
...mapMutations(['ADD', 'MINUS'])
- 模板中调用
mapActions与mapMutations使用时,若需要传递参数需要,在模板中绑定事件时传递好参数,否则参数是事件对象
四.多组件共享数据
① 代码详情
Count.vue
<template>
<div>
<h1>当前求和为{{ sum }}</h1>
<h2>当前求和放大10倍为{{ bigSum }}</h2>
<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="ADD(n)">+</button>
<button @click="MINUS(n)">-</button>
<!-- <button @click="incrementOdd(n)">当前求和为奇数再加</button>
<button @click="incrementWait(n)">等一等再加</button> -->
<button @click="addOdd(n)">当前求和为奇数再加</button>
<button @click="addWait(n)">等一等再加</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
name: 'Count',
data () {
return {
n: 1, // 用户选择的数字
}
},
computed: {
// 帮助我们映射state中的数据为计算属性
// ...mapState({ sum: 'sum', school: 'school', subject: 'subject' })
...mapState(['sum', 'school', 'subject', 'personList']),
// 帮助我们映射getter中的数据为计算属性
// ...mapGetters({ bigSum: 'bigSum' })
...mapGetters(['bigSum'])
},
methods: {
// 借助mapMutations 生成对应的方法,方法中调用commit去联系mutation(对象写法)
// ...mapMutations({ increment: 'ADD', decrement: 'MINUS' }),
// 借助mapMutations 生成对应的方法,方法中调用commit去联系mutation(数组写法)
...mapMutations(['ADD', 'MINUS']),
// 借助mapActions 生成对应的方法,方法中调用 dispatch 去联系mutation (对象写法)
// ...mapActions({ incrementOdd: 'addOdd', incrementWait: 'addWait' })
// 借助mapActions 生成对应的方法,方法中调用 dispatch 去联系mutation (数组写法)
...mapActions(['addOdd', 'addWait'])
},
mounted () {
},
}
</script>
<style scoped>
</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 { mapState } from 'vuex'
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 obj = { id: nanoid(), name: this.name }
this.$store.commit('ADD_PERSON', obj)
this.name = ''
}
},
}
</script>
<style>
</style>
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>
<style>
button {
margin-left: 10px;
}
</style>
store/index.js
// 该文件用于创建Vuex中的store
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
// 使用Vuex
Vue.use(Vuex)
// 1.actions用于响应组件中的动作
const actions = {
// add (context, value) {
// context.commit('ADD', value)
// },
// minus (context, value) {
// context.commit('MINUS', value)
// },
addOdd (context, value) {
if (context.state.sum % 2) {
context.commit('ADD', value)
}
},
addWait (context, value) {
setTimeout(() => {
context.commit('ADD', value)
}, 500)
}
}
// 用于将state的数据进行加工
// 当state中的数据需要经过加工再使用时,可以使用getters加工
const getters = {
bigSum (state) {
return state.sum * 10
}
}
// 2.mutations 用于操作数据(state)
// mutations里面的方法最好是大写的
const mutations = {
ADD (state, value) {
state.sum += value
},
MINUS (state, value) {
state.sum -= value
},
ADD_PERSON (state, value) {
state.personList.unshift(value)
}
}
// 3.state用于存储数据
const state = {
sum: 0,
school: '尚硅谷',
subject: '前端',
personList: [
{ id: '001', name: '张三' }
]
}
// 创建并暴露store
export default new Vuex.Store({
actions,
mutations,
state,
getters
})
共享体现在哪里
① 在Count.vue中可以使用person的数据
② person里面使用count的数据
五. Vuex模块化和命名空间
5.1 Vuex模块化
① 分模块进行编程:每个模块负责自己模块的数据
② 这个名字可以随便起
③ 引入modules配置项
④ 使用
- count.vue中使用
如果要使用下面的方式取模块中的数据或者调用模块中的方法,就需要在对应的store管理文件中开启命名空间,调用的时候在前面声明调用哪个模块的方法
- person.vue中使用
(1)取数据:
(2)调用commit和dispatch方法的时候使用 / 的形式
(3) 使用getters取数据
5.2 所有模块化代码
① 文件目录
② Count.vue
<template>
<div>
<h1>当前求和为{{ sum }}</h1>
<h2>当前求和放大10倍为{{ bigSum }}</h2>
<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="ADD(n)">+</button>
<button @click="MINUS(n)">-</button> -->
<button @click="incrementOdd(n)">当前求和为奇数再加</button>
<button @click="incrementWait(n)">等一等再加</button>
<!-- <button @click="addOdd(n)">当前求和为奇数再加</button>
<button @click="addWait(n)">等一等再加</button> -->
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
name: 'Count',
data () {
return {
n: 1, // 用户选择的数字
}
},
computed: {
// 帮助我们映射state中的数据为计算属性
// ...mapState({ sum: 'sum', school: 'school', subject: 'subject' })
...mapState('countAbout', ['sum', 'school', 'subject']),
...mapState('personAbout', ['personList']),
// 帮助我们映射getter中的数据为计算属性
// ...mapGetters('countAbout', { bigSum: 'bigSum' })
...mapGetters('countAbout', ['bigSum'])
},
methods: {
// 借助mapMutations 生成对应的方法,方法中调用commit去联系mutation(对象写法)
...mapMutations('countAbout', { increment: 'ADD', decrement: 'MINUS' }),
// 借助mapMutations 生成对应的方法,方法中调用commit去联系mutation(数组写法)
// ...mapMutations(['ADD', 'MINUS']),
// ***********************************//
// incrementOdd () {
// this.$store.dispatch('addOdd', this.n)
// },
// incrementWait () {
// this.$store.dispatch('addWait', this.n)
// }
// 借助mapActions 生成对应的方法,方法中调用 dispatch 去联系mutation (对象写法)
...mapActions('countAbout', { incrementOdd: 'addOdd', incrementWait: 'addWait' })
// 借助mapActions 生成对应的方法,方法中调用 dispatch 去联系mutation (数组写法)
// ...mapActions(['addOdd', 'addWait'])
},
mounted () {
},
}
</script>
<style scoped>
</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 { mapState } from 'vuex'
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 obj = { id: nanoid(), name: this.name }
this.$store.commit('personAbout/ADD_PERSON', obj)
this.name = ''
},
addWang () {
const obj = { id: nanoid(), name: this.name }
this.$store.dispatch('personAbout/addPersonWang', obj)
this.name = ''
},
addPersonServer () {
this.$store.dispatch('personAbout/addPersonServer')
}
},
}
</script>
<style>
</style>
④ 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>
<style>
button {
margin-left: 10px;
}
</style>
⑤ count.js
export default {
namespaced: true,
actions: {
addOdd (context, value) {
if (context.state.sum % 2) {
context.commit('ADD', value)
}
},
addWait (context, value) {
setTimeout(() => {
context.commit('ADD', value)
}, 500)
}
},
mutations: {
ADD (state, value) {
state.sum += value
},
MINUS (state, value) {
state.sum -= value
},
},
state: {
sum: 0,
school: '尚硅谷',
subject: '前端'
},
getters: {
bigSum (state) {
return state.sum * 10
}
}
}
⑥ index.js
// 该文件用于创建Vuex中的store
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
import personOptions from './person'
import countOptions from './count'
// 使用Vuex
Vue.use(Vuex)
// 求和相关配置
// 人员管理相关的配置
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://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) {
state.personList.unshift(value)
}
},
state: {
personList: [
{ id: '001', name: '张三' }
]
},
getters: {
firstPersonName (state) {
return state.personList[0].name
}
}
}