博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Vuex从入门到精通(一)
阅读量:6733 次
发布时间:2019-06-25

本文共 4856 字,大约阅读时间需要 16 分钟。

hot3.png

状态管理

状态的初始化

状态管理,我们应该并不陌生。

举个例子,超市里新进了一批商品,管理员给这些商品分类,建立索引,然后按照顺序放入货架的过程就是最简单的状态管理。

let goods1 = {  category: 'fruit',  name: 'apple',  quantity: 5}let goods2 = {  category: 'supplies',  name: 'toothbrush',  quantity: 5}let goods3 = {  category: 'clothes',  name: 'sweater',  quantity: 5}

简单归类后 :

let shop = {  goods: {    fruit: [{ name: 'apple', quantity: 5 }],    supplies: [{ name: 'toothbrush', quantity: 5 }],    clothes: [{ name: 'sweater', quantity: 5 }]  }}

这样,当我们需要某一商品时,很容易根据类目检索到这个商品 :

console.log(shop.goods.fruit.find(f => f.name === 'apple'))//-> { name: 'apple', quantity: 5 }

 

状态的改变

当有顾客前来购买商品时,我们需要类似的操作来减少被购买商品的数量 :

shop.goods.fruit.find(f => f.name === 'apple').quantity --

然而在成千上万的交易量背后,你不知道这些商品被购买的详细情况,你甚至不知道上周卖出了多少苹果,你也就无从得知下周该进多少。

所以你需要一个账目来记录商品购买明细 :

let account = {  appleSold (value) {    console.log("apple sold " + value)    shop.goods.fruit.find(f => f.name === 'apple').quantity -= value  }}

当卖出苹果时,POS机“滴”一声,记录生成了 :

account.appleSold (5)//-> apple sold 5

 

最简单的store

于是,我们得到了一个最简单的store :

let shop = {  goods: {    fruit: [{ name: 'apple', quantity: 5 }],    supplies: [{ name: 'toothbrush', quantity: 5 }],    clothes: [{ name: 'sweater', quantity: 5 }]  },  account: {    appleSold (value) {      console.log("apple sold " + value)      shop.goods.fruit.find(f => f.name === 'apple').quantity -= value    },    funcN () { }  }}

 

由此可知,状态管理可以帮助我们更友好的改变状态,同时,跟踪状态变化的轨迹。

 

Vue(x) er 须知

开始

Vuex 官方文档:

 

Vuex最核心的概念 :

  1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
  2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

下面对此拓展:

对象引用

下面这两段代码将输出什么? 先不要往下看, 自己写一下

let store = {  state: {    msg: "welcome"  }}, copy = store.state;store.state = {  hello: "world"};console.log(Object.keys(copy));
let store = {  state: {    msg: 'welcome'  }}, copy = store.state;store.state.hello = "world";console.log(Object.keys(copy))

 

结果如下(如果你都答对了,那么理解和上手Vuex将会很轻松) :

//-> ["msg"]//-> ["msg", "hello"]

 

提交和分发

vuex 只是一个工具,或许过了这段时间,过了这个项目,你就不会再用它。

我们要记住的是它留给我们的启示:

不要直接更改状态, 而是通过提交(commit)和分发(dispatch)的方法通知管理者改变对象状态,这是大型项目和复杂状态管理的最佳实践。

 

Vuex 核心概念

一个完整的 Vuex Store

/** * index.js */import axios from 'axios'const store = new Vuex.Store({  state: {    counter: 0  },  getters: {    counter: state => state.counter  },  // 可处理异步请求, dispatch 触发  actions: {    askPermission ({commit}) {      axios.get('/url').then((res) => {        if(res.data.permission)          commit('addCounter')      }).catch((err) => {        console.log('Error: in process "Ask permission".\n Detailed: ' + err)      })    }  },  // 同步, commit 触发  mutations: {    addCounter (state) {      state.counter ++    }  }})

PS: 仔细研究一下 dispatch & actions,  commit & mutations,  是否有一种似曾相识的感觉?

Look, 看这对 emit & on (事件机制),同样的事件类型,同样的回调函数。

 

State

单一状态树

Vuex使用单一状态树,一个state对象包含全部应用层状态,使得一个应用只有唯一数据源(SSOT, Single Source of Truth)

这对模块化并不造成影响

state: {  moduleA: {      },  moduleB: {      }}

 

Getter

state: {  prop: ''}

你可以使用store.state.prop直接读取状态的值, 当然也可以使用Getter :

getters: {  prop = state => state.prop}

使用Getter的好处在于,你可以从state中派生出一些状态 :

getters: {  prop = state => state.prop,  fixedProp = state => state.prop || '暂无'}

 

Mutation

Vuex 中的 mutation 类似于事件,有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler),回调函数的接受state作为第一个参数,我们在这里修改状态(state)

state: {  counter: 0},mutations: {  addCounter (state) {    state.counter ++  },  addCounter (state, payload) {    state.counter += payload.value  }}

通过 commit 通知状态变化

store.commit('addCounter')store.commit('addCounter', {value: 1})

 

Action

类似于mutation,不同在于

  • 只能通过 commit mutation 通知状态变化
  • mutation 只能包含同步操作,而 action 可以包含异步操作(比如, 在这里可以执行ajax请求)
actions: {  askPermission ({commit}) {    axios.get('/url').then((res) => {      if(res.data.permission)        commit('addCounter')    }).catch((err) => {      console.log('Error: in process "Ask permission".\n Detailed: ' + err)    })  },  askPermission ({commit}, payload) {    axios.get('/url', { params:payload }).then((res) => {      if(res.data.permission)        commit('addCounter')    }).catch((err) => {      console.log('Error: in process "Ask permission".\n Detailed: ' + err)    })  }}

通过 dispatch 通知状态变化

store.dispatch('askPermission')store.dispatch('askPermission', { author: "lonelydawn" })

 

Module

Vuex 允许我们将store分割成模块,每个模块拥有自己的state, mutation, action, getter, 甚至是嵌套子模块 :

const store = new Vuex.Store({  modules: {    a: {      state: {},      mutations: {        addCounter(state) {}      },      actions: {},      getters: {}    },    b: {      namespaced: true, // 建立命名空间      state: {},      mutations: {        addCounter(state) {}      },      actions: {}    }  }})store.state.astore.state.b//  提交 给 模块 a 的 mutationsstore.commit('addCounter')//  提交 给 模块 b 的 mutationsstore.commit('b/addCounter')

 

最后

 Vuex 的基本用法已经介绍完了。

相关内容 :

 

在下列内容中, 我将 演示如何使用 vue + vuex 以及其他常用组件从入门到实战。

转载于:https://my.oschina.net/lonelydawn/blog/1589708

你可能感兴趣的文章
这里有一些图标资源
查看>>
读心或成现实,OpenBCI要将脑波传感技术用于VR中
查看>>
三年“苏宁之夏”,锐捷无线用才华“闪耀”狂欢夜
查看>>
菜鸟学Linux 第045篇笔记 openSSH
查看>>
Win8Metro(C#)数字图像处理--2.5图像亮度调整
查看>>
php安装php-redis模块
查看>>
无线网络破解________破解wap密码..............
查看>>
Matlab实现求a到b被c整除的个数
查看>>
Page Object设计模式
查看>>
RMI 相关知识
查看>>
Spring中@Async用法总结
查看>>
Spring data 如何定义默认时间与日期
查看>>
php 重置数组索引,兼容多维数组
查看>>
ARC 之内存转换
查看>>
输入密码与确认密码的匹配提示
查看>>
POI获取JXL生成的Excel带公式Cell返回空
查看>>
互联网项目经理工作到底是一种什么样的体验?
查看>>
php header 头输出 不同文档
查看>>
WIN7开发无法通过IP(127.0.0.1/10.4.250.107)而只能通过localh...
查看>>
Folding Views
查看>>