一、vuex介绍

目标
  • 什么是Vuex
  • 为什么学习Vuex
通信方案

组件关系 数据通信
父子关系 父传子:props ; 子传父:$emit
非父子关系 vuex (一种组件通信方案)
Vuex是什么
  • 概念:专门在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应 用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方 式,且适用于任意组件间通信。

  • Vuex 实现了一个单向数据流,在全局拥有一个 State 存放数据,当组件要更改 State 中的数据时,必须通过 Mutation 提交修改信息, Mutation 同时提供了订阅者模式供外部插件调用获取 State 数据的更新。而当所有异步操作(常见于调用后端接口异步获取更新数据)或批量的同步操作需要走 Action ,但 Action 也是无法直接修改 State 的,还是需要通过Mutation 来修改State的数据。最后,根据 State 的变化,渲染到视图上。

    • Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
    • 改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样可以方便地跟踪每一个状态的变化。
  • 原理如图所示:

vuex为何学

程序页面多, 数据变量多

  1. 不同组件数据保持同步
  2. 数据的修改都是可追踪

一个户外商店有两名员工,张三和李四

一天的早上,他们分别对帐篷的数量做了一次盘点,发现一共有三个帐篷

张三卖出去俩个,他以为库存里还有一个

李四卖出去一个,他以为库存里还有两个

而事实上是,库存现在已经为

如果他们再接受客户的预订,就会出现库存不足的情况

张三和李四因为没有保持库存的数量的同步导致了尴尬,这个就是所谓的数据保持同步

店长需要知道, 谁卖出了多少个帐篷,这个行为我们称之为数据修改是可追踪的

图示:

Vuex中存什么

多个组件共享状态,才存储在Vuex中

某个组件中的私有数据,依旧存储在data中

例如:

  • 登陆的用户名需要在首页, 个人中心, 结算页面使用, 用户名存在Vuex中

  • 文章详情数据, 只有在文章详情页查看, 在自身data中声明

小结
  1. 什么是Vuex

    • Vuex是Vue官方推荐的集中式状态管理机制
  2. 为何学Vuex
    • 数据同步, 集中管理
  3. Vuex中存什么
    • 多个组件共享的值

二、Vuex学习内容

目标
  • 知道Vuex要学习什么
核心概念
  1. 官网地址: https://vuex.vuejs.org/zh/

  2. 安装(固定)

  3. 配置项(固定)

    配置项 含义 注意
    state 单一状态树 类似data
    mutations 数据管家(同步) 唯一修改state地方
    actions 异步请求 要改state需要提交给mutations
    getters vuex计算属性 类似computed
    modules 模块拆分
图示关系

单一定义store对象, 里面5个配置项, 在任意组件可以使用

小结
  1. Vuex五个核心概念是?

    • state / mutations / actions / getters / modules

三、Vuex例子准备

目标
  • 创建项目, 为学习准备

    • 需求1: App.vue(作为根组件)

    • 需求2: 子组件Add和子组件Sub, 嵌入在App.vue里

    • 需求3: 三个组件共享库存数据(保持同步)

工程准备
  1. 初始化新的工程 vuex-demo

    vue create vuex-demo
  2. 清空欢迎界面

  3. 并设置如下三个组件, 目录如下:

    |-components
    |---AddItem.vue
    |---SubItem.vue
    |-App.vue
App.vue

复制标签和样式, 引入AddItem和SubItem2个子组件显示

<template>
<div id="app">
<h1>根组件</h1>
<span>库存总数:</span>
<input type="text">
<div style="border:1px solid black; width: 300px;">
<AddItem></AddItem>
</div>
<hr>
<div style="border:1px solid black; width: 300px;">
<SubItem></SubItem>
</div>
</div>
</template> <script>
import AddItem from '@/components/AddItem'
import SubItem from '@/components/SubItem'
export default {
components: {
AddItem,
SubItem
}
}
</script> <style>
#app {
width: 300px;
margin: 20px auto;
border:1px solid #ccc;
padding:4px;
}
</style>
AddItem.vue
<template>
<div>
<h3>AddItem组件</h3>
<p>已知库存数: 0</p>
<button>库存+1</button>
</div>
</template> <script>
export default { }
</script>
SubItem.vue
<template>
<div>
<h3>SubItem组件</h3>
<p>已知库存数: 0</p>
<button>库存-1</button>
</div>
</template> <script>
export default { }
</script>
小结
  1. App下套用了AddItem和SubItem, 要在3个组件共享一个数据

四、vuex-store准备

目标
  • 创建store仓库
  • 注入到Vue项目中
store概念

每个 Vuex 应用的核心 store(仓库), 包含5个核心概念

Vuex目录

和路由模块router/index.js - 类似, 维护项目目录的整洁,新建src/store/index.js文件

当然, 这个步骤并不是必需的

使用步骤
  1. 工程中 - 下载vuex

    yarn add vuex
  2. store/index.js - 创建定义导出store对象

    // 目标: 创建store仓库对象
    // 1. 下载vuex: 终端命令(yarn add vuex)
    // 2. 引入vuex
    import Vue from 'vue'
    import Vuex from 'vuex'
    // 3. 注册
    Vue.use(Vuex)
    // 4. 实例化store对象
    const store = new Vuex.Store({})
    // 5. 导出store对象
    export default store
  3. main.js - 导入注入到Vue中

    import Vue from 'vue'
    import App from './App.vue'
    import store from '@/store' // 导入store对象 Vue.config.productionTip = false new Vue({
    // 6. 注入到Vue实例中(确保组件this.$store使用) // this.$store = store
    store,
    render: h => h(App),
    }).$mount('#app')

请再次回忆一下vue-router的用法,是不是很像?

小结
  1. vuex的核心是什么?

    • store对象(包含5个核心属性)
  2. 如何创建store对象?

    • 工程下载vuex模块
    • store/index.js
      • 引入注册
      • 生成store对象导出
      • main.js - 导入注入

五、vuex-state数据源

目标
  • 定义state
  • 直接使用state
  • 辅助函数mapState

state是唯一的公共数据源,统一存储

定义state

在store/index.js定义state

语法:

/*
const store = new Vuex.Store({
state: {
变量名: 初始值
}
})
*/

具体代码:

const store = new Vuex.Store({
state: {
count: 100 // 库存
}
})
使用state2种方式
  • 方式1: 组件内 - 直接使用

    语法:

    this.$store.state.变量名
  • 方式2: 组件内 - 映射使用 (推荐)

    语法:

    // 1. 拿到mapState辅助函数
    import { mapState } from 'vuex'
    export default {
    computed: {
    // 2. 把state里变量映射到计算属性中
    ...mapState(['state里的变量名'])
    }
    }
AddItem直接用
<template>
<div>
<h3>AddItem组件</h3>
<p>已知库存数: {{ $store.state.count }}</p>
<button>库存+1</button>
</div>
</template>
App.vue直接用

计算属性count, 和输入框的v-model双向绑定

<input type="text" v-model="count">

<script>
export default {
computed: {
count: {
set(){},
get(){
return this.$store.state.count
}
}
}
}
</script>
SubItem映射用
<template>
<div>
<h3>SubItem组件</h3>
<p>已知库存数: {{ count }}</p>
<button>库存-1</button>
</div>
</template> <script>
// 需求1: 映射state到计算属性
// 1. 拿到辅助函数 mapState
// 2. 在computed内, ...mapState(['state变量名'])
// 3. 当计算属性使用
import { mapState } from 'vuex'
// let r = mapState(['count']) // 提取store里的state叫count的变量
// console.log(r); // 返回值: {count: 函数体(return state里count的值)} export default {
computed: {
// 映射count, 得到对象展开, 合并到计算属性中
...mapState(['count'])
},
}
</script>

整个过程的示意图如下

注意

state是响应式的, 只要state值变化, 页面上使用的地方会自动更新同步

小结
  1. state作用?

    定义全局状态数据源

  2. state如何定义?

    在store内, state: {变量名: 初始值}

  3. state的值如何用到具体vue组件内?

    • 直接使用 this.$store.state.变量名
    • 映射使用 ...mapState(['state的变量名'])

六、vuex-mutations定义-同步修改

目标
  • 定义mutations
定义mutations

mutations类似数据管家, 操作state里的数据

在store/index.js定义mutations

语法:

/*
const store = new Vuex.Store({
mutations: {
函数名 (state, 可选值) {
// 同步修改state值代码
}
}
})
*/

具体代码

const store  = new Vuex.Store({
state: {
count: 100 // 库存
},
mutations: {
addCount (state, value) { // 负责增加库存的管家
state.count += value
},
subCount (state, value) { // 负责减少库存的管家
state.count -= value
},
setCount (state, value) { // 负责直接修改库存的管家
state.count = value;
}
}
})
注意
  1. mutations是唯一能修改state的地方, 确保调试工具可以追踪变化
  2. mutations函数内, 只能写同步代码, 调试工具可追踪变化过程
    • 因为调试工具要立刻产生一次记录, 所以必须是同步的
小结
  1. mutations里函数作用?

    • 负责修改state里的数据
  2. mutations只能写什么样的代码?

    • 同步流程的代码

七、vuex-mutations使用

目标
  • 使用mutations2种方式
  • mutations注意事项
使用mutations的2种方式
  • 方式1: 组件内 - 直接使用

    语法:

    this.$store.commit("mutations里的函数名", 具体值)
  • 方式2: 组件内 - 映射使用

    语法:

    // 1. 拿到mapMutations辅助函数
    import { mapMutations } from 'vuex'
    export default {
    methods: {
    // 2. 把mutations里方法映射到原地
    ...mapMutations(['mutations里的函数名'])
    }
    }
AddItem直接用
  • 点击事件绑定
  • 提交mutations传入值
<button @click="addFn">库存+1</button>

<script>
export default {
methods: {
addFn(){
this.$store.commit('addCount', 1)
}
}
}
</script>
App.vue直接用
  • 触发计算属性的set方法
  • 提交mutations传入值
<span>库存总数: </span>
<input type="text" v-model="count"> <script>
export default {
computed: {
count: {
set(val){
this.$store.commit('setCount', val) // 把表单值提交给store下的mutations
},
get(){
return this.$store.state.count
}
}
}
}
</script>
SubItem映射用
  • 点击事件
  • 映射mutations的方法
  • 调用mutations方法传值
<button @click="subFn">库存-1</button>

<script>
// 需求2: 映射mutations到方法里
// 1. 拿到辅助函数 mapMutations
// 2. 在methods内, ...mapMutations(['mutations函数名'])
// 3. 当普通方法使用 import { mapMutations } from 'vuex'
export default {
methods: {
...mapMutations(['subCount']),
subFn(){
this.subCount(1)
}
}
}
</script>
注意

mutations函数上, 只能接收一个参数值, 如果传对个, 请传一个对象

小结
  1. mutations有哪2种使用方式?

    直接使用 this.$store.commit()

    映射使用 mapMutations把方法映射到组件内直接调用

  2. state, mutations, 视图组件, 3个关系是什么?

八、vuex-actions定义-异步修改

目标
  • 定义actions
定义actions

在store/index.js定义actions

语法:

/*
const store = new Vuex.Store({
actions: {
函数名 (store, 可选值) {
// 异步代码, 把结果commit给mutations给state赋值
}
}
})
*/

具体代码:

const store  = new Vuex.Store({
// ...省略state和mutations此处
actions: {
asyncAddCount(store, num){
setTimeout(() => { // 1秒后, 异步提交给add的mutations
store.commit('addCount', num)
}, 1000)
},
asyncSubCount(store, num) {
setTimeout(() => { // 1秒后, 异步提交给sub的mutations
store.commit('subCount', num)
}, 1000)
}
}
})
小结
  1. actions和mutations区别?

    mutations里同步修改state

    actions里放入异步操作

  2. actions是否能操作state?

    不建议, 要commit给mutations(为调试工具可追踪)

  3. actions和mutations里函数, 第一个形参分别是什么?

    mutations的是state

    actions的是store

九、vuex-actions使用

目标
  • 使用actions
使用actions的2种方式
  • 方式1: 组件内 - 直接使用

    语法:

    this.$store.dispatch('actions函数名', 具体值)
  • 方式2: 组件内 - 映射使用

    语法:

    // 1. 拿到mapActions辅助函数
    import { mapActions } from 'vuex'
    export default {
    methods: {
    // 2. 把actions里方法映射到原地
    ...mapActions(['actions里的函数名'])
    }
    }
AddItem直接用
  • 点击事件
  • dispatch触发action
<button @click="asyncAddFn">延迟1秒, 库存+5</button>

<script>
export default {
methods: {
asyncAddFn(){
this.$store.dispatch('asyncAddCount', 5)
}
}
}
</script>
SubItem映射用
  • 点击事件
  • 映射actions的方法
  • 调用actions的方法传值
<button @click="asyncSubFn">延迟1秒, 库存-5</button>

<script>
// 需求3: 映射actions到方法里
// 1. 拿到辅助函数 mapActions
// 2. 在methods内, ...mapActions(['actions函数名'])
// 3. 当普通方法使用 import { mapActions } from 'vuex'
export default {
methods: {
...mapActions(['asyncSubCount']),
asyncSubFn(){
this.asyncSubCount(5)
}
}
}
</script>
小结
  1. actions使用方式?

    方式1: this.$store.dispatch('actions方法名字', 值)

    方式2: ...mapActions(['actions里的方法名']) 映射到原地使用

  2. 视图组件, state, mutations, actions的关系是?

十、vuex-重构购物车-准备Store

目标
  • 在现有项目如何集成vuex
store准备
  1. 复制预习资料<shopcar-模板>到自己今天文件夹下
  2. 下载vuex
  3. store/index.js创建导出store对象
  4. main.js把store引入, 然后注入到Vue实例
小结
  1. 现有项目如何集成vuex

    下载vuex

    创建store对象并注入到Vue实例中

十一、vuex-重构购物车-配置项(上午结束)

目标
  • 准备state和mutations还有actions
配置项准备
  1. 定义state - 保存商品列表数组
state: {
goodsList: [] // 列表
}
  1. 定义mutations - 给state里变量赋值
mutations: {
setGoodsList(state, newList) {
state.goodsList = newList
}
}
  1. 定义actions - 异步请求数据提交给mutations
actions: {
async asyncGetGoodsList(store) {
const url = `https://www.escook.cn/api/cart`
// 发送异步请求
const res = await axios({ url: url });
store.commit('setGoodsList', res.data.list) // 提交mutation修改state中的数据
}
}
App.vue使用vuex
  • 把vuex商品数组映射回来使用
  • 网络请求调用actions方法
<script>
import { mapState, mapActions } from 'vuex'
export default {
computed: {
...mapState({list: 'goodsList'}) // 自定义原地属性名list, 映射vuex里的goodsList变量值
},
created(){
this.asyncGetGoodsList()
},
methods: {
...mapActions(['asyncGetGoodsList']),
allFn(bool){
this.list.forEach(obj => obj.goods_state = bool)
}
}
}
</script>
小结
  1. mapState可以改变映射到原地的计算属性名吗?

    可以的, 格式...mapState({''计算属性名', 'state里要映射的变量名'})

十二、vuex-getters定义-计算属性

目标
  • getters概念
  • 定义getters
getters概念

vuex身上的全局状态-计算属性, 类似于computed

getters 依赖于 state中原始数据的变化,并返回计算后的新数据

定义getters

在store/index.js定义getters

语法:

/*
const store = new Vuex.Store({
getters: {
计算属性名 (state) {
return 值给计算属性
}
}
})
*/

具体代码

const store = new Vuex.Store({
// ...省略其他
getters: {
allCount(state) {
return state.goodsList.reduce((sum, obj) => {
if (obj.goods_state === true) { // 选中商品才累加数量
sum += obj.goods_count;
}
return sum;
}, 0)
},
allPrice(state) {
return state.goodsList.reduce((sum, obj) => {
if (obj.goods_state) {
sum += obj.goods_count * obj.goods_price
}
return sum;
}, 0)
}
}
})
小结
  1. getters有什么用?

    vuex里的计算属性, 属于全局计算属性, 类似computed

十三、vuex-getters使用

目标
  • 组件内使用getters
使用getters的2种方式
  • 方式1: 组件内 - 直接使用

    语法:

    this.$store.getters.计算属性名
  • 方式2: 组件内 - 映射使用

    语法:

    // 1. 拿到mapGetters辅助函数
    import { mapGetters } from 'vuex'
    export default {
    computed: {
    // 2. 把getters里属性映射到原地
    ...mapGetters(['getters里的计算属性名'])
    }
    }
MyFooter.vue里使用
  • 使用2种方式给计算属性值
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
allCount(){
return this.$store.getters.allCount;
},
...mapGetters(['allPrice'])
}
}
</script>
小结
  1. getters如何使用?

    方式1: this.$store.getters.计算属性名

    方式2: ...mapGetters(['getters里计算属性名'])

十四、vuex-modules定义-分模块

目标
  • 为何要分模块
  • modules定义
为何分模块

代码上的对比

创建modules模块对象
  • 新建store/modules/user.js
  • 新建store/modules/cart.js

语法: 对象里包含5个核心概念, 只有state变成函数形式

user.js - 用户模块对象

// 用户模块对象
const userModule = {
state(){
return {
name: "",
age: 0,
sex: ''
}
},
mutations: {},
actions: {},
getters: {}
}
export default userModule

cart.js - 购物车模块对象

// 购物车模块对象
import axios from 'axios'
const cartModule = {
state() {
return {
goodsList: []
}
},
mutations: {
setGoodsList(state, newList) {
state.goodsList = newList
}
},
actions: {
async asyncGetGoodsList(store) {
const url = `https://www.escook.cn/api/cart`
// 发送异步请求
const res = await axios({ url: url });
store.commit('setGoodsList', res.data.list) // 提交mutation修改state中的数据
}
},
getters: {
allCount(state) {
return state.goodsList.reduce((sum, obj) => {
if (obj.goods_state === true) { // 选中商品才累加数量
sum += obj.goods_count;
}
return sum;
}, 0)
},
allPrice(state) {
return state.goodsList.reduce((sum, obj) => {
if (obj.goods_state) {
sum += obj.goods_count * obj.goods_price
}
return sum;
}, 0)
}
}
}
export default cartModule
定义modules

语法:

modules: {
模块名: 模块对象
}
  • 把2个模块对象, 引回到store里注册
import Vue from 'vue'
import Vuex from 'vuex'
import cartModule from './modules/cart'
import userModule from './modules/user'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user: userModule,
cart: cartModule
}
})
export default store
小结
  1. 为什么分模块?

    集中式管理项目过大, 变量过多, 会导致state臃肿, 难以维护

  2. 如何分模块?

    定义模块对象, state变成函数返回对象形式, 每个模块都有state/mutations/actions/getters/modules

  3. 根store如何注册?

    modules里 { 模块名: 模块对象 }

十五、分模块-影响state取值方式

目的
  • 只要分模块, state取值方式改变, 其他暂时不变
state使用方式修改
  • 方式1: 组件内 - 直接使用

    原语法:

    this.$store.state.变量名

    分模块后语法:

    this.$store.state.模块名.变量名
  • 方式2: 组件内 - 映射使用

    原语法:

    ...mapState(['state里变量名'])
    ...mapState({'变量名': "state里变量名"}) // 给映射过来的state起别的名字

    分模块后语法:

    ...mapState({
    '变量名': state => state.模块名.变量名
    })
App.vue-修改
computed: {
// ...mapState({list: 'goodsList'}) // 本地属性名list, 映射vuex里的goodsList变量值
// 方式1: 直接用
// list(){ // 这个list就是组件内普通的计算属性名
// return this.$store.state.cart.goodsList
// }.
// 方式2: 映射方式改变
...mapState({'list': state => state.cart.goodsList})
},
小结
  1. 分模块对什么有影响?

    对state的取值方式有影响, 对其他暂无影响

  2. state如何取值?

    在组件使用的时候, 要state.模块名.变量名

十六、分模块-命名空间

目标
  • 防止多个模块之间, mutations/actions/getters的名字冲突
开启命名空间

在模块对象内设置namespaced: true

const moduleShopCar = {
namespaced: true,
state () {},
mutations: {},
actions: {},
getters: {},
modules: {}
}
state使用方式修改
  • 直接使用无变化: this.$store.state.模块名.变量名

  • 辅助函数需要遵守格式

    ...mapState("模块名", ['state变量名'])
mutations使用方式修改
  • 方式1: 组件内 - 直接使用

    • 原语法:

      this.$store.commit("mutations里的函数名", 具体值)
    • 开命名空间后语法:

      this.$store.commit("模块名/mutations里的函数名", 具体值)
  • 方式2: 组件内 - 映射使用

    • 原语法:

      ...mapMutations(['mutations里方法名'])
    • 开命名空间后语法:

      ...mapMutations("模块名", ['mutations里方法名'])
actions使用方式修改
  • 方式1: 组件内 - 直接使用

    • 原语法:

      this.$store.dispatch("actions里的函数名", 具体值)
    • 开命名空间后语法:

      this.$store.dispatch("模块名/actions里的函数名", 具体值)
  • 方式2: 组件内 - 映射使用

    • 原语法:

      ...mapActions(['actions里方法名'])
    • 开命名空间后语法:

      ...mapActions("模块名", ['actions里方法名'])
getters使用方式修改
  • 方式1: 组件内 - 直接使用

    • 原语法:

      this.$store.getters.计算属性名
    • 开命名空间后语法:

      this.$store.getters['模块名/计算属性名']
  • 方式2: 组件内 - 映射使用

    • 原语法:

      ...mapGetters(['getters里计算属性名'])
    • 开命名空间后语法:

      ...mapGetters("模块名", ['getters里计算属性名'])
小结
  1. state和mutations, 在根store和开启命名空间里的区别?

  1. 整个vuex的体系是?

十七、Vuex的构造

1.actions
  • 由子组件this.$store.dispatch('actions名',传递的数据)触发
  • 传递的数据只能是单个数据,多个数据用对象传递
  • actions: { action名({commit},数据){...}}
  • store中actions内,commit用于触发mutations,actions只做业务逻辑,不修改state
2.mutations
  • 由actions中的commit('mutations名',传递的数据)触发
  • mutations:{mutations名(state,数据){...}}
  • store中的mutations内,mutations可以修改state中的数据
3.state
  • 存储数据:state:{userInfor:{}}
  • 可以通过mutations存储或者修改,也是getters里面计算属性的依据
4.getters
  • 计算state中的数据:getters:{getters名(state){...}}
  • state用于getters计算属性的依据

十八、Vuex中的模块(module)和命名空间(namespaced)

1.模块(module)
  • 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

    为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的state、mutations、actions、getters、甚至是嵌套子模块。
2.命名空间(namespaced)
  • 默认情况下,模块内部的 actions、mutations 和 getters 是注册在全局命名空间的——这样使得多个模块能够对同一 mutations 或 actions 作出响应,如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getters、actions 及 mutations 都会自动根据模块注册的路径调整命名。

  • 如果你想模块之间相互独立、互不影响。可以通过添加 namespaced: true 的方式使其成为带命名空间的模块,当模块被注册后,它的所有 getters、actions 和 mutations 都会自动根据模块注册的路径调整命名。所以开启命名空间的模块中的getters、actions 和 mutations的使用方式都会改变;但是开启命名空间和不开启命名空间的模块中的state的使用方式不会改变。格式依然是store.state.模块名.状态名。

    // 开启store子模块的命名空间
    const moduleName = {
    state: {},
    getters: {},
    mutations: {},
    actions: {},
    namespaced: true // 开启命名空间
    }
    export default moduleName
    // 在组件中使用
    import { mapState, mapGetters, mapActions } from 'vuex'
    export default {
    computed: {
    // 传统方式:获取store中的数据
    proData () {
    return this.$store.state.productModule.proData
    },
    themeData () {
    return this.$store.getters['themeModule/themeData']
    },
    proName () {
    return this.$store.getters['productModule/proName']
    },
    proDesc () {
    return this.$store.getters['productModule/proDesc']
    },
    indexData () {
    return this.$store.getters['productModule/indexData']
    }
    // 辅助函数方式一:获取store中的数据(代码较简洁)
    ...mapState({ proData: state => state.productModule.proData })
    ...mapGetters(['themeModule/themeData'])
    ...mapGetters(['themeModule/proName', 'themeModule/proDesc', 'themeModule/indexData'])
    // 辅助函数方式二:获取store中的数据(代码最简洁)
    ...mapState('productModule', { proData: state => state.proData })
    ...mapGetters('themeModule', ['themeData'])
    ...mapGetters('productModule', ['proName', 'proDesc', 'indexData'])
    },
    created () {
    // 传统方式:获取异步数据
    this.$store.dispath('themeModule/queryThemeAction')
    this.$store.dispath('productModule/queryProDataAction')
    this.$store.dispath('productModule/queryIndexDataAction')
    // 辅助函数方式:获取异步数据(需要在methods中使用mapActions定义方法)
    this.queryThemeAction()
    this.queryProDataAction()
    this.queryIndexDataAction()
    },
    methods: {
    ...mapActions('themeModule', ['queryThemeAction'])
    ...mapActions('productModule', ['queryProDataAction', 'queryIndexDataAction'])
    }
    }

扩展: 使用Devtools调试vuex数据

优秀的调试工具可以使我们写程序事半功倍,最后我们再学习一下如果使用dev-tools来调试vuex中的数据,这也是数据可预测特性里不可缺少的一环

目标
  • 掌握dev-tools调试vuex
  • 理解什么是数据状态是可追踪的
如何进行调试

注意只有vue+vuex的项目才可以用

调试信息说明

Vuex从入门到精通的更多相关文章

  1. vuejs2从入门到精通与项目开发实战

    vuejs2从入门到精通:一.基础部分0.课件1.介绍2.vue实例3.模板语法4.计算属性和观察者5.Class与Style绑定6.条件渲染7.列表渲染8.事件处理9.表单输入绑定10.1.组件(1 ...

  2. <程序员从入门到精通> -- How

    定位 自己才是职业生涯的管理者,想清楚自己的发展路径: 远期的理想是什么?近期的规划是什么?今日的任务和功课又是什么? 今日之任务或功课哪些有助于近期之规划的实现,而近期之规划是否有利于远期之理想? ...

  3. 【无私分享:从入门到精通ASP.NET MVC】从0开始,一起搭框架、做项目 目录索引

    索引 [无私分享:从入门到精通ASP.NET MVC]从0开始,一起搭框架.做项目(1)搭建MVC环境 注册区域 [无私分享:从入门到精通ASP.NET MVC]从0开始,一起搭框架.做项目(2)创建 ...

  4. ASP.NET MVC4入门到精通系列目录汇总

    序言 最近公司在招.NET程序员,我发现好多来公司面试的.NET程序员居然都没有 ASP.NET MVC项目经验,其中包括一些工作4.5年了,甚至8年10年的,许多人给我的感觉是:工作了4.5年,We ...

  5. Web jquery表格组件 JQGrid 的使用 - 从入门到精通 开篇及索引

    因为内容比较多,所以每篇讲解一些内容,最后会放出全部代码,可以参考.操作中总会遇到各式各样的问题,个人对部分问题的研究在最后一篇 问题研究 里.欢迎大家探讨学习. 代码都经过个人测试,但仍可能有各种未 ...

  6. 1、ASP.NET MVC入门到精通——新语法

    本系列目录:ASP.NET MVC4入门到精通系列目录汇总 在学习ASP.NET MVC之前,有必要先了解一下C#3.0所带来的新的语法特性,这一点尤为重要,因为在MVC项目中我们利用C#3.0的新特 ...

  7. 5、ASP.NET MVC入门到精通——NHibernate代码映射

    本系列目录:ASP.NET MVC4入门到精通系列目录汇总 上一篇NHibernate学习笔记—使用 NHibernate构建一个ASP.NET MVC应用程序 使用的是xml进行orm映射,那么这一 ...

  8. 6、ASP.NET MVC入门到精通——ASP.Net的两种开发方式

    本系列目录:ASP.NET MVC4入门到精通系列目录汇总 目前,ASP.NET中两种主流的开发方式是:ASP.NET Webform和ASP.NET MVC.从下图可以看到ASP.NET WebFo ...

  9. 7、ASP.NET MVC入门到精通——第一个ASP.NET MVC程序

    本系列目录:ASP.NET MVC4入门到精通系列目录汇总 开发流程 新建Controller 创建Action 根据Action创建View 在Action获取数据并生产ActionResult传递 ...

  10. 8、ASP.NET MVC入门到精通——View(视图)

    本系列目录:ASP.NET MVC4入门到精通系列目录汇总 View视图职责是向用户提供界面.负责根据提供的模型数据,生成准备提供给用户的格式界面. 支持多种视图引擎(Razor和ASPX视图引擎是官 ...

随机推荐

  1. LeetCode - 数组的旋转总结

    1. 数组的旋转总结 数组的旋转指的是将数组的最后若干个数提前到数组前面,数组的翻转指的是将数组的顺序颠倒.旋转可以通过多次翻转实现. 数组的翻转很简单,通过双指针来实现:交换数组的第一个数和最后一个 ...

  2. sql内连查询

    select <查询的列名> from <表名> inner join `<连接的表名称>` on <第一张表的主键> = <第二张表的外键> ...

  3. HTML5中新增实用的标签

    1:progress  进度条 <h3>progress</h3> <progress value="75" max="100"& ...

  4. POJ3342 Party at Hali-Bula(树形DP)

    dp[u][0]表示不选u时在以u为根的子树中最大人数,dp[u][1]则是选了u后的最大人数: f[u][0]表示不选u时的唯一性,f[u][1]是选了u后的唯一性,值为1代表唯一,0代表不唯一. ...

  5. Java注解(3):一个真实Elasticsearch案例

    学会了技术就要使用,否则很容易忘记,因为自然界压根就不存在什么代码.变量之类的玩意,这都是一些和生活常识格格不入的东西.只能多用多练,形成肌肉记忆才行. 在一次实际的产品开发中,由于业务需求的缘故,需 ...

  6. 使用 Apache Hudi 实现 SCD-2(渐变维度)

    数据是当今分析世界的宝贵资产. 在向最终用户提供数据时,跟踪数据在一段时间内的变化非常重要. 渐变维度 (SCD) 是随时间推移存储和管理当前和历史数据的维度. 在 SCD 的类型中,我们将特别关注类 ...

  7. SQL优化步骤

    当生产数据量急剧增长后,很多SQL语句可能会开始暴露出性能问题.当面对一个有SQL性能问题的数据库时,应该从何处入手进行系统的分析,使得能够尽快定位到问题SQL处并尽快解决问题? 第一步:查看SQL执 ...

  8. 2.RabbitMQ系列之生产者

    1. 新建队列 2. 新增POM.xml配置文件 <parent> <groupId>org.springframework.boot</groupId> < ...

  9. 动词时态=>1.动作的时间和状态

    时态 什么是时态? 英语的时态,是由动作的时间 + 动作的状态:这俩一起构成了时态 动词的时间和状态在一起,合称时态 理论上的十六种时态 先将 时间和状态的概念搞清楚,再具体讨论,用什么词,去构成时态 ...

  10. 事件循环Event Loop

    在 事件循环 期间的某个时刻,运行时会从最先进入队列的消息开始处理队列中的消息.被处理的消息会被移出队列,并作为输入参数来调用与之关联的函数.正如前面所提到的,调用一个函数总是会为其创造一个新的栈帧. ...