一、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. gin项目部署到服务器并后台启动

    前言 我们写好的gin项目想要部署在服务器上,我们应该怎么做呢,接下来我会详细的讲解一下部署教程. 1.首先我们要有一台虚拟机,虚拟机上安装好go框架. 2.将写好的项目上传到虚拟机上. 3.下载好项 ...

  2. Spring Boot 配置 jar 包外面的 Properties 配置文件

    一.概述 Properties 文件是我们可以用来存储项目特定信息的常用方法.理想情况下,我们应该将其保留在 jar 包之外,以便能够根据需要对配置进行更改. 在这个教程中,我们将研究在 Spring ...

  3. Java 求解自幂数(水仙花数)

    什么是自幂数 如果在一个固定的进制中,一个 n 位自然数等于自身各个数位上数字的 n 次幂之和,则称此数为自幂数. 例如:在十进制中,153 是一个三位数,各个数位的3次幂之和为 1^3+5^3+3^ ...

  4. 服务器之Apollo单机部署(快速安装)

    部署Apollo apollo单机部署(快速安装) Apollo官网:https://www.apolloconfig.com/#/zh/deployment/quick-start-docker 官 ...

  5. 齐博x1客服系统显示客户在哪个页面

    如下图所示,要想实现下面的效果,即显示客户给你发消息时,当时处于哪个商品页面.这样方便跟客户针对此商品进行交流. 你的模板如果使用了碎片的话,就可以添加下面的代码index_style/default ...

  6. 京东云开发者|IoT运维 - 如何部署一套高可用K8S集群

    环境 准备工作 配置ansible(deploy 主机执行) # ssh-keygen # for i in 192.168.3.{21..28}; do ssh-copy-id -i ~/.ssh/ ...

  7. Intel GPU Gen 9 架构

    * 参考spec:the-compute-architecture-of-intel-processor-graphics-gen9-v1d0.pdf SOC 架构 Gen9 架构是早期用在igpu ...

  8. IO学习笔记

    IO File 概述 构造方法 代码实现: public class FileDemo001 { public static void main(String[] args) { File f1 = ...

  9. perl中 use strict会出现“requires explicit package name”错误

    转载 perl中use strict的用法 如果你使用 use strict 的话,它会强迫你用 my 声明变量,否则将会报上述错误.

  10. 某工控图片上传服务 CPU 爆高分析

    一:背景 1.讲故事 今天给大家带来一个入门级的 CPU 爆高案例,前段时间有位朋友找到我,说他的程序间歇性的 CPU 爆高,不知道是啥情况,让我帮忙看下,既然找到我,那就用 WinDbg 看一下. ...