參照官網整理總結vuex語法。
計劃日期:
Vuex基礎部分:2022年2月20日——2022年2月28日
Vuex源碼相關實踐:待定
Vuex拓展:待定
寫完后,會發到倉庫地址:待定
Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。
- state,驅動應用的數據源;
- view,以聲明方式將 state 映射到視圖;
- actions,響應在 view 上的用戶輸入導致的狀態變化。

store——包含以上概念的容器
view——以聲明方式將 state 映射到視圖
state 狀態、數據
getters:當state的數據變更時,getters的值也發生變化(相當于vuex中state的計算屬性)
mutations 更改狀態的函數
actions 異步操作
Modules 模塊。為了將store的狀態進行分割,每個模塊都有屬于自己的state、mutation、action、getter
Vuex V3.0
基礎代碼:
import Vue from 'vue'
import Vuex from 'vuex'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
Vue.use(Vuex)//使用vuex
// 將 store 實例作為插件安裝
const store = new Vuex.Store({/*狀態、數據 存儲 */state: {count: 0},/* 行為,更改狀態的函數 */mutations: {increment(state) {state.count++}}
})
new Vue({router,store,// 把 store 對象提供給 “store” 選項,這可以把 store 的實例注入所有的子組件render: function (h) {return h(App)}
}).$mount('#app')
state——狀態、數據
狀態、數據 **單一狀態樹 **作為一個“唯一數據源 (SSOT (opens new window))”而存在。
操作:
讀取state中數據
this.$store.state.count
變更state中的數據
//使用commit調用mutations內的increment方法
this.$store.commit("increment")
mapState
輔助函數
計算屬性顯示數據
作用:當獲取多個狀態減少申明多個狀態的重復和冗余,使用輔助函數來生成計算屬性。
main.js
import Vue from 'vue'
import Vuex from 'vuex'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
// 將 store 實例作為插件安裝
Vue.use(Vuex)
const store = new Vuex.Store({/*狀態、數據 存儲 */state: {count: 0,c: 1,},/* 行為,更改狀態的函數 */mutations: {increment(state) {state.count++}}
})
new Vue({router,store,render: function (h) {return h(App)}
}).$mount('#app')
home.vue
<template><div>首頁<p>{{ count }}</p><p>{{ countPlusLocalState }}</p><p>{{ countAlias }}</p></div>
</template>
<script>
import { mapState } from "vuex";
export default {//import引入的組件需要注入到對象中才能使用components: {},data() {//這里存放數據return {localCount: 123,};},//監聽屬性 類似于data概念computed: mapState({// 箭頭函數可使代碼更簡練count: (state) => state.count,// 傳字符串參數 'count' 等同于 `state => state.count`countAlias: "count",// 為了能夠使用 `this` 獲取局部狀態,必須使用常規函數countPlusLocalState(state) {return state.count + this.localCount;},}),// computed: mapState(["count"]),//監控data中的數據變化watch: {},//方法集合methods: {increment() {/* 獲取state內的數據值 */this.$store.commit("increment");console.log(this.$store.state.count);},},
};
</script>

簡寫形式
當計算屬性名稱和state的數據名稱相同可以簡寫成數組形式
computed: mapState(["count"]),
頁面內調用:
{{count}}

展開mapstate對象方便調用
<template><div>首頁<p>{{ count }}</p><p>{{ c }}</p><!-- <p>{{ countPlusLocalState }}</p> --><!-- <p>{{ countAlias }}</p> --></div>
</template>
<script>
computed: {//寫法1...mapState(["count", "c"]),//寫法2...mapState({count: "count",c: "c",}),
},
</script>
Getter——store內的計算屬性
當state內的數據變化后,getter內的數據也隨之變化
屬性訪問
Getter(state,getters)
state——(必填)返回state狀態數據內的值
示例:`state.count++`
getters——(可選)調用getters內的方法
示例:`getters.todolist.length`
完整示例:
vuex書寫:
const store = new Vuex.Store({/*狀態、數據 存儲 */state: {/* state練習 */count: 0,c: 1,/* getters練習 */todos: [{ id: 1, text: '...', done: true },{ id: 2, text: '...', done: false }]},/* 行為,更改狀態的函數 */mutations: {/* state練習 */increment(state) {state.count++}},getters: {doneTodos: (state) => {// 返回todo.done為true的列表項return state.todos.filter(todo => todo.done)},// 返回完整的列表todolist: (state) => {return state.todos;},// 接受其他getters作為第2個參數doneTodosCount(state, getters) {console.log(getters.todolist)return getters.todolist.length}}
})
vue頁面顯示數據
<template><div>首頁<p>為true的列表:{{ doneTodos }}</p><p>完整的列表項:{{ todolist }}</p><p>完整的列表長度:{{ doneTodosCount }}</p></div>
</template>
<script>export default {computed: {// 返回todos列表doneTodos() {return this.$store.getters.doneTodos;},todolist() {return this.$store.getters.todolist;},// 返回列表長度doneTodosCount() {return this.$store.getters.doneTodosCount;},},}
</script>
結果顯示:

方法訪問
通過給getters方法傳遞參數,從而實現返回想要的數據內容
vuex
/*狀態、數據 存儲 */
state: {//.../* getters練習 */todos: [{ id: 1, text: '...', done: true },{ id: 2, text: '...', done: false }]
},
getters: {//...//給getters方法傳遞參數getTodoById: (state) => (id) => {return state.todos.find(todo => todo.id === id)}
}
調用
<template><div><h3>通過方法訪問</h3><p>返回指定id的列表項:{{ gettodo(2) }}</p></div>
</template>
<script>//需要寫在methods方法內,前面寫在computed計算屬性內methods: {/* 返回指定id的列表項 */gettodo(id) {return this.$store.getters.getTodoById(id);},//...},
</script>
輸出:

mapGetters
輔助函數
注:只能映射到計算屬性中,無法映射到方法中
寫法與mapState類似
原本寫法:
computed: {// 返回todos列表doneTodos() {return this.$store.getters.doneTodos;},todolist() {return this.$store.getters.todolist;},// 返回列表長度doneTodosCount() {return this.$store.getters.doneTodosCount;},},
使用mapGetter寫法:
寫法1
import { mapGetter } from "vuex";computed: {...mapGetters(["doneTodos", "todolist", "doneTodosCount"]),},
寫法2
import { mapGetters } from "vuex";computed: {...mapGetters({doneTodos: "doneTodos",todolist: "todolist",doneTodosCount: "doneTodosCount",}),},
輸出結果:

mutations——更改state狀態的函數
Vuex 的 store 中的狀態的唯一方法是提交 mutation
基本格式:
type(state,mutation)
-
type:(事件類型)——命名在mutations中的函數名稱
示例:
increment (state, n) {state.count += n}
increment
為事件類型 state:【必選】(數據)——store中存儲的數據
-
mutation:【可選】(荷載)——調用事件類型時傳遞給事件的參數。
示例:
store.commit('increment', 10)
最后的10
為參數事件類型為increment
完整示例:
store
const store = new Vuex.Store({/*狀態、數據 存儲 */state: {//.../* mutation練習 */mut: 1},/* 行為,更改狀態的函數 */mutations: {//.../* mutation練習 */incrementdata(state, n) {state.mut += n.sum}},getters: {}
})
mutation.vue
<template><div class="">mutation獲取值:{{ mudata }}</div>
</template>
<script>
export default {components: {},data() {return {mudata: "",};},methods: {runmutation() {this.$store.commit({type: "incrementdata",sum: 1,});console.log(this.$store.state);this.mudata = this.$store.state.mut;},},mounted() {this.runmutation();},
};
</script>
結果:

Mutation 必須是同步函數,異步的話導致事件無法追蹤(原因在于mutation直接變更的是
State
(狀態)內的數據)
mapMutations
輔助函數
和
mapGetters
跟mapState
類似
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')`})}
}
使用常量替代 Mutation 事件類型
const SOME_MUTATION = 'SOME_MUTATION'
import { createStore } from 'vuex'const store = createStore({state: { ... },mutations: {// 我們可以使用 ES2015 風格的計算屬性命名功能來使用一個常量作為函數名[SOME_MUTATION] (state) {// 修改 state}}
})
示例:
const CHANGE_NAME = 'CHANGE_NAME'
mutations: {[CHANGE_NAME](state, data) {state.name = data}
},
Action 行為
參數概要
目的是為了處理mutation中的異步操作,原因在于,action提交的是mutation,而mutation直接變更的是state(狀態數據)內的值
- Action 提交的是 mutation,而不是直接變更狀態。
- Action 可以包含任意異步操作。
接收1個參數
第一個參數 返回store內所有的對象(所以可以用解構賦值的方式獲取指定store內的對象)
打印
increment (context)
context的數據結果

寫法1.
actions: {increment (context) {setTimeout(() => {context.commit('increment')}, 1000)}}
寫法2.
actions: {incrementAsync ({ commit }) {setTimeout(() => {commit('increment')}, 1000)}
}
調用action
store.dispatch('increment')
異步調用action
actions: {incrementAsync ({ commit }) {setTimeout(() => {commit('increment')}, 1000)}
}
載荷形式分發(同mutation)
// 以載荷形式分發
store.dispatch('incrementAsync', {amount: 10
})// 以對象形式分發
store.dispatch({type: 'incrementAsync',amount: 10
})
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')`})}
}
組合Action(同時觸發多個action)
state: {//.../* action練習 */act: 1,
},
mutations: {//.../* action練習 */action(state) {console.log(state.act)state.act++console.log('返回存儲的值:' + state.act)}
},
actions: {//...action(context) {console.log(context);context.commit('action')},/* action異步分發 */actionA(con) {return new Promise((resolve, reject) => {setTimeout(function () {con.commit('action')console.log('actionA:' + con.state.act)resolve()}, 1000)})},actionB(con) {// 異步的形式調用2次actionreturn con.dispatch('actionA').then(() => {con.commit('action')console.log('actionB:' + con.state.act)})},/* async await包裹異步函數寫法 */async actionA(con) {// commit觸發mutations中的action行為導致act+1,//dispatch調用action中的action,再次觸發了mutations中的action行為導致act+1,con.commit('action', await con.dispatch('action'))//相當于異步+2console.log('actionB調用=>A:' + con.state.act);//3},async actionB(con) {await con.dispatch('actionA');//3}}
界面內調用:
this.$store.dispatch("actionB");

用async await 寫成同步形式
/* async await包裹異步函數寫法 */async actionA(con) {// commit觸發mutations中的action行為導致act+1,//dispatch調用action中的action,再次觸發了mutations中的action行為導致act+1,con.commit('action', await con.dispatch('action'))//相當于異步+2console.log('actionB調用=>A:' + con.state.act);//3},async actionB(con) {await con.dispatch('actionA');//3}

module 模塊分割
Vuex 允許我們將 store 分割成模塊(module)
多模塊注冊及基本使用
思路分別寫2個goods和users2個不同的模塊,最后注冊引入到實例中
完整的store對象【全部代碼】
/* 用module之后 */
const store = new Vuex.Store({/* 全局狀態 */state: {name: 'ccc'},/* 全局狀態變更 */mutations: {},/* 全局行為 */actions: {},/* 全局狀態返回類似計算屬性 */getters: {},modules: {goods,// users,//注冊模塊的方式進行注冊/* 多模塊公用 */goodslist: {namespaced: true,//開啟命名空間/* 公用相同的模型 */modules: {goods1: goods,goods2: goods,}}}
})
goods模型
const goods = {namespaced: true,// 普通的純對象形式申明,這個狀態對象會通過引用被共享,則當多模型共用的時候數據也會發生改變【模型重用】// state: {// name: '默認goods',// },// 函數形式每個模型都是單獨不會同時改變【模型重用】state() {return {name: '默認goods',}},// 更改狀態mutations: {GOODS(state, data) {state.name = data}},// 行為actions: {change_name(state, data) {state.commit('GOODS', data)}},// 計算屬性getters: {getname: (state) => {return state.name + ' ' + state.name}},}
export default goods;
users模型
const users = {namespaced: true,state: {name: '默認users',},// 更改狀態mutations: {[CHANGE_NAME](state, data) {state.name = data}},// 行為actions: {change_name(state, data) {state.dispatch('CHANGE_NAME', data)}},// 計算屬性getters: {getname: (state) => {return state.name}},}
export default users;
界面調用module.vue
<template><div class=""><h2>模型1:goods</h2><p>當前名稱:{{ goods }}</p><p>getter獲取的當前名稱:{{ getname }}</p>商品名稱:<input type="text" v-model="goodsname" /><input type="button" @click="changegoodsname" value="修改商品名稱" /><h2>多模型共用</h2><p>goods模型1 name值:{{ goodslist1 }}</p><p>goods模型2 name值:{{ goodslist2 }}</p><h3>注冊嵌套模塊</h3><p>goods模型3 name值:{{ goodslist3 }}</p><h2>模型2:users</h2><p>當前的名稱:{{ users }}</p></div>
</template>
<script>
import { mapGetters, mapState, mapActions, mapMutations } from "vuex";
export default {//import引入的組件需要注入到對象中才能使用components: {},data() {//這里存放數據return { goodsname: "123" };},//監聽屬性 類似于data概念computed: {...mapState({goods: (state) => {return state.goods.name;},users: (state) => {return state.users.name;},goodslist1: (state) => {return state.goodslist.goods1.name;},goodslist2: (state) => {return state.goodslist.goods2.name;},goodslist3: (state) => {return state.goodslist.goods2.name;},}),...mapGetters("goods", {getname: "getname",}),},//監控data中的數據變化watch: {},//方法集合methods: {/* 用mutation同步修改值 */// ...mapMutations("goods", {// changegoods: "GOODS",// }),/* 用action異步修改值 */...mapActions("goods", {actionchangegoods: "change_name",}),changegoodsname() {// this.changegoods(this.goodsname);this.actionchangegoods(this.goodsname);},},//生命周期 - 創建完成(可以訪問當前this實例)created() {},//生命周期 - 掛載完成(可以訪問DOM元素)mounted() {},
};
</script>
模塊動態注冊【保留state】
// 注冊模塊 `myModule`
//{ preserveState: true }使模塊中的state無法被覆寫,保持原樣【保留原始state】,注冊的模塊state無法寫入
store.registerModule('users', users, { preserveState: false })
// 注冊嵌套模塊 `goodslist/myModule`(前面的goodslist必須存在的情況下才能進行嵌套)
store.registerModule(['goodslist', 'goods3'], goods, { preserveState: false })
模塊重用
前面完整代碼中的一部分goods1和goods2模塊重用的方式寫入
goods3注冊模塊的方式寫入。用的也是同一個模塊
/* 用module之后 */
const store = new Vuex.Store({//...modules: {goods,// users,//注冊模塊的方式進行注冊/* 多模塊公用 */goodslist: {namespaced: true,//開啟命名空間/* 公用相同的模型 */modules: {goods1: goods,goods2: goods,}}}//...
})
// 注冊嵌套模塊 `goodslist/myModule`(前面的goodslist必須存在的情況下才能進行嵌套)
store.registerModule(['goodslist', 'goods3'], goods, { preserveState: false })
結果展示
點擊按鈕,修改上方商品名稱內容

在線鏈接【需翻墻】https://codesandbox.io/s/wonderful-night-ew7uj2?file=/src/views/module1.vue
Vuex V4.0
State(不變)
Getter(不變)
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務

喜歡的朋友記得點贊、收藏、關注哦!!!