经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Vue.js » 查看文章
Vue使用Vuex一步步封装并使用store全过程
来源:jb51  时间:2023/1/11 8:38:44  对本文有异议

一、安装Vuex依赖

  1. cnpm install vuex --save

二、一步步封装store

1. main.js中全局引入store仓库(下一步创建)

  1. import store from './store' //引入store
  2. new Vue({
  3. el: '#app',
  4. router,
  5. store, //挂载store,this将自动生成$store属性
  6. template: '<App/>',
  7. components: { App }
  8. })

挂载store,this将自动生成$store属性

2. this.$store

创建store仓库:习惯在src下创建store文件夹,再创建index.js,内容:

  1. import Vue from 'vue';
  2. import Vuex from 'vuex';
  3. Vue.use(Vuex);
  4. const store = new Vuex.Store();
  5. export default store;

此时你已经有了一个空的store全局仓库,没有任何功能,但可以在任何vue实例下使用 this.$store 去访问它。

  • store使用范围均是可以全局使用;
  • let a=1; {a:a}.a 的缩写是 {a}.a,即当字典的键和值命名一样时,可以省略只写a
  • state、getters、mutations、mutations均是Vuex封装好的特殊变量,以下声明的功能变量均是这些名字,一个好处是store挂载该功能时可以简写(如3-1,本例均如此)。当然你也可直接在store中写功能(如3-2)。

3. this.$store.state

给store仓库读取数据功能:state

  1. /********* 3-1 **********/
  2. import Vue from 'vue';
  3. import Vuex from 'vuex';
  4. Vue.use(Vuex);
  5. const state={ //要设置的全局访问的state对象,赋予初始属性值
  6. themeColor: {val:'blue',opacity:false},
  7. changeThemeCount:0,
  8. cache:''
  9. };
  10. const store = new Vuex.Store({
  11. state
  12. });
  13. export default store;

此时你的store仓库已经有了存取数据的功能,可以用 this.$store.state.themeColor 等数据了。

下面是第二种写法

  1. /********* 3-2 **********/
  2. import Vue from 'vue';
  3. import Vuex from 'vuex';
  4. Vue.use(Vuex);
  5.  
  6. const store = new Vuex.Store({
  7. state:{
  8. //要设置的全局访问的state对象,赋予初始属性值
  9. themeColor: {val:'blue',opacity:false},
  10. changeThemeCount:0,
  11. cache:''
  12. }
  13. });
  14. export default store;

4. this.$store.getters(this. $store.state的升级)

给state功能升级,让他拥有计算能力(类似vue中的computed方法):getters:

  1. import Vue from 'vue';
  2. import Vuex from 'vuex';
  3. Vue.use(Vuex);
  4. const state={ //要设置的全局访问的state对象,赋予初始属性值
  5. themeColor: {val:'blue',opacity:false},
  6. changeThemeCount:0,
  7. cache:''
  8. };
  9. const getters = { //实时监听state值的变化(最新状态)
  10. getThemeColor(state) { //定义函数,返回处理过的val,命名最好有代表性
  11. let hour = new Date().getHours();
  12. // 如果白天则主题色不透明,反之
  13. state.themeColor.opacity = 8 <= hour && hour <= 20;
  14. return state.themeColor
  15. }
  16. };
  17. const store = new Vuex.Store({
  18. state, // 挂载存取数据功能
  19. getters //挂载数据计算功能
  20. });
  21. export default store;

此时使用 this.$store.getters.getThemeColor 获取颜色,将自动根据时间的不同自动设置主题是否有透明的效果

5. this.$store.commit(‘mutations’)

给store仓库使用函数功能(只为操作state数据):mutations - 同步

  1. import Vue from 'vue';
  2. import Vuex from 'vuex';
  3. Vue.use(Vuex);
  4. const state={ //要设置的全局访问的state对象,赋予初始属性值
  5. themeColor: {val:'blue',opacity:false},
  6. changeThemeCount:0,
  7. cache:''
  8. };
  9. const getters = { //实时监听state值的变化(最新状态)
  10. getThemeColor(state) { //定义函数,返回处理过的val,命名最好有代表性
  11. let hour = new Date().getHours();
  12. // 如果白天则主题色不透明,反之
  13. state.themeColor.opacity = 8 <= hour && hour <= 20;
  14. return state.themeColor
  15. }
  16. };
  17. const mutations = {
  18. //自定义改变state初始值的方法,这里面的参数除了state之外还可以再传额外的参数(变量或对象);
  19. clearCatch(state) {
  20. state.cache = "";
  21. state.changeThemeCount= 0;
  22. },
  23. setThemeColor(state,color,opacity){
  24. state.themeColor.val = color;
  25. state.themeColor.opacity = opacity;
  26. state.changeThemeCount++;
  27. }
  28. };
  29. const store = new Vuex.Store({
  30. state, // 挂载存取数据功能
  31. getters, //挂载数据计算功能
  32. mutations // 挂载函数功能
  33. });
  34. export default store;

此时可以使用 this.$store.commit(‘setThemeColor’,‘grey’,‘1’) 了(注意第一个参数是函数名,不是传参给state的,state自己会传,后两个才是对应传参)。

可以主动设置主题色和透明度,操作是同步的,即如果你在同一个组件连续调用多次setThemeColor函数,获取仓库中state.changeThemeCount的值是一样的,下面介绍异步函数。

6. this.$store.dispatch(‘actions’)(this. $store.commit(‘mutations’)的升级)

给store仓库的函数commit功能升级(只为异步操作mutations中的函数):actions - 异步

  1. import Vue from 'vue';
  2. import Vuex from 'vuex';
  3. Vue.use(Vuex);
  4. const state={ //要设置的全局访问的state对象,赋予初始属性值
  5. themeColor: {val:'blue',opacity:false},
  6. changeThemeCount:0,
  7. cache:''
  8. };
  9. const getters = { //实时监听state值的变化(最新状态)
  10. getThemeColor(state) { //定义函数,返回处理过的val,命名最好有代表性
  11. let hour = new Date().getHours();
  12. // 如果白天则主题色不透明,反之
  13. state.themeColor.opacity = 8 <= hour && hour <= 20;
  14. return state.themeColor
  15. }
  16. };
  17. const mutations = {
  18. //自定义改变state初始值的方法,这里面的参数除了state之外还可以再传额外的参数(变量或对象);
  19. clearCatch(state) {
  20. state.cache = "";
  21. state.changeThemeCount= 0;
  22. },
  23. setThemeColor(state,color,opacity){
  24. state.themeColor.val = color;
  25. state.themeColor.opacity = opacity;
  26. state.changeThemeCount++;
  27. }
  28. };
  29. const actions = {
  30. //自定义触发mutations里函数的方法,context与store 实例具有相同方法和属性
  31. setThemeColorAction(context,color,opacity){
  32. context.commit('setThemeColor',color,opacity);
  33. }
  34. };
  35. const store = new Vuex.Store({
  36. state, // 挂载存取数据功能
  37. getters, //挂载数据计算功能
  38. mutations, // 挂载函数功能
  39. actions // 挂载异步函数
  40. });
  41. export default store;

此时可以使用 this.$store.dispatch(‘setThemeColorAction’,‘grey’,‘1’) 了(注意第一个参数是函数名,不是传参给context的,context自己会传,后两个才是对应传参)。

可以主动设置主题色和透明度,操作是异步的,即如果你在同一个组件连续调用多次setThemeColorAction函数,获取仓库中state.changeThemeCount的值就不是一样的。

7. strict严格模式

  1. export default new Vuex.Store({
  2. strict: true,
  3. state: {
  4. ...
  5. },
  6. ...
  7. }

此模式下所有的状态变更(即更新state)必须使用mutation(commit),如果在组件中直接修改state则会报错。这样的好处是所有的state的更新都体现在仓库中,整改方便;使用devTools调试工具时可以跟踪到状态的修改。

三、modules 模块化

第二个模块介绍了store仓库的四个功能:state、getters、mutations和actions,下面介绍第五个功能:modules。

  • 当项目比较大时,一个store中数据会非常多而复杂,不易管理。此时便可建多个“子仓库”,分别对应不同模块做数据的读取和操作。
  • 注意主仓库还是那一个,只要把他的“子仓库”放在主仓库的modules下即可。
  • 子仓库看着很像仓库,其实它并不是store的实例,不是仓库(new Vuex.Store()实例化后的对象才是仓库),只是一个普通js对象(字典)。

1、在store下新建modules文件夹,在modules下新建home.js“子仓库”。

即home.js只管主页下的数据(一般不要分的太细,最多一个页面一个仓库管简洁),下面是home.js代码

  1. //home.js
  2.  
  3. const state={
  4. users:[] //存访问该页面的所有用户
  5. };
  6. const getters={
  7. getUsers(state){ //获取访问该页面的所有用户
  8. // 对数据清理-除去脏数据
  9. if (state.users.includes('*')) delete state.users['*']
  10. return state.users;
  11. }
  12. };
  13. const mutations={
  14. addUser(state,name){ //增加访问用户
  15. state.collects.push(name)
  16. }
  17. };
  18. const actions={
  19. invokeAddUser(context,name){ //触发mutations里面的addUser,传入数据形参name对应到users
  20. context.commit('addUser',name);
  21. }
  22. };
  23. // 注意和仓库的区别
  24. const store = {
  25. // namespaced用于在全局引用此文件里的方法时标识这一个的文件名,使得让人明白这些数据来自哪个仓库
  26. // 即当你需要在别的文件里面使用子仓库(mapStates、mapGetters、mapActions)时,里面的方法需要注明来自哪一个模块的方法
  27. namespaced:true,
  28. state,
  29. getters,
  30. mutations,
  31. actions
  32. }
  33. export default store;

2.“子仓库”创建完成,要让主仓库引用它:

  1. import Vue from 'vue';
  2. import Vuex from 'vuex';
  3. import home from './modules/home.js'
  4.  
  5. Vue.use(Vuex);
  6. const state={ //要设置的全局访问的state对象,赋予初始属性值
  7. themeColor: {val:'blue',opacity:false},
  8. changeThemeCount:0,
  9. cache:''
  10. };
  11. const getters = { //实时监听state值的变化(最新状态)
  12. getThemeColor(state) { //定义函数,返回处理过的val,命名最好有代表性
  13. let hour = new Date().getHours();
  14. // 如果白天则主题色不透明,反之
  15. state.themeColor.opacity = 8 <= hour && hour <= 20;
  16. return state.themeColor
  17. }
  18. };
  19. const mutations = {
  20. //自定义改变state初始值的方法,这里面的参数除了state之外还可以再传额外的参数(变量或对象);
  21. clearCatch(state) {
  22. state.cache = "";
  23. state.changeThemeCount= 0;
  24. },
  25. setThemeColor(state,color,opacity){
  26. state.themeColor.val = color;
  27. state.themeColor.opacity = opacity;
  28. state.changeThemeCount++;
  29. }
  30. };
  31. const actions = {
  32. //自定义触发mutations里函数的方法,context与store 实例具有相同方法和属性
  33. setThemeColorAction(context,color,opacity){
  34. context.commit('setThemeColor',color,opacity);
  35. }
  36. };
  37. const store = new Vuex.Store({
  38. state, // 挂载存取数据功能
  39. getters, //挂载数据计算功能
  40. mutations, // 挂载函数功能
  41. actions // 挂载异步函数
  42. modules:{ // 挂载子仓库
  43. home
  44. }
  45. });
  46. export default store;

此时便有了第一个“子仓库”了!

四、使用仓库

1. 无map系列

适合使用场景较少:

建好仓库,组件中直接使用state、getters、mutations、actions:

  • this.$store.state.*
  • this.$store.getters.*
  • this.$store.commit.*
  • this.$store.dispatch.*

2. map映射系列

适合使用场景频繁:

使用mapGetters、mapActions 和 mapStates之前需要import导入:

  1. import {mapState,mapGetters,mapActions} from 'vuex';

使用ES6新语法-超引用,将某个功能下的数据或方法全部映射出来以供使用,下面是mapState、mapGetters、mapActions的例子:

  1. //这里的...是超引用,映射内容,可以写在computed下、methods下等(一般放在开头)
  2. // 直接从库中取值 - 将库里的users值返回给字典中的users并映射给this组件
  3. ...mapState({
  4. users:state=>state.home.users
  5. }),
  6. // 使用计算属性 - 将库里的users计算后的值返回给字典中的users并映射给this组件
  7. ...mapGetters('home',{
  8. users:'getUsers' //获取清理后的数据
  9. //由于home仓库 namespaced:true,所以第一个参数作为标识
  10. // 不使用标识访问的是主仓库
  11. })
  12. // 使用异步函数 - 以数组中的函数名,从库中对应的函数映射给this组件以供使用
  13. ...mapActions('home',['invokeAddUser'])
  14. // 有某个组件 <span @click='invokeAddUser(name)'></span>
  15. // 或者直接使用 this.invokeAddUser(name)

3. 扩展

mapState映射的三种写法

  1. computed: mapState({
  2. // 箭头函数可使代码更简练
  3. count: state => state.count,
  4.  
  5. // 传字符串参数 'count' 等同于 `state => state.count`
  6. countAlias: 'count',
  7.  
  8. // 为了能够使用 `this` 获取局部状态,必须使用常规函数
  9. countPlusLocalState (state) {
  10. return state.count + this.localCount
  11. }
  12. })
  13. 2、当映射的计算属性的名称与state的子节点名称相同时,
  14. 我们也可以给 mapState传一个字符串数组。
  15. computed: mapState([ // 数组
  16. "count"
  17. ])
  18. 3、仓库中action的第二种接收参数
  19. const actions = {
  20. //自定义触发mutations里函数的方法,{commit}与store 实例具有相同方法和属性
  21. setThemeColorAction({commit},color,opacity){
  22. commit('setThemeColor',color,opacity);
  23. }
  24. };

3. 总结

1、Vuex 是一个专门为 Vue.js 应用所设计的集中式状态管理架构。它借鉴了 Flux 和 Redux 的设计思想,但简化了概念,并且采用了一种为能更好发挥 Vue.js 数据响应机制而专门设计的实现。

2、Vuex 的四个核心概念分别是:

  • The state tree:Vuex 使用单一状态树,用一个对象就包含了全部的应用层级状态。至此它便作为一个『唯一数据源(SSOT)』而存在。这也意味着,每个应用将仅仅包含一个 store 实例。单状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。
  • Getters: 用来从 store 获取 Vue 组件数据。
  • Mutators: 事件处理器用来驱动状态的变化。
  • Actions: 可以给组件使用的函数,以此用来驱动事件处理器 mutations

3、Vuex 应用中数据的流向(Vuex 官方图)

数据流都是单向的组件能够调用 actionaction 用来派发 Mutation只有 mutation 可以改变状态store 是响应式的,无论 state 什么时候更新,组件都将同步更新

最后

以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号