28-vuex 深碍√TFBOYSˉ_ 2023-10-08 18:17 15阅读 0赞 ## vuex ## #### 一、vuex #### 专门在vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。 使用场景: * 多个组件依赖于同一状态 * 来自不同组件的行为需要变更同一状态 #### 二、搭建Vuex环境 #### 1. 创建文件:`src/store/index.js` // 用于创建vuex中最核心的store // 引入vuex import Vue from 'vue' 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, // actions:actions mutations, state }); 1. 在`main.js`中创建vm时传入`store`配置项 import Vue from 'vue' import App from './App.vue' // 引入store,因为store写的是index.js,所以此处不需要写完整的./store/index.js路径 import store from './store' new Vue({ render: h => h(App), store, // 使用vuex插件之后,就可以使用store配置项了 }).$mount('#app') 此时,Vue实例对象vm和所有的组件实例对象vc都可以通过 `this.$store`获取到store对象,通过store的`dispatch('xxx', value)`调用`actions`中配置的方法,通过store的`commit('xxx',value)`调用mutations中配置的方法,通过`state`获取到state中配置的具体变量。 Vuex的一般流程为: 1. 组件中通过 `this.$store.dispatch('xxx', value)` 调用 actions中配置的方法 2. actions的方法中,通过`context.commit('xxx', value)` 调用 mutations中配置的方法 3. mutations的方法中,对`state`中的变量进行修改操作 ![vuex.png][] actions可以理解为饭店的服务员:组件调用`dispatch`告诉actions服务员点菜。服务员可以进行一些判断逻辑,比如客户是否有忌口、厨房是否还有原材料等(发送ajax去菜市场买菜也在这里处理) mutations可以理解为饭点的厨师:actions中调用`commit`通知厨师做具体的菜。厨师对`state`中具体的原材料变量进行处理。 > 如果actions中没有什么判断逻辑,只是单纯的调用了`commit`通知厨师,那么就可以组件中通过`commit`直接通知厨师做菜。 > > 虽然actions中也可以对`state`进行操作做菜,但是不推荐这么做。因为页面控制台的Vuex监控插件只会监控mutations对state的改变,不会监控actions。 #### 三、示例 #### 在index.js文件编写actions、mutations、state: // ....... // 准备actions,用于响应组件中的动作 const actions = { // context是一个mini版的store,拥有store的dispatch、commit等相关方法 jia(context, value) { context.commit('JIA', value); }, jian(context, value) { context.commit('JIAN', value); }, jiaOdd(context, value) { if(context.state.sum % 2) { context.commit('JIA', value) } }, jiaWait(context, value) { setTimeout(() => { context.commit('JIA', value) }, 500); }, demo1(context, value) { // actions中的方法,可以通过dispatch继续调用其他方法。 context.dispatch('demo2', value) }, demo2(context,value) { context.commit('JIA', value) } } // 准备mutations,用于操作数据(state) const mutations = { // mutations内部的方法名一般用大写 JIA(state, value) { state.sum += value }, JIAN(state, value) { state.sum -= value } } // 准备state,用于存储数据 const state = { sum:0 } // ......... 组件中调用相关方法: <template> <div> <!-- 读取Vuex中的数据 --> <h2>当前求和为:{ {$store.state.sum}}</h2> <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() { // this.$store.dispatch('jia', this.n); // actions中没有其他逻辑,只是调用commit。那么就可以在组件中通过commit直接调用mutations中的方法 this.$store.commit('JIA', this.n) }, decrement() { // this.$store.dispatch('jian', this.n); this.$store.commit('JIAN', this.n) }, incrementOdd() { // 通过dispatch调用actions中的方法 this.$store.dispatch('jiaOdd', this.n) }, incrementWait() { this.$store.dispatch('jiaWait', this.n) } }, } </script> #### 四、getters #### 类似于计算属性,位于`store`中。当state中的数据需要加工后再使用时,可以使用getters加工。 这个属性是非必须的,可以根据需要添加。 示例: 在index.js中配置getters // 定义getters const getters = { bigSum(state) { // 可以接收到state return state.sum * 10; // 需要有返回值 } } // 创建并暴露store export default new Vuex.Store({ actions, mutations, state, getters // 将getters配置到store中 }); 在页面使用getters: <template> <div> <h2>当前求和为:{ {$store.state.sum}}</h2> <!-- 通过$store.getters获取到getters配置的属性 --> <h2>当前求和放大10倍为:{ {$store.getters.bigSum}}</h2> </div> </template> #### 五、4个map方法的使用 #### `mapState`可以用于帮我们映射`state`中的数据为计算属性。 `mapGetters`用于帮我们映射`getters`中的数据为计算属性。 `mapActions`用于帮我们生成与`actions`对话的方法,即包含`$store.dispatch(xxx)`的函数 `mapMutations`用于帮我们生成与`mutations`对话的方法,即包含`$store.commit`的函数 如果要从`state`中获取很多属性,直接使用计算属性的写法为: <template> <div> <h2>求和:{ {he}}</h2> <h2>学校:{ {xuexiao}}</h2> <h2>学科:{ {xueke}}</h2> </div> </template> <script> export default { name:'Count', computed: { he() { return this.$store.state.sum; }, xuexiao() { return this.$store.state.school; }, xueke() { return this.$store.state.subject; } } } </script> 每次都要写`this.$store.state.`比较繁琐,可以使用`mapState`进行简写: <script> // 引入mapState import {mapState} from 'vuex' export default { name:'Count', computed: { // mapState是一个对象,需要使用解构语法对其属性进行解构 // 此时就相当于在计算属性中定义了he、xuexiao、xueke这些计算属性,冒号后面为映射到的state中的属性 ...mapState({he:'sum', xuexiao:'school', xueke:'subject'}) } } </script> 特别的,如果计算属性和`state`属性名相同,可以使用数组简写: <script> // 引入mapState import {mapState} from 'vuex' export default { name:'Count', computed: { // ...mapState({sum:'sum', school:'school', subject:'subject'}) // 数组简写 ...mapState(['sum', 'school', 'subject']) } } </script> 同样的,如果要获取`getters`中的属性,可以使用`mapGetters`进行简写: <script> // 引入mapState、mapGetters import {mapState,mapGetters} from 'vuex' export default { name:'Count', computed: { ...mapState(['sum', 'school','subject']), // bigSum() { // return this.$store.getters.bigSum // } // 简写为 // ...mapGetters({bigSum:'bigSum'}) // 或者简写为 ...mapGetters(['bigSum']) } } </script> 如果要调用actions中的dispatch方法,直接在methods中写法为: <template> <div> <button @click="increment">+</button> <button @click="decrement">-</button> </div> </template> <script> export default { name:'Count', data() { return { n:1, } }, methods: { incrementOdd() { // 通过dispatch调用actions中的方法 this.$store.dispatch('jiaOdd', this.n) }, incrementWait() { this.$store.dispatch('jiaWait', this.n) } } } </script> 可以使用`mapActions`简写`$store.dispatch`: <template> <div> <!-- 使用mapActions时,需要在调用方法时直接将参数传进去 --> <button @click="increment(n)">+</button> <button @click="decrement(n)">-</button> </div> </template> <script> export default { name:'Count', data() { return { n:1, } }, methods: { ...mapActions({incrementOdd:'jiaOdd', incrementWait:'jiaWait'}) // 对象写法 } } </script> 如果组件中方法名和actions中方法名同名,则在`mapActions`中同样可以使用数组写法。 同样的,可以使用`mapMutations`简写`$store.commit`: <template> <div> <!-- 使用mapMutations时,需要在调用方法时直接将参数传进去 --> <button @click="incrementOdd(n)">当前求和为奇数再加</button> <button @click="incrementWait(n)">等一等再加</button> </div> </template> <script> export default { name:'Count', data() { return { n:1, } }, methods: { // mapMutations同样有对象写法、数组写法 ...mapMutations({increment:'JIA', decrement:'JIAN'}), } } </script> mapActions和mapMutations使用时,若需要传递参数:需要在模板中绑定事件时传递好参数,否则参数是事件对象。 #### 六、模块化和命名空间 #### 目的:让代码更好维护,让多种数据分类更加明确。 示例:修改store的`index.js` // 定义count组件用到的 const countOptiosn = { namespaced: true, actions: { jia(context, value) { // console.log('actions的jia调用了', context, value); context.commit('JIA', value); }, jian(context, value) { context.commit('JIAN', value); }, jiaOdd(context, value) { if(context.state.sum % 2) { context.commit('JIA', value) } }, 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) { state.sum -= value } }, state: { sum:0, school: '庞各庄小学', subject: '数学' }, getters: { bigSum(state) { return state.sum * 10; } } } // 定义person组件用到的 const personOptions = { namespaced: true, actions: { addLiSi(context, value) { if(value.name === '李四') { context.commit('addUser', value); } else { alert('只能输入李四进行添加') } } }, mutations: { addUser(state, value) { state.personList.unshift(value); } }, state: { personList: [{ id:'001', name:'张三'}] }, getters: { } } // 使用Vuex插件 Vue.use(Vuex) // 创建并暴露store export default new Vuex.Store({ // 使用modules进行暴露 modules: { countOptions: countOptions, personOptions: personOptions } }); 在组件中使用map读取命名空间的数据: export default { name:'Count', methods: { // 调用countOptions命名空间的mutations ...mapMutations('countOptions',{ increment:'JIA', decrement:'JIAN'}), // 调用countOptions命名空间的actions ...mapActions('countOptions',{ incrementOdd:'jiaOdd', incrementWait:'jiaWait'}) }, computed: { // 读取countOptions命名空间的state ...mapState('countOptions',['sum', 'school','subject']), // 读取countOptions命名空间的getters ...mapGetters('countOptions',{ bigSum:'bigSum'}) } } 在组件中直接读取命名空间的数据: export default { name: 'Person', data() { return { name: '' } }, computed: { personList() { // 读取personOptions命名空间的state数据 return this.$store.state.personOptions.personList; }, countSum() { // 读取countOptions命名空间的getters数据 return this.$store.getters['countOptions/bigSum'] } }, methods: { addUser() { // 调用personOptions命名空间的mutations方法 this.$store.commit('personOptions/addUser', { id:nanoid(), name: this.name}); this.name = ''; }, addLiSi() { // 调用personOptions命名空间的actions方法 this.$store.dispatch('personOptions/addLiSi',{ id:nanoid(), name: this.name}); this.name = ''; } } } **先赞后看,养成习惯!!!^ \_ ^ ❤️ ❤️ ❤️ 码字不易,大家的支持就是我的坚持下去的动力。点赞后不要忘了关注我哦!** [vuex.png]: https://img-blog.csdnimg.cn/img_convert/24fc18cbcaee9cb120981344224f70f1.png
相关 28-vuex vuex 一、vuex 专门在vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方 深碍√TFBOYSˉ_/ 2023年10月08日 18:17/ 0 赞/ 16 阅读
相关 Vuex 一、vuex vuex是实现组件状态(数据)管理的一种机制,可以方便的实现组件之间数据的共享。 1. 安装vuex npm install Vuex --s 蔚落/ 2022年10月28日 15:29/ 0 赞/ 193 阅读
相关 vuex 原文 https://segment.com/a/119000000501564 原文: [Learn Vuex by Building a Notes App][] ,有删 朱雀/ 2022年05月30日 00:05/ 0 赞/ 283 阅读
相关 vuex 转自: https://segmentfault.com/a/1190000009404727 如果你在使用 `vue.js` , 那么我想你可能会对 vue 组件之 以你之姓@/ 2022年05月26日 02:13/ 0 赞/ 260 阅读
相关 Vuex Vuex 是⼀个专为 Vue.js 应⽤程序开发的状态管理模式。它采⽤集中式存储管理应⽤的所有组件的状 态,并以相应的规则保证状态以⼀种可预测的⽅式发⽣变化。 谁践踏了优雅/ 2022年05月14日 04:18/ 0 赞/ 299 阅读
相关 vuex vuex在项目中维护一个状态,在项目中的作用是一个唯一的数据源, 相当于全局对象,各个组件共享这一个对象 初始化一个新项目 vue init webpack myv 快来打我*/ 2022年04月12日 05:56/ 0 赞/ 300 阅读
相关 vuex—1vuex初始 1.vuex是什么 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4 落日映苍穹つ/ 2022年01月21日 03:37/ 0 赞/ 294 阅读
相关 vuex 自己的理解: 一: 第一种 state mutations actions getters 集中式管理 Vuex 是一个专为 Vue.js 应用程序开发 系统管理员/ 2021年08月28日 01:12/ 0 赞/ 495 阅读
相关 vuex > Vuex称为Vue的状态管理工具,也是多组件状态共享的工具 > > Vuex相当于是Vue的一个集中式的存储仓库 > > 它存储的是数据 【 状态 】 > 蔚落/ 2021年07月25日 15:08/ 0 赞/ 517 阅读
相关 Vuex Vuex 1. 什么是vuex Vuex 是一个专为 Vue.js 应用程序开发中管理的一个模式。 通过创建一个集中的数据存储,方便程序中的所有组件进行 青旅半醒/ 2021年07月24日 18:56/ 0 赞/ 668 阅读
还没有评论,来说两句吧...