5. Vuex
1. 理解 Vuex
1. 多组件共享数据-全局事件总线实现
红线是读,绿线是写
2. 多组件共享数据-vuex实现
- vuex 不属于任何组件
3. 求和案例-纯vue版
核心代码
1.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 {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 scoped>
button {margin-left: 5px;
}
</style>
2.App.vue
<template><div><count /></div>
</template>
<script>
import Count from "./components/Count.vue";
export default {components: { Count },name: "App",
};
</script>
<style scoped>
.container,
.foot {display: flex;justify-content: space-around;
}
h4 {text-align: center;
}
</style>
1. 什么是 Vuex
- 概念:专门在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应 用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方 式,且适用于任意组件间通信。
- Github 地址: https://github.com/vuejs/vuex
2.什么时候使用 Vuex
- 多个组件依赖于同一状态
- 来自不同组件的行为需要变更同一状态
- 多个组件需要共享数据时
3. Vuex 工作原理图
如果dispatch知道怎么操作,并且知道具体数值时,可以直接省略actions直接commit
注意:在2022年2月7日,vue3成为了默认版本,所以说 npm i vue,安装的直接就是vue3了,并且vue3成为默认版本的同时,vuex也更新到了4版本,所以我们现在执行npm i vuex,安装的是vuex4,但vuex的4版本,只能在vue3中使用,如果安装就会出现下图的报错
vue2中,要用vuex的3版本vue3中,要用vuex的4版本
4. 搭建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
配置项...... //引入store import store from './store' ......//创建vm new Vue({el:'#app',render: h => h(App),store })
-
注意事项:
import str1 from "./test1"; console.log(100) console.log(200) import str2 from "./test2"; // 原因:在脚手架里写 import 的时候,会扫描全局,不管放在哪里,中间有多少数据,按照你编写代码的顺序,都会汇总到最上方,挨个执行
test1.js
console.log('test1') const str1 = 'test1' export default str1
test2.js
console.log('test2') const str2 = 'test2' export default str2
5.求和案例改造成vuex
核心代码
1. 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 {name: "Count",data() {return {n: 1, // 用户选择的数据};},mounted() {},methods: {increment() {// this.$store.dispatch("jia", this.n);this.$store.commit("JIA", this.n);},decrement() {// this.$store.dispatch("jian", this.n);this.$store.commit("JIAN", this.n);},incrementOdd() {// if (this.$store.state.sum % 2) {this.$store.dispatch("jiaOdd", this.n);// }},incrementWait() {// setTimeout(() => {this.$store.dispatch("jiaWait", this.n);// }, 500);},},
};
</script>
<style scoped>
button {margin-left: 5px;
}
</style>
2. App.vue
<template><div><count /></div>
</template>
<script>
import Count from "./components/Count.vue";
export default {components: { Count },name: "App",mounted() {// console.log("App", this);},
};
</script>
<style scoped>
.container,
.foot {display: flex;justify-content: space-around;
}
h4 {text-align: center;
}
</style>
3. store/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) {console.log('actions中的jiaOdd被调用了', context, value);if (context.state.sum % 2) {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
})
4. main.js
<template><div><count /></div>
</template>
<script>
import Count from "./components/Count.vue";
export default {components: { Count },name: "App",mounted() {// console.log("App", this);},
};
</script>
<style scoped>
.container,
.foot {display: flex;justify-content: space-around;
}
h4 {text-align: center;
}
</style>