zoukankan      html  css  js  c++  java
  • VUE学习笔记--vuex

    1、vuex是干啥的

    官网的说法是 vuex是一个专为vue应用程序开发的状态管理模式。
    通俗的说,是用来管理组件间共享变量的。

    1、我们能自己封装一个对象来管理共享变量吗?

    当然可以,只是除了要管理共享变量,我们也不能抛弃vue最大的特点“响应式”,如果再加上响应式,其实这就是vuex了。我们当然可以自己实现这些功能,但一般来说官方的轮子总是比我们自己造的要好一些的。

    2、有哪些状态需要在组件间共享呢?

    没有严格的定义;一般来说,比如用户的登录状态、名称、头像、地理位置信息,或者购物车、收藏等内容是系统内很多地方需要访问的内容,这些内容就可以放到vuex中,既方便了处理,也仍然有响应式。一些临时性质的,仅仅在一两个组件共享的对象,一般不建议放到vuex中,以避免vuex过于复杂。

    2、vuex的使用

    跟普通插件一样:

    //1、安装插件   
    Vue.use(Vuex)   
    //2、创建对象   
    const store = new Vuex.Store({
        state:{ //单一状态树
            
        },
        mutations:{},//用于提交的方法
        actions:{}, //异步操作
        getters:{}, //类似于计算属性
        modules:{}  //模块划分
    })
    //3、导出store对象
    export default store
    
    
    //4、使用
    new Vue({
        el: '#app',
        store,
        render: h => h(App)
    })
    
    //5、完成4以后会在原型上绑定数据 Vue.prototype.$store = store ;我们可以在需要的地方$store来引用;
    

    为了处理并发修改的问题,vuex设计了一套状态机制,用来跟踪数据状态变更;虽然可以直接修改数据,但仍强烈建议通过状态机制修改。

    3、状态管理的使用

    vuex的状态关系图:
    vuex状态图
    异步操作一般在actions进行,需要操作状态对象,则通过commit方法调用Mutations中的方法。这样操作,会将状态变更纳入vuex的状态跟踪机制,利用vue提供的插件Devtools可以清楚的看到数据状态的变化。
    以点击按钮,对某数值进行递增为例,正确用法为:

    //在vuex中,声明变量跟方法
    const store = new Vuex.Store({
        state:{
            counter: 1000,
            students:[
            {name:'zhangsan',age:10},
            {name:'lisi',age:15},
            {name:'wangwu',age:20},
            {name:'maliu',age:25},
            {name:'zhengqi',age:30}
            ]
        },
        mutations:{
            //方法
            increment(state){
                state.counter ++
            },
            addStudent(state, stu){
                state.students.push(stu);
            }
        },
        actions:{},
        getters:{
            //年龄大于20的学生列表
            more20stu(state){
              return state.students.filter(s => s.age > 20)  
            },
            //年龄大于20的人数,第二个参数为getter
            more20studentLength(state, getter){
                return getter.more20stu.length
            },
            //可以返回函数
            moreAgeStu(state){
                return function(age){
                    return state.students.filter(s => s.age > age)
                }
            }
        },
        modules:{}
    })
    
    //在vue中用方法进行响应
    export default {
        methods:{
            addition(){
                //注意这里是commit去调用的
                this.$store.commit('increment')
            }
        }
    }
    

    单一状态树:Single Source of Truth,直译应为单一数据源。 vuex是可以建多个store对象的,但这不方便管理维护,vuex建议只用一个store实例,这个实例就是所谓的单一状态树。

    mutations: 定义方法,用于响应外部提交的方法;只有通过这种方式对state数据进行的访问,才会被纳入状态管理,vue官方强烈建议采用该种方式。通过mutation更新数据时,也可以额外携带一些参数,这些参数被称为载荷(payload);
    getters: 跟cumputed类似,可以获取变化的属性;方法有两个参数,第一个为state本身,第二个为getter;除了可以返回计算结果,也可以返回函数。

    4、响应规则

    Vuex的store中的state是响应式的,当state中的数据发生变化时,vue组件会自动更新。但这要求我们必须遵守一些vuex对应的规则:

    1、提前在store中初始化好所需的属性
    2、当给state中的对象添加新属性时,使用如下方式:
    a、使用Vue.set(obj, '属性名', '属性值')
    b、用新对象给旧对象重新赋值

    另外,通常情况下,Vuex要求我们Mutation中的方法必须是同步方法,主要原因是当我们使用devtools时,devtools可以帮我们捕捉mutation的快照,但如果是异步操作,那么devtools将不能很好的追踪这个操作什么时候完成。但如果的确需要在vuex中进行一些异步操作,该如何实现呢,使用action!action跟mutation类似,只是用来处理异步操作。
    需要注意的是,在action进行了异步操作之后,不能跳过mutation直接修改数据状态,仍要调用mutation中的方法,来实现数据状态的监控。这里可以跟promise结合,使代码更优雅。
    提交mutation用commit,提交action用dispatch。

    5、modules模块划分

    modules 模块划分,避免状态过多问题;

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    const moduleA = {
     state:{
       a:{name:"张三",age:20}
     },
     mutations:{
       updateName(state){
         state.a.name = '李四'
       }
     }
    }
    
    const store = new Vuex.Store({
     state:{
       counter: 1000,
       students:[
         {name:'zhangsan',age:10},
         {name:'lisi',age:15},
         {name:'wangwu',age:20},
         {name:'maliu',age:25},
         {name:'zhengqi',age:30}
       ]
     },
     mutations:{
       increatment(state){
         state.counter ++;
       },
       decrement(state){
         state.counter --;
       }
     },
     actions:{},
     getters:{
       powerCounter(state){
         return state.counter * state.counter
       }
     },
     modules:{
       obj: moduleA
     }
    })
    
    export default  store
    
    

    使用可以如下:

    <span>moduleA:{{$store.state.obj.a.name}}</span>
    

    6、代码结构

    将vuex的各个部分,比如action,mutation等抽取为独立的文件,modules也单独文件夹处理,参考目录如下:

    |-- index.html
    |-- main.js
    |-- api
    |  |-- # 抽取出api请求
    |
    |-- components
    |  |-- App.vue
    |  |
    |  |-- ...
    |
    |-- store
       |-- index.js      #组装并导出store的地方
       |-- actions.js     #根级别的action
       |-- mutations.js    #根级别的mutation
       |-- modules
          |-- cart.js    #购物车模块
          |-- product.js  #产品模块

  • 相关阅读:
    苏宁11.11:系统拆分的一些经验谈
    双11超级工程—阿里巴巴数据库技术架构演进
    阿里的Json解析包FastJson使用
    JSONObject、JSONArray、Map、JavaBean的相互转换
    method.invoke(...)反射点
    Spring中的CharacterEncodingFilter
    数组去重Demo引出的思考
    HDU 5095--Linearization of the kernel functions in SVM【模拟】
    GUI编程及文件对话框的使用
    Android中的指纹识别
  • 原文地址:https://www.cnblogs.com/nevermorewang/p/14711894.html
Copyright © 2011-2022 走看看