大白话理解和初步使用vuex

TL;DR

  • 单向数据流是state => view => action => state,而view是不能直接改变state的
  • vuex就是数据管理,全部数据的修改都必须写成方法,放在mutations,只能经过store.commit('xxmutation')修改数据
  • state/getters/mutations/actions,state注意没有s,代码里mapState/mapGetters/mapMutations/mapActions
  • actions常和请求使用,配合async和await
  • v-model注意在computed那边设置getter setter

单向数据流是啥

<div>
  <h1>{{title}}</h1>
  <button @click="handleClick">将标题第一个字母大写</button>
<div>
复制代码
  • 大白话版:js的data里写了title => h1那边能显示出来,点击按钮 => js里method执行 => data的title的第一个字母大写了 => h1那边再次显示出来
  • 专业名词版:state => view => action => state (和上面一一对应,感觉下)
  • 图片版:
    单向数据流的解释

其实数据不复杂的状况下,method就够用的。数据复杂以后,就有点云里雾里了。固然组件传递数据很麻烦的状况下,vuex也是方便不少。css

vuex,其实就是管理数据的,全部数据的变化都必须经过方法add(1),不能直接xx.a=4这种。而后就是专有名词和具体用法须要记忆了。html

vuex的专业名词

vuex的官网vuex的apivue

vuex的专业名词:ios

  • store,看代码new Vuex.Store({state:{},mutations:{}}),store是仓库,存着数据,存着改变数据的方法。
  • state,就是数据,至关于datastate:{title:'hi'}
  • getter,state派生出一些状态,至关于computed,但computed是经过this拿到data,而这里是经过参数访问store的state和getters,getters:{ doneTodosCount: (state,getters)=>{return getters.doneTodos.length} }
  • mutation,相似于事件,至关于method,仍是经过参数拿到state,参数直接放后面,mutations:{ add(state,n){ state.count + n } },调用的时候,store.commit('add',10),发现没,传方法名和参数就能够了,不用传state~
  • action,上面的mutation只能同步,若是有异步,就须要用action了,可是改变数据,只能commit(mutation),action的参数和上面都不同,其是store实例,能够拿到store因此的东西,但通常commit居多,actions:({ add({commit}){commit('add')} }),触发的方式store.dispatch('add'),这样感觉不到异步的特殊性,换种方式
actions: {
  incrementAsync ({ commit }) {
    setTimeout(() => {
      commit('increment')
    }, 1000)
  }
}
复制代码

action这边,其实特别重要,由于请求基本都是异步的,这边写下,结合请求使用actionvuex

state:{
  listData:[]
},
mutations:{
  setListData(state,data){
    state.listData = data
  }
},
// 另外的文件里,export function getList(){ return axios.get('/list').then(res => res.data)}
actions: {
  async setListData ({ commit }) {
    commit('setListData', await getList())
  },
  async setOtherListData ({ dispatch, commit }) {
    // 若是有串联请求 先请求这个
    await dispatch('setListData')
    commit('setOtherListData', await getOtherList())
  }
}

// 顺便写下 若是延时改变
actions: {
  actionA ({ commit }) {
    // 处理异步操做 当选promise
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('someMutation')
        resolve()
      }, 1000)
    })
  },
  actionB ({ dispatch, commit }) {
    return dispatch('actionA').then(() => {
      commit('someOtherMutation')
    })
  }
}
// 组件里 1s以后变值
store.dispatch('actionA').then(() => { ... })
// 或者
store.dispatch('actionB')
复制代码
  • module,全部的状态都在一个store里,可能渐渐就庞大了,和css相似,能够将store分割成模块,每一个模块有本身的state、mutation、action、getter甚至是嵌套子模块。
const moduleA = { state: { ... }, mutations: { add(state,n){state.count+n} }, actions: { ... }, getters: { ... } }
const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } }
const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  },
  state:{}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
复制代码

代码里怎么使用vuex

首先store是挂载在vue实例上的,因此全部的组件都能访问到store,new Vue({store})axios

组件里访问state

/* xx.vue v1.0.0 */
computed: {
  count () {
    // count就是在store那边
    // Vuex 经过 store 选项,提供了一种机制将状态从根组件“注入”到每个子组件中,这样子组件经过this.$store就能够访问
    return this.$store.state.count
  },
  isLogin () {
    return this.$store.state.isLogin
  }
}

/* 可是当属性不少的时候,这样写太冗余了 用数组简化下 v2.0.0 */
let res = {}
['count', 'login'].map(prop => { res[prop] = () => this.$store.state[prop] })
// 用的时候
computed:{...res}
 
/* 索性能够定义成一个方法 v3.0.0 */
function mapState(propArr){
  let res = {}
  propArr.map(prop => { res[prop] = () => this.$store.state[prop] })
  return res
}
// 用的时候
computed:{...mapState(['count', 'login'])}

/* 固然咱们能想到的,vuex早就替咱们想到了,因此vuex本身提供了mapState v4.0.0 */
// 固然mapState还能够对象形式,能够去官网看看
import { mapState } from 'vuex'
computed:{...mapState(['count', 'login'])}
复制代码

组件里访问getters

用法同state,不赘述。api

import { mapGetters } from 'vuex'
computed:{...mapGetters(['count', 'login'])}
复制代码

组件里访问mutations

其实知道state的用法,这边就简单多了,两种形式,下面也写个例子:数组

// mutation怎么写的 回忆下 add(state,n){state.count+n}

/* 1. 直接组件里 this.$store.commit('add',1) */

/* 2. 组件里 把mutation放进methods */

methods:{
  add (n) {
    this.$store.commit('add', n)
  }
}
// 多个的话
import { mapMutations } from 'vuex'
methods:{
  ...mapMutations(['add'])
}

复制代码

组件里访问actions

用法同mutations,不赘述。promise

/* 1. 直接组件里 this.$store.dispatch('add',1) */

/* 2. 组件里 把actions放进methods */
import { mapActions } from 'vuex'
methods:{...mapActions(['add'])}
复制代码

特别注意v-model

v-model会直接改变数据,违背了vuex,因此不能像以前那样写,换个写法异步

// <input v-model="message">

// store.js
mutations: {
  updateMessage (state, message) {
    state.obj.message = message
  }
}

// xx.vue
computed: {
  message: {
    get () {
      return this.$store.state.obj.message
    },
    set (value) {
      this.$store.commit('updateMessage', value)
    }
  }
}
复制代码

vuex使用必须记住的

  • 应用层级的状态应该集中到单个 store 对象中。

  • 提交 mutation 是更改状态的惟一方法,而且这个过程是同步的。

  • 异步逻辑都应该封装到 action 里面。

相关文章
相关标签/搜索