## 一、概述
為了方便在組件中使用,可以把vuex中定義的那些state、mutation、action及getters在組件里面做映射。這樣,就可以大大簡化了對狀態組件的使用了;
>[danger] 簡單的理解,就是通過映射,把vuex中定義的那些元素,映射到組件的定義中來,直接通過映射的方法名就可以使用了,而不用再通過詳細的代碼過程來調用;
## 二、state與mapState
當一個組件需要獲取多個狀態時候,將這些狀態都聲明為計算屬性會有些重復和冗余。為了解決這個問題,我們可以使用mapState輔助函數幫助我們生成計算屬性;
舉例來說:
```js
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
}
}
}
```
當映射的計算屬性的名稱與 state 的子節點名稱相同時,我們也可以給mapState傳一個字符串數組。
```
computed: mapState([
// 映射 this.count 為 store.state.count
'count'
])
```
mapState函數返回的是一個對象。我們如何將它與局部計算屬性混合使用呢?通常,我們需要使用一個工具函數將多個對象合并為一個,以使我們可以將最終對象傳給computed屬性。
```
computed: {
localComputed () { /* ... */ },
// 使用對象展開運算符將此對象混入到外部對象中
...mapState({
// ...
})
}
```
## 三、getter與mapGetters
有時候我們需要從 store 中的 state 中派生出一些狀態,例如對列表進行過濾并計數:
```
computed: {
doneTodosCount () {
return this.$store.state.todos.filter(todo => todo.done).length
}
}
```
Vuex 允許我們在 store 中定義“getter”(可以認為是 store 的計算屬性)。就像計算屬性一樣,getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變才會被重新計算。
Getter 接受 state 作為其第一個參數:
```
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
```
Getter 會暴露為`store.getters`對象:
```
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
```
Getter 也可以接受其他 getter 作為第二個參數:
```
getters: {
// ...
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
store.getters.doneTodosCount // -> 1
```
### 組件中使用:
我們可以很容易地在任何組件中使用它:
```
computed: {
doneTodosCount () {
return this.$store.getters.doneTodosCount
}
}
```
mapGetters 輔助函數僅僅是將 store 中的 getter 映射到局部計算屬性;
```
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
// 使用對象展開運算符將 getter 混入 computed 對象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
}
```
如果你想將一個 getter 屬性另取一個名字,使用對象形式:
```
mapGetters({
// 映射 `this.doneCount` 為 `store.getters.doneTodosCount`
doneCount: 'doneTodosCount'
})
```
## 四、mutation和mapMutations
更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似于事件:每個 mutation 都有一個字符串的**事件類型 (type)**和 一個**回調函數 (handler)**。這個回調函數就是我們實際進行狀態更改的地方,并且它會接受 state 作為第一個參數:
```
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 變更狀態
state.count++
}
}
})
```
```
store.commit('increment')
```
當使用對象風格的提交方式,整個對象都作為載荷傳給 mutation 函數,因此 handler 保持不變;
```
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
```
使用常量替代 Mutation 事件類型,
```
// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
// store.js
import Vuex from 'vuex'
import { SOME_MUTATION } from './mutation-types'
const store = new Vuex.Store({
state: { ... },
mutations: {
// 我們可以使用 ES2015 風格的計算屬性命名功能來使用一個常量作為函數名
[SOME_MUTATION] (state) {
// mutate state
}
}
})
```
### 組件中使用:
你可以在組件中使用 this.$store.commit('xxx') 提交 mutation。
或者使用 mapMutations 輔助函數將組件中的 methods 映射為 store.commit 調用(需要在根節點注入 store)。
```
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment', // 將 `this.increment()` 映射為 `this.$store.commit('increment')`
// `mapMutations` 也支持載荷:
'incrementBy' // 將 `this.incrementBy(amount)` 映射為 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 將 `this.add()` 映射為 `this.$store.commit('increment')`
})
}
}
```
## 五、action與mapActions
Action 類似于 mutation,不同在于:
Action 提交的是 mutation,而不是直接變更狀態;
Action 可以包含任意異步操作;
Action 函數接受一個與 store 實例具有相同方法和屬性的 context 對象,因此你可以調用`context.commit`提交一個 mutation,或者通過`context.state`和`context.getters`來獲取 state 和 getters。
```
actions: {
increment ({ commit }) {
commit('increment')
}
}
```
分發:
Action 通過`store.dispatch`方法觸發:
```
store.dispatch('increment')
```
乍一眼看上去感覺多此一舉,我們直接分發 mutation 豈不更方便?實際上并非如此,還記得**mutation 必須同步執行**這個限制么?Action 就不受約束!我們可以在 action 內部執行**異步**操作:
```
actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
```
Actions 支持同樣的載荷方式和對象方式進行分發:
```
// 以載荷形式分發
store.dispatch('incrementAsync', {
amount: 10
})
// 以對象形式分發
store.dispatch({
type: 'incrementAsync',
amount: 10
})
```
### 組件中使用:
你在組件中使用`this.$store.dispatch('xxx')`分發 action,或者使用`mapActions`輔助函數將組件的 methods 映射為`store.dispatch`調用(需要先在根節點注入`store`):
```
用法:
// 引入?mapActions
import { mapActions } from 'vuex';
// 進行解構賦值和拓展運算
export default {
// ...
methods: {
//下述中的 ... 是拓展運算符
// 使用 [] 是解構賦值
...mapActions([
'increment', // 將 `this.increment()` 映射為 `this.$store.dispatch('increment')`
// `mapActions` 也支持載荷:
'incrementBy' // 將 `this.incrementBy(amount)` 映射為 `this.$store.dispatch('incrementBy', amount)`
]),
...mapActions({
add: 'increment' // 將 `this.add()` 映射為 `this.$store.dispatch('increment')`
})
}
}
```
注意:
1. mapActions?必須放在?methods中,因為?action?或者? mutation?都是函數.
2. mapAction?里面都是store?里面的集合,所以使用ES6中解構賦值的方法進行獲取我們所需的方法。
3. mapAction?前面的 ( ...?)?是ES6中?拓展運算符,對我們所需的方法從數組中拓展出來。
4. ES6對象中同名屬性可以簡寫。
5. 也可以自己命名不同函數名來映射?action方法
## 六、createNamespacedHelpers
`createNamespacedHelpers(namespace: string): Object`
創建基于命名空間的組件綁定輔助函數。其返回一個包含`mapState`、`mapGetters`、`mapActions`和`mapMutations`的對象。它們都已經綁定在了給定的命名空間上。
## 七、實例
```vue
<template>
//直接使用state的代碼
{{this.$store.state.views}}
//mapState方式
{{viewsCount}}
</template>
```
```js
<script>
import { mapState, mapGetters, mapActions, mapMutations } from 'vuex'
export default {
data () {
return {
checked: true
}},
created () {
// this.$store.dispatch('addViews') // 直接通過store的方法 觸發action, 改變 views 的值
this.blogAdd() // 通過mapActions 觸發mutation 從而commit ,改變state的值
},
computed: {
...mapState({
viewsCount: 'views'
}),
...mapGetters({
todosALise: 'getToDo' // getToDo 不是字符串,對應的是getter里面的一個方法名字 然后將這個方法名字重新取一個別名 todosALise
})},
methods: {
...mapMutations({
totalAlise: 'clickTotal' // clickTotal 是mutation 里的方法,totalAlise是重新定義的一個別名方法,本組件直接調用這個方法
}),
...mapActions({
blogAdd: 'blogAdd' // 第一個blogAdd是定義的一個函數別名稱,掛載在到this(vue)實例上,后面一個blogAdd 才是actions里面函數方法名稱
})}
}
</script>
```
- 引言
- 01、開發工具
- Maven
- 術語
- 倉庫
- Archetype
- 安裝配置
- 典型配置
- 內置變量
- eclipse插件
- 本地包安裝
- 依賴庫更新
- 依賴庫排錯
- 常見問題
- Gradle
- build.gradle
- gradle插件
- eclipse插件
- Eclipse
- json生成bean
- 常見問題
- IDEA Community
- 工程管理
- maven操作
- 格式化
- 常見問題
- Git
- GitHub
- 快速開始
- 既有工程
- 新建工程
- 日常提交
- PR操作
- 多人協作
- 常用命令
- 常見問題
- 同步代碼
- 發布庫包
- CodeGenerator
- VSCode
- 安裝
- 配置
- 快速開始
- 與GitHub整合
- 斷點調試
- 便捷開發
- 擴展
- prettier+
- Vetur
- 前端調試
- F12調試工具
- Vue前端調試
- 測試工具
- 壓力測試
- 接口測試
- 抓包工具
- 導入證書
- SecureCRT
- 02、前端技術
- 前端設計
- javascript
- 基本語法
- 數據類型
- 類型轉換
- 錯誤處理
- console對象
- 標準庫
- 異步操作
- ES6及后續增強
- 模塊化
- 擴展運算符
- 解構變量
- 箭頭函數
- 混入模式
- web標準
- css
- html
- HistoryApi
- dom
- 如何理解
- 虛擬dom
- JSON
- svg
- WebAssembly
- web components
- HtmlComponents
- Custom Elements
- 標準擴展
- javascript
- Babel
- TypeScript
- JavaScript
- ECMAScript
- 模塊化
- CommonJS
- require
- exports與module.exports
- ES6模塊
- export
- import
- AMD
- define
- require
- CMD
- define
- require
- Web Storage
- JSX
- ES6語法
- 語法糖
- ==和===
- let與const
- call&apply
- 內置對象
- Object
- Class
- Promise對象
- then
- catch
- finally
- resolve
- reject
- Module
- Generator函數
- arguments
- 函數擴展
- 數組
- 對象
- Set和Map
- Proxy對象
- css
- sass
- less
- postcss
- CSS Modules
- Node.js
- 安裝
- npm
- ls
- init
- install
- run
- uninstall
- update
- version
- npm生態
- yarn
- package.json
- node_modules
- 常用技術
- 應用實例
- Web框架
- Express
- Egg.js
- Mock
- Mock.js
- 語法規范
- 非核心api
- 核心api
- easymock
- 開發測試
- ESLint
- jest
- Travis
- Prettier
- stylelint
- 構建工具
- gulp
- Browserify
- webpack
- 安裝配置
- 入口起點entry
- 輸出output
- 裝載器loader
- 插件plugins
- webpack-cli
- public目錄
- 技術概念
- CSR與SSR
- polyfill
- axios
- 請求對象
- 響應對象
- 自定義實例
- 攔截器
- 跨域訪問
- 03、前端框架
- mvvm
- vue.js
- 簡明指南
- vue文件結構
- 組件指南
- 組件命名
- 應用流程
- 單文件組件
- 組件導入導出
- 生命周期
- Prop
- 復用方法
- 懶加載
- 全局環境
- 全局配置
- 全局API
- 選項對象
- 混入選項
- vue實例$
- vue指令
- v-bind(:)
- v-on(@)
- v-model
- 特殊屬性
- 內置組件
- 自定義機制
- 組件
- 指令
- 過濾器
- 混入
- slot插槽
- 渲染函數
- 注意事項
- 總結
- vueCli
- 安裝
- 組成部分
- vue.config.js
- vue核心文件
- 狀態管理
- 簡單狀態
- Vuex
- 構造器選項
- 實例屬性
- 實例方法
- 綁定輔助函數
- 模塊化
- 總結
- 路由管理
- 簡單路由
- Vue Router
- 路由模式
- route
- router
- <router-link>與編程式
- <router-view>
- 嵌套路由
- 導航守衛
- 總結
- vue插件
- Vue Loader
- 實戰舉例
- vue快速入門
- vue與后臺聯動
- vue完整實例
- vue組件庫
- vue-ls
- Enquire.js
- lodash
- md5.js
- moment
- nprogress
- viser-vue
- vue-clipboard2
- vue-cropper
- vue-quill-editor
- wangeditor
- vue-svg-icon-loader
- 實戰參考
- Vue Antd Admin
- ant-design-vue
- 快速開始
- 要點解析
- vuepress
- vant
- 04、后端框架
- SprigBoot
- 快速入門
- 完整示例
- 完整進階
- 核心技術
- 核心標記
- 頁面技術
- Thymeleaf
- 數據訪問
- 基本用法
- 事務控制
- 事務規則
- 注意事項
- 實體狀態
- 數據查詢
- 普通查詢
- 分頁查詢
- 統計查詢
- 命名訪問
- 公用共享
- 緩存機制
- 服務層
- 控制器
- AOP
- 定時任務
- 異步任務
- 靜態注入
- WebClient
- 啟動機制
- 應用監控
- 線程安全
- 調試測試
- 打包部署
- 打jar包
- 常見問題
- 配置問題
- 開發問題
- 文檔生成
- 相關技術
- springfox
- knife4j
- actuator
- kaptcha
- YAML
- API Blueprint
- 啟用https
- SpringSecurity
- 快速入門
- 核心元素
- jwt
- 與springsecurity集成
- 05、運行容器
- artemis
- 協議支持
- mqtt
- 安裝運行
- 管理配置
- 日志配置
- 業務配置
- 安全配置
- 數據存儲
- SSL支持
- 運行維護
- mosquitto
- 安裝運行
- 管理配置
- SSL支持
- rocketmq
- 安裝運行
- 控制臺
- 代碼實例
- kafka
- ZooKeeper
- 安裝運行
- 代碼實例
- zookeeper
- 安裝運行
- 應用實例
- dubbo
- 代碼實例
- hadoop
- 安裝配置
- 快速運行
- netty
- 06、相關技術
- Serverless
- Protobuf
- SSL
- 證書
- 認證類型
- 硬件技術
- 基礎知識
- 開發技術
- 消息協議
- 07、項目實戰
- 前端開發
- 從零開始開發
- 開發環境搭建
- 原生技術開發
- 路由守衛
- 動態路由菜單
- 全局API
- 登錄認證
- 與后端交互
- 代碼開發調試
- 快速打包發布
- 常見問題收集
- 后端開發
- 從零開始開發
- 開發環境搭建
- 常用注解說明
- 常用基礎設施
- 核心業務約定
- 平臺配置文件
- 業務配置清單
- 關鍵配置參數
- 項目必配參數
- 項目調優參數
- 返回結果處理
- 字段翻譯機制
- 列表字段翻譯
- 實體字段翻譯
- 組合字段翻譯
- 列表數據增強
- 列表數據簡化
- 返回字段過濾
- 返回字段改名
- 定制返回結果
- 原生技術開發
- 動態級聯字典
- 簡單數據查詢
- 短信驗證業務
- 測試數據模擬
- 開放平臺登陸
- 微信開放平臺
- 抖音開放平臺
- 文件處理方案
- 文件字段存儲
- 文件字段解析
- 圖像數據存取
- 文件資源方案
- 服務集成開發
- redis服務集成
- mqtt服務集成
- kafka集成
- rocketmq集成
- websocket集成
- elasticsearch集成
- netty集成
- 外部工具開發
- 發送短信服務
- 發送郵件服務
- 動態pdf生成
- 數據處理開發
- 同步導出數據
- 異步導出數據
- 同步導入數據
- 異步導入數據
- 多線程與并發
- 線程并發安全
- 操作間隔控制
- 異步待辦機制
- 平臺定時任務
- 平臺異步任務
- 常見注意事項
- 安全相關開發
- 接口安全策略
- 接口限流策略
- 接口授權策略
- 權限相關開發
- 路由權限方案
- 組織權限方案
- 數據權限方案
- 字段權限方案
- 按鈕權限方案
- 支付相關開發
- 微信原生支付
- 微信H5支付
- 微信JSAPI支付
- 微信批量轉賬
- 微信動態支付
- 支付寶移動網站支付
- 支付寶PC網站支付
- 平臺緩存機制
- 內置進程內緩存
- 內置分布式緩存
- 平臺自定義緩存
- 平臺插件機制
- 賬號的邀請碼
- 賬號的二維碼
- 定制事件機制
- 約定實現機制
- 請求回調機制
- 啟動自動加載
- 平臺基礎設施
- 動態參數加載
- 定制待定常量
- 定制單位組織
- 平臺緩存機制
- 平臺外訪機制
- 靜態資源獲取
- 調試打印機制
- 數據源隨時用
- 上下文隨處拿
- 平臺診斷機制
- 平臺內置資源
- 強制間隔時間
- 賬號擴展開發
- 賬號變更事件
- 業務開發指南
- 字典數據獲取
- 數據層持久化
- 基礎服務調用
- 查詢時間范圍
- 代碼開發調試
- 常見問題收集
- 從零開始
- PCV1運行
- PCV2運行
- H5端運行
- 開發進階
- 最佳實踐
- 開發方案
- 前后分離
- 跨域訪問
- 庫表設計
- 模型設計
- 容器部署
- 集群部署
- 日志收集
- 動態配置
- 開發管理
- 開發環境
- 代碼控制
- 問題跟蹤
- 進度跟蹤
- 測試環境
- 調試輔助
- DevOps
- 代碼風格
- 運行維護
- 基本監控知識
- 線程堆棧分析
- 內存堆棧分析
- 應用診斷工具
- 工程示范
- 后端開發
- 前端開發
- PC端
- 移動端
- 08、內置容器
- 調度服務
- 調度容器
- 快速開發
- 線程并發
- 多點部署
- 本地調試
- 常見問題
- 開放服務
- 快速接入
- 接口開發
- 09、開放平臺
- 微信公號
- 環境準備
- 環境配置
- 技術方案
- 獲取OpenId
- 常見問題
- 10、平臺功能
- 系統管理
- 單位組織
- 角色管理
- 賬號管理
- 子賬號
- 財務賬戶
- 開放數據
- 綁定數據
- 套餐權益
- 會員定義
- 變更審核
- 注冊審核
- 系統配置
- 路由配置
- 參數配置
- 屬性配置
- 樹形設置
- 服務接口
- 訪問設置
- 系統監控
- 在線用戶
- 內存數據
- 系統變量
- 外訪數據
- 到訪數據
- 操作記錄
- 靜態字典
- 日志管理
- 元數據
- 接入管理
- 微信公號
- 微信支付
- 開放服務
- 客戶端
- 服務列表
- 請求歷史
- 請求服務
- 調度服務
- 調度監控
- 11、補充語言
- php
- 生產環境
- 安裝
- 初始配置
- nginx集成
- 配置文件
- 語法
- 變量和常量
- 數據類型
- 條件控制
- 運算符
- 數組
- 指針
- 循環控制
- 函數
- 語法糖
- 預定義變量
- session和cookie
- 命名空間
- 面向對象
- 數據庫操作
- 表單
- 錯誤
- 異常
- 過濾器
- JSON
- XML
- AJAX
- Composer
- 開發環境
- 本地調試
- 遠程調試
- .net
- 開發環境
- C#快速入門
- 12、依賴容器
- elasticsearch
- 運行配置
- 命令操作
- 中文分詞
- Kibana
- Logstash
- 開發技術
- 搜索類型
- 代碼示例
- 應用場景
- 常見問題
- nginx
- 下載安裝
- 基本配置
- 服務啟停
- 安全防護
- 常見問題
- linux
- 常用操作
- 常用命令
- 用戶管理
- ftp服務
- 防火墻
- 運維
- 網絡安全
- 內核參數
- 安裝
- yum源問題
- mysql
- 安裝配置
- 快速安裝
- 正式安裝
- 參數配置
- 性能優化
- 語句優化
- 配置優化
- 設計優化
- 運維常識
- 系統監控
- 連接數
- 超時
- cpu利用率
- 數據備份
- 導入復制
- 經驗舉例
- 故障處理
- 用戶管理
- 系統日志
- 日志清理
- 安全經驗
- 集群方案
- MySQL Replication
- MySQL Cluster
- 常見問題
- redis
- 安裝配置
- 安裝運行
- 參數配置
- 運維常識
- 技術要點
- pubSub
- 操作命令
- 持久化
- 常見問題
- docker
- 安裝運行
- 鏡像操作
- 容器操作
- 倉庫操作
- 實戰案例
- kubernetes
- 后記