vuex

2018-11-29  本文已影响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中定义了,当在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用就行了

上一篇下一篇

猜你喜欢

热点阅读