• Vue-管理状态仓库Vuex



    什么是vuex

    Vuex是一个状态管理工具,采用集中式存储管理应用的所有组件的状态,并且以相应的规则保证状态可预测的方式发生改变。本质就是把组件的共享状态和触发修改状态的函数抽离出来,这样就能获得状态或者触发行为。

    Vuex的特点

    1.能够在vuex中集中管理共享的数据,易于开发和后期维护

    2.能够高效地实现组件之间的数据共享, 提高开发效率

    3.存储在 vuex中的数据都是响应式的,能够实时保持数据与页面的同步

    4.一般情况下,只有组件之间共享的数据,才有必要存储到vuex中;

    5.对于组件中的私有数据,依旧存储在组件自身的data中即可.

    什么情形下适合使用Vuex?

    如果不打算开发大型单页应用,使用Vuex就会变得很冗余,就会有“牛刀杀鸡”的感觉,因为它会附带很多概念。这种情况下使用store模式就足够了。

    如果正在开发一个中大型的单页应用,Vuex是更好的选择。

    引入Vuex

    1.手动下载引入
    安装:

    npm i vuex --save
    
    导入:
    
    import Vuex from "vuex"
    
    Vue.use(Vuex)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    创建仓库:

    const store=new Vuex.Store({
    
               state:{msg:"我就是所有共享的数据"}
    
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5

    把仓库挂载到vm对象:

    new Vue({
    
         render(h){return h(app)},
    
         router,
    
         store//挂载以后  所有的组件就可以直接从store中获取全局数据
    
    }).$mount( "#app")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.使用Vue脚手架安装

    vue create app

    选择配置vuex
    再main.js文件夹下引入store

    import store from './store'
    
    • 1

    挂载到vm对象,跟上面一样

    State

    创建state状态,状态就是那个存数据的对象

    const store=new Vuex.store({
    
               state:{data:"所有共享的数据"}
    })
    
    • 1
    • 2
    • 3
    • 4

    2.组件中访问数据

    this.$store.state.msg
    
    • 1

    Getter

    getter就像是store的计算属性,它会传入state对象供我们操作

    设计

      getters: {
        //当作计数属性使用
        mycomput(state){
          //计算总价
          return state.arr.reduce((n1,n2)=>{return n1+n2.price*n2.count},0)
        }
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    使用

    this.$store.getters.mycomput
    
    • 1

    Mutation

    组件中希望更改 Vuex 的 store 中的状态(数据)的唯一方法是提交 mutation
    不要用赋值表达式直接在组件中给store设置新数据
    这样设计的原因是,只有通过mutation来更新数据,它才会去帮我们通知所有使用数据的组件更新数据 刷新UI

    注意:一条重要的原则就是要记住 mutation 必须是同步处理
    为什么必须是同步处理?
    因为每一条mutation都会被devtools记录,devtools需要捕捉前一状态、后一状态。如果mutation函数中如果有异步函数,devtools无法得知异步函数什么时候执行,也就无法记录状态的变更。

    设计:

    mutations: {
        mychange(state,obj){
           方式一:state.arr[0].price=obj  
           方式二:state.arr[0].price=obj.n   
        }
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用:

    //直接触发并传值(提交载荷)
    方式一:this.$store.commit("mychange",10)  
    //可以以一个对象的形式传入
    方式二:this.$store.commit("mychange",{n:10})  
    方式二另一种写法:this.$store.commit({type:"mychange",n:10})  //type属性值是需要触发的事件名,n则为obj下面的键值对
    
    • 1
    • 2
    • 3
    • 4
    • 5

    案例:

    //vuex文件中
    export default new Vuex.Store({
      state: {
        msg:"所有组件共享的数据",
        arr:[{id:1,price:1,count:22},{id:2,price:2,count:25},{id:3,price:1,count:26}]
      },
      getters: {
        //当作计数属性使用
        mycomput(state){
          //计算总价
          return state.arr.reduce((n1,n2)=>{return n1+n2.price*n2.count},0)
        }
      },
      //更改状态
      mutations: {
        mychange(state,obj){
              state.arr[0].price=obj
        }
      },
      
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    //home组件中
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    //Box1组件中
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    //Box3组件中
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    请添加图片描述

    Action

    actions选项的功能和mutations选项类似,但是也有不同之处:
    Actions提交的是mutation,而不是直接变更状态;
    Actions里面可以包含任意的异步操作;

    所有的Action函数都接受一个与store实例具有相同方法和属性的context对象,这里的context对象指向当前的仓库,也就是store。因此在函数体中可以调用context.commit提交触发状态,相当于store.commit。这里注意,context对象不是store对象本身,这里相当于复制体。

    设计:

      actions: {
        mychange2(ctx,obj){
          setTimeout(()=>{
             //提交载荷
             ctx.commit("mychange",obj)
          },1000)
        }
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    使用:

    //直接分发
    this.$store.dispatch("mychange2", 20)
    //以对象形式
    this.$store.dispatch('mychange2',{n:20})
    this.$store.dispatch({type: 'mychange2',n:20})
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Module

    可用于业务分块开发:
    由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
    为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter

    //分块设计:
    const moduleA = {
      namespaced: true,//局部命名空间(让state的中变量与其他模块中的同名变量不冲突)	
      state: { msg:1 },
      mutations: { change(state,n){state.msg=n} },
      actions: { change(context,n){context.commit("change",n)} },
      getters: { x(state){return state.msg} }
    }
    
    const moduleB = {
       namespaced: true,//局部命名空间	
       state: {  msg:1 },
       mutations: { change(state,n){state.msg=n} },
       actions: { change(context,n){context.commit("change",n)} },
       getters: { x(state){return state.msg} }
    }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })
    
    //组件中的使用:
    this.$store.state.a.msg // -> moduleA 的状态
    this.$store.state.b.msg // -> moduleB 的状态
    this.$store.commit("a/change",100)-> moduleA 的mutations
    this.$store.commit("b/change",200)-> moduleB 的mutations
    this.$store.getters["a/x"]-> moduleA 的getters
    this.$store.getters["b/x"]-> moduleB 的getters
    this.$store.dispatch("a/change",100)-> moduleA 的actions
    this.$store.dispatch("b/change",200)-> moduleB 的actions
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    总结

    使用vuex步骤:

    • 引入vuex;
    • 全局注册Vuex,Vue.use(Vuex);
    • 创建一个Vuex仓库,仓库里面可以包含五个选项:state(状态)、getters(对状态的过滤)、mutations(状态修改)、actions(异步提交修-改状态信息)、modules(模块);
    • 触发mutation:通过commit触发仓库中的状态更新,store.commit(“对应的mutation”);
    • 将仓库注入到Vue对象中,也可以挂载到Vue对象原型上;
  • 相关阅读:
    Redis为什么要使用SDS作为基本数据结构
    java继承简介说明
    机器学习算法——聚类3(k均值算法)
    caffe安装探索整理
    野生程序员的成长之路(续)--团队需要什么样的管理者?
    自定义md-loader来简单高效的维护组件文档
    PMP 报名有什么条件?容易满足吗?
    【操作系统】I/O软件层次结构
    华为面试宝典OD
    【金融分析】Python:病人预约安排政策 | 金融模拟分析
  • 原文地址:https://blog.csdn.net/qq_56973906/article/details/126860138