vuex是vue的一个插件,是一种组间通信的方式,整个项目可以共享数据和方法
安装:
npm i vuex@3
编辑
如上图所示,如果需求非常简单,我们就可以绕过dispatch方法,直接去调用commit方法
dispatch方法用于编写业务代码
vuex的配置目录:src/store/index.js
// 响应组件中的动作
const actions = {
jian(context, val) {
context.commit('JIAN', val)
},
jianOdd(context, val) {
if (context.state.sum % 2 === 0) return
context.commit('JIA', val)
},
incrWait(context, val) {
setTimeout(() => {
context.commit('JIA', val)
}, 2000)
},
}
// 用于真实操作数据
const mutations = {
JIA(state, val) {
state.sum += val
},
JIAN(state, val) {
state.sum -= val
},
}
// 用于存储数据
const state = {
sum: 0,
}
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)
// 默认暴露,这里Store要大写
export default new Vuex.Store({actions, mutations, state})
main.js引入vuex:
import Vue from 'vue'
import App from './App.vue'
// 默认会引入store目录下的index.js文件
import store from './store'
// 关闭vue生产的提示
Vue.config.productionTip = false
new Vue({
render: h => h(App),
// 这里要小写
store,
}).$mount('#app')
使用案例:
<h1>当前求和的数为:{{ $store.state.sum }}</h1>
this.$store.commit('JIA', this.n)
this.$store.dispatch('jianOdd', this.n)
getters的用法:
伪代码
// index.js
const getters = {
bigSum(state) {
return state.sum * 10
}
}
export default new Vuex.Store({actions, mutations, state, getters})
// Count.vue
<h1>当前求和的数为:{{ $store.getters.bigSum }}</h1>
使用的时候用mapState的简写:
computed: {
...mapState({he: 'sum', xuexiao: 'school', xueke: 'subject'}),
}
<h1>学校:{{ xuexiao}}</h1>
2、使用数组的方式引入:
...mapState(['sum','subject','school']),
通过mapState的语法格式,从而得知mapGetters语法格式
mapMutations:
methods: {
...mapMutations(['JIA','JIAN']),
},
<button @click="JIA(n)">+</button>
mapActions的用法也相似,这里就不赘述了
推荐前端生成随机数的插件nanoid:
推荐前端日期格式插件dayjs
import {nanoid} from "nanoid";
模块化:
使用命名空间,为了解决store里面太臃肿的问题
推荐一个很厉害了的api:一言API (uixsj.cn)
count.js:
// 求和相关配置
export default {
// 命名空间
namespaced: true,
state: {
sum: 0,
school: '尚硅谷',
subject: '前端',
},
getters: {
bigSum(state) {
return state.sum * 10
}
},
actions: {
jianOdd(context, val) {
if (context.state.sum % 2 === 0) return
context.commit('JIA', val)
},
incrWait(context, val) {
setTimeout(() => {
context.commit('JIA', val)
}, 2000)
},
},
mutations: {
JIA(state, val) {
state.sum += val
},
JIAN(state, val) {
state.sum -= val
},
}
}
person.js:
// 人员相关配置
import axios from "axios";
import {nanoid} from "nanoid";
export default {
// 命名空间
namespaced: true,
state: {
persons: [
{id: 'VeZvrijiOTzqi7NNu6U0Q', name: 'tom'}
],
},
getters: {
firstPersonName(state) {
return state.persons[0].name
},
},
actions: {
addPersonWang(context, val) {
// context上下文
if (val.name.indexOf('王') === 0) {
context.commit('ADD_PERSON', val)
} else {
alert('添加的用户必须行姓王')
}
},
addPersonServer(context) {
axios.get('https://api.uixsj.cn/hitokoto/get').then(res => {
// commit就是调用mutations
context.commit('ADD_PERSON', {id: nanoid(), name: res.data})
}, err => {
alert(err.message)
})
},
},
mutations: {
ADD_PERSON(state, val) {
state.persons.push(val)
},
},
}
main.js:
import count from "./count";
import person from "./person";
import Vuex from 'vuex'
import Vue from 'vue'
Vue.use(Vuex)
// 默认暴露
export default new Vuex.Store({
modules: {countOptions: count, personOptions: person}
})
Count.vue:
<template>
<div>
<div>
<h1>当前求和的数为:{{ sum }}</h1>
<h1>放大十倍的数为:{{ bigSum }}</h1>
<h1>学校:{{ school }}</h1>
<h1>学科:{{ subject }}</h1>
<select v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="JIA(n)">+</button>
<button @click="JIAN(n)">-</button>
<button @click="jianOdd(n)">奇数才加</button>
<button @click="incrWait(n)">延时加</button>
</div>
<div>
下方组件的总人数是:{{ persons.length }}
</div>
<hr/>
</div>
</template>
<script>
import {mapActions, mapGetters, mapMutations, mapState} from 'vuex'
export default {
name: "Count",
data() {
return {
n: 1
}
},
methods: {
...mapMutations('countOptions', ['JIA', 'JIAN']),
...mapActions('countOptions', ['jianOdd', 'incrWait']),
},
computed: {
...mapState('countOptions', ['sum', 'school', 'subject']),
...mapState('personOptions', ['persons']),
...mapGetters('countOptions', ['bigSum']),
},
mounted() {
},
}
</script>
<style scoped>
</style>
Person.vue:
<template>
<div>
<div>
上方组件的求和为:{{ sum }}
</div>
<div>
<input v-model="name" type="text">
<button @click="add">添加</button>
<button @click="addPersonWang">添加一个姓王的用户</button>
<button @click="addPersonServer">添加一个随机的用户</button>
</div>
<div>
<ul>
<li v-for="i in persons">{{ i.name }}</li>
</ul>
</div>
<div>第一个用户的名字:{{ firstPersonName }}</div>
</div>
</template>
<script>
import {mapState} from "vuex";
import {nanoid} from "nanoid";
export default {
name: "Person",
data() {
return {
name: '',
}
},
computed: {
sum() {
return this.$store.state.countOptions.sum
},
// 1、全部导入的简写方式
...mapState('personOptions', ['persons']),
firstPersonName() {
return this.$store.getters['personOptions/firstPersonName']
}
},
methods: {
add() {
const personObj = {id: nanoid(), name: this.name}
// 1、导入后简写的方式
// this.ADD_PERSON(personObj)
// 2、单独使用一个方法的方式
this.$store.commit('personOptions/ADD_PERSON', personObj)
this.name = ''
},
//1、简写的导入
// ...mapMutations('personOptions', ['ADD_PERSON']),
addPersonWang() {
const personObj = {id: nanoid(), name: this.name}
this.$store.dispatch('personOptions/addPersonWang', personObj)
this.name = ''
},
addPersonServer(){
this.$store.dispatch('personOptions/addPersonServer')
},
}
}
</script>
<style scoped>
</style>