mount 返回状态_状态管理模式 — Vuex如何使用?
Extract
試想當我們在開發一個Vue應用程序時,如果在一個項目中頻繁的使用組件傳參的方式來同步data中的值,一旦項目結構變得復雜,管理和維護這些數據將變得十分繁瑣,為此,Vue為這些被多個組件共同使用的data提供了一個統一的管理工具---Vuex。
Vuex是專為Vue.js應用程序開發的狀態管理模式,集中存儲管理應用的所有組件的狀態(數據),并以相同的規則保證狀態以一種可預測的方式發生變化。
安裝
可在項目目錄下直接通過npm安裝,其他安裝方式詳見Vuex安裝。
npm install vuex --save使用
首先需要創建一個store實例,引入你創建的所有modules:
目錄結構/src|-main.js|-/store|-/modules|-index.js// index.js import Vue from 'vue' import Vuex from 'vuex' import user from './modules/user' import team from './modules/team' import product from "./modules/product"; import chat from "./modules/chat"; import notification from "./modules/notification";Vue.use(Vuex)export default new Vuex.Store({modules: {user,team,product,chat,notification},strict: true })在main.js中,引入store實例并暴露出來:
import Vue from 'vue'import App from './App.vue'import store from './store'?export default new Vue({render: h => h(App),store}).$mount('#app')State
State是Vuex的基本屬性,稱為單一狀態樹,如果熟悉Java面向對象編程的話,我們可以將其類比為成員變量:
public class User {//成員變量private String name;private Integer age;private String gender;}public class Users {private List<User> users;}const state = () => ({//Stateusers: [{name: ...,age: ...,gender: ..., },.........] })在Vue組件中獲得Vuex狀態可通過以下兩種方式:
//方法一:在根實例中注冊store選項,該實例會注入到根組件下的所有子組件中this.$store.state.name?//方法二:使用mapState輔助函數import { mapState } from 'vuex'?export default {// ...computed: mapState({// 箭頭函數可使代碼更簡練count: state => state.count,?// 傳字符串參數 'count' 等同于 `state => state.count`countAlias: 'count',?// 為了能夠使用 `this` 獲取局部狀態,必須使用常規函數countPlusLocalState (state) {return state.count + this.localCount}})}?Getter
getter的使用可類比為Java中的get方法。
public class User {//成員變量private String name;private Integer age;private String gender;}public class Users {private List<User> users;//get方法public List<User> getUsers() {return users;}}//State const state = () => ({users: [{name: ...,age: ...,gender: ..., },.........] })//getter const getters = {users: state => state.users, }如果僅僅如此,為何不直接獲取state呢?因為有時候我們需要從state中派生出一些狀態,例如對列表進行過濾,同樣我們可與Java實現類比:
public class User {//成員變量private String name;private Integer age;private String gender;}public class Users {private List<User> users;//get方法public List<User> getUsers() {return users;}//返回18歲及以下用戶對象public List<User> getChildren() {List<User> children = new ArrayList<>;for (User item: this.users) {if (item.age <= 18) {children.add(item)}}return children;}}//State const state = () => ({users: [{name: ...,age: ...,gender: ..., },.........] })//getter const getters = {users: state => state.users,//返回18歲及以下用戶對象children: state => state.users,filter(user => user.age <= 18), }在Vue組件中我們可以通過屬性訪問或者通過mapGetters來獲取對象:
import { mapGetters } from 'vuex'export default {computed: {...mapGetters(['users',]),},methods: {printUsers() {//通過mapGetters訪問console.log(this.users)//通過屬性訪問console.log(this.$store.getters.users)}}}Mutation
提交mutation是更改Vuex的store中狀態的唯一方法,Vuex中的mutation類似于事件:每個mutation都有一個字符串的事件類型(type)和一個回調函數(handler)。這個回調函數就是我們實際進行狀態更改的方法,并且他會接受state作為第一個參數。
mutation的實際使用類似于Java中的set方法,是設置state值的唯一方式。
public class User {//成員變量private String name;private Integer age;private String gender;}public class Users {private List<User> users;private Boolean status;//set方法public void setStatus() {this.status = true; }}//State const state = () => ({users: [{name: ...,age: ...,gender: ..., },.........],status: null, })//mutation const mutations = {setStatus(state) {state.status = true} }但不同于Java中set的使用方式,我們不能直接調用一個mutation handler,而是提交一個名為xxx的mutation,觸發相應的mutation handler執行具體的變更。
Users users = new Users(); users.setStatus();this.$store.commit("setStatus")在Java中set函數可以傳入參數進而變更成員變量。
public class User {//成員變量private String name;private Integer age;private String gender;}public class Users {private List<User> users;private Boolean status;//set方法public void setStatus() {this.status = true; }public void setUser(User user) {this.users.add(user);}}調用set函數:
Users users = new Users();users.setUser(newUser);在Vuex中我們也可以通過提交載荷(Payload)的方式向store.commit傳入額外的參數,即mutation的載荷。
//Stateconst state = () => ({users: [{name: ...,age: ...,gender: ..., },.........],status: null,})//mutationconst mutations = {setStatus(state) {state.status = true},setUser(state, user) {state.users.push(user)}}在組件中提交攜帶載荷的mutation:
this.$store.commit('setUser', user)或者使用mapMutations映射出來:
import { mapMutations } from 'vuex'?export default {methods: {...mapMutations(['setUser',]),appendUser(user){this.setUser(user)},}}綜上看來,mutation的使用與set函數的目的是相同,但mutation在使用中最大的原則 --- 必須是同步函數。
在mutation中混合異步調用會導致你的程序很難調試,當我們調用了兩個包含異步回調的mutation來改變狀態,我們無法知道什么時候回調以及哪個先回調,因此在Vuex中,mutation都是同步事務。
Action
action類似于mutation是可“調用”的方法,兩者不同點在于:
- action提交mutation,而不直接變更狀態;
- action可以包含任意異步操作。
這段代碼中我們注冊了一個簡單的異步action,我們通過request向后端發送請求,請求新用戶,然后我們在回調函數中提交mutation變更狀態。
this.$store.dispatch('updateUser')action同樣可以通過提交載荷的方式進行分發:
//Stateconst state = () => ({users: [{name: ...,age: ...,gender: ..., },.........],status: null,})?//actionconst actions = {appendUser({commit}, user) {commit('setUser', user)}}//mutationconst mutations = {setStatus(state) {state.status = true},setUser(state, user) {state.users.push(user)}} this.$store.dispatch('appendUser', newUser)或者使用mapAction映射出來:
import { mapActions } from 'vuex'?export default {// ...methods: {...mapActions(['appendUser',]),test() {this.appendUser(user)}}}Module
使用單一狀態樹,應用的所有狀態都會集中到一個較大的對象,隨著應用迭代變得越來越復雜,store對象會變得越來越臃腫。為了解決以上問題,Vuex允許我們將對象模塊(Module)化,每個模塊擁有自己的state、mutation、action、getter甚至嵌套子模塊。
const moduleA = {state: () => ({ ... }),mutations: { ... },actions: { ... },getters: { ... }}?const moduleB = {state: () => ({ ... }),mutations: { ... },actions: { ... }}?const store = new Vuex.Store({modules: {a: moduleA,b: moduleB}})?store.state.a // -> moduleA 的狀態store.state.b // -> moduleB 的狀態在默認情況下,模塊內部的action、mutation和getter是注冊在全局命名空間的,這樣使得多個模塊能夠對同一mutation或action作出響應。
目錄結構/src|-main.js|-/store|-/modules|-user.js|-team.js|-product.js|-chat.js|-notification.js|-index.js以user.js為例,讓我們看一下一個完整的Module是怎樣的。
//user.jsimport {request} from '../../lib/network/request'?//Stateconst state = () => ({users: [{name: ...,age: ...,gender: ..., },.........],status: null,})?//actionconst actions = {updateUser({commit}) {request({url: '/user/getNewUser'method: 'get'}).then(res => {commit('setUser', res.data)})}}?//getterconst getters = {users: state => state.users,//返回18歲及以下用戶對象children: state => state.users,filter(user => user.age <= 18),}//mutationconst mutations = {setStatus(state) {state.status = true},setUser(state, user) {state.users.push(user)}}?export default {state,getters,actions,mutations}然后需要在/modules目錄下的index.js中將各個module注冊到store對象中:
//index.jsimport Vue from 'vue'import Vuex from 'vuex'import user from './modules/user'import team from './modules/team'import product from "./modules/product";import chat from "./modules/chat";import notification from "./modules/notification";?Vue.use(Vuex)?export default new Vuex.Store({modules: {user,team,product,chat,notification},//嚴格模式:無論何時發生了狀態變更且不是由 mutation 函數引起的,將會拋出錯誤。這能保證所有的狀態變更都能被調試工具跟蹤到。strict: true})?然后在main.js中將store放進我們的Vue應用程序中:
//main.jsimport Vue from 'vue'import App from './App.vue'import store from './store'?export default new Vue({render: h => h(App),store}).$mount('#app')至此,這便是一個完整的Vuex的使用實例,雖然在Vue中我們也可以通過屬性傳遞的方式在不同組件之間傳遞data,但是當同一個data需要被多個組件同時調用,數據的一致性便很難保證,Vuex的引入則很好的解決了這一問題,Vuex中狀態的變化是全局的,是實時計算的,當我們getter的計算依托于多個state時,當我們提交了新的commit變更狀態,相應的getter返回值也會變化,這讓我們不用過多分心于數據的一致性。
總結
以上是生活随笔為你收集整理的mount 返回状态_状态管理模式 — Vuex如何使用?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lede更改软件源_Linux的上传和下
- 下一篇: c mysql并行多条sql_Linu