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  #产品模块   

posted @ 2021-04-28 09:40  facelessvoidwang  阅读(67)  评论(0编辑  收藏  举报