vuex

作者: 索伯列夫 | 来源:发表于2018-11-29 23:18 被阅读0次

    vuex

    vuex是状态管理模式。

    回顾下组件间的通信

    需求:比如在我们的博客中,每个组件中都需要用户的登录状态以及登录信息(多个视图依赖于同一状态,来自多个视图的行为需要变更同一状态),这个时候,就可以使用vuex来维护这个状态。

    vuex的核心就是仓库store,其实就是一个容器,包含应用中的很多状态(state),以及管理状态的方法。vuex的状态存储是响应式的。

    const store = new Vuex.Store({
        state: {
            isLogin: false
        },
        getters:{},
        mutations:{},
        actions:{}
    })
    

    下面介绍核心概念

    一、State

    state翻译为状态,就是需要维护的状态,在上边例子已经展示。

    问题:如何获得vuex状态?

    我们上边已经说了,vuex的状态存储是响应式的。

    vue文档中,data中,有这么一句话:大概来说,data 应该只能是数据 - 不推荐观察拥有状态行为的对象。

    那么,如何获取呢?我们么可以通过计算属性返回某个状态。

    计算属性,是用来处理逻辑运算的

    // 创建一个 Counter 组件
    const Counter = {
      template: `<div>{{ count }}</div>`,
      computed: {
        count () {
          return store.state.isLogin
        }
      }
    }
    

    那么,如果我们有很多组件,这样,太烦了!

    vuex提供了store选项,将状态从根组件注入到每个子组件中。然后我们在子组件中,就可以通过this.$store访问。(如何访问,当然还是通过computed属性访问)

    const app = new Vue({
      el: '#app',
      store
    })
    

    感觉这俩没啥区别?

    区别挺大的:要是我们的组件比较多,注入之后,就不要在组件中一个一个导入了。

    辅助函数mapState

    用处:当一个组件需要获取多个状态的时候,如果我们将每一个都声明为计算属性,真的会很烦,辅助函数可以帮我们简化这个过程。

    比如,在我们的博客中,要维护的状态有用户的登录状态以及用户的登录信息:

    const store = new Vuex.Store({
        state: {
            isLogin: false,
            user: {}
        }
    })
    

    辅助函数的用法:

    // 在单独构建的版本中辅助函数为 Vuex.mapState
    import { mapState } from 'vuex'
    
    //当映射的计算属性名称和state中状态名称相同时,这么用
    //就是this.isLogin = store.state.isLogin
    computed: mapState([
      'isLogin',
      'user'
    ])
    //简化上边的写法,使用对象展开符
    computed: {
      ...mapState({
        'isLogin','user'
      })
    }
    

    二、Getter

    getter就像store的计算属性一样。

    比如我们在state维护了一个数组,我们将state的数据做一些处理,再使用。按照我们刚才说的,当任何一个组件需要使用处理后的数据时,都需要把这个过程再重复一次,显然是不划算的。

    如果我们能在store中将数据处理好,再暴露出来,岂不是更好。

    这就是getter的用途。

    在我们的博客项目中,为什么也使用getter呢?

    我们的状态很简单,只有isLogin/user,用来存储用户的登录状态以及信息。但是麻烦的是,我们分了模块。

    store

    ---modules

    ------auth.js

    ------blog.js

    ---index.js

    这样依赖,每次实际上都是看到的状态state->auth->isLogin/user,这样的结构麻烦,不方便访问,所以才将其放到getter中,getter和state是同级的。直接用就可以

    const getters = {
      isLogin: state=>state.isLogin,
      user: state=>state.user
    }
    

    就像上边的例子一样,Getter接受state作为其第一个参数。

    问题:如何访问getter

    • 通过属性访问
    • 通过方法访问

    mapGetters辅助函数:用法和刚才的都一样

    三、Mutation

    其实,这个问题应该在最开始就提:

    state我们用来定义状态。要是我想要改这些状态呢?

    比如,用户需要注销登录、页面跳转到另一个人的时候,我们需要将用户信息更改掉。这些需求,我们就需要通过mutation来完成。

    Mutation是干啥的?

    文档中说:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。

    mutation示例:

    const store = new Vuex.Store({
      state: {
        count: 1
      },
      mutations: {
        increment (state) {
          // 变更状态
          state.count++
        }
      }
    })
    

    如果想调用mutation,就需要用:

    store.commit('increment')
    

    问题:如果我们在修改状态的时候,需要传入数据呢。

    这就是payload(载荷)。其实就是向store.commit传入额外的参数就行了。

    store.commit('increment', payload)
    

    Mutation必须是同步函数

    在组件中当然也是可以提交mutation的

    this.$store.commit('xxx')

    或者使用辅助函数也是可以

    我没用,需要时,再看文档把

    四、Action

    既然mutation必须是同步的,那么我们就用action处理异步就可以了。

    需要注意:

    • Action提交的是mutation,不可直接变更状态

    我们的博客项目中,我们要维护用户的登录状态以及信息。

    用户登录前后的信息,我们肯定是需要维护的,但是登录、注册之类的要搞成异步啊。那么这些就只能在Action中定义了,当在Action中异步登录成功,就可以开开心心提交mutation修改登录状态了。

    Action的用法:(博客登录异步处理,当然auth.login肯定封装好的)

    const actions = {
        login({ commit }, { username, password }) {
            return auth.login({ username, password })
                .then(
                    res => {
                        commit('setUser', { user: res.data })
                        commit('setLogin', { isLogin: true })
                    })
        }
    }
        
    

    或者看文档的例子,可能更直接一点。

    问题:既然Action都是异步的,那啥时候结束呢?(结束之后,才好去提交mutation啊)

    使用promise就行了...上边例子,auth.login就是返回的promise对象,接着then就行了...

    async/await当然也可以...就是我没太用过

    问题:搞了这么久,Action如何在组件中使用啊?

    使用mapActions在组件的method中映射下,直接this.xxx用就行了

    相关文章

      网友评论

          本文标题:vuex

          本文链接:https://www.haomeiwen.com/subject/sknqcqtx.html