mount 返回状态_状态管理模式 — Vuex如何使用?
Extract
試想當(dāng)我們?cè)陂_發(fā)一個(gè)Vue應(yīng)用程序時(shí),如果在一個(gè)項(xiàng)目中頻繁的使用組件傳參的方式來同步data中的值,一旦項(xiàng)目結(jié)構(gòu)變得復(fù)雜,管理和維護(hù)這些數(shù)據(jù)將變得十分繁瑣,為此,Vue為這些被多個(gè)組件共同使用的data提供了一個(gè)統(tǒng)一的管理工具---Vuex。
Vuex是專為Vue.js應(yīng)用程序開發(fā)的狀態(tài)管理模式,集中存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài)(數(shù)據(jù)),并以相同的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化。
安裝
可在項(xiàng)目目錄下直接通過npm安裝,其他安裝方式詳見Vuex安裝。
npm install vuex --save使用
首先需要?jiǎng)?chuàng)建一個(gè)store實(shí)例,引入你創(chuàng)建的所有modules:
目錄結(jié)構(gòu)/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實(shí)例并暴露出來:
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的基本屬性,稱為單一狀態(tài)樹,如果熟悉Java面向?qū)ο缶幊痰脑?#xff0c;我們可以將其類比為成員變量:
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狀態(tài)可通過以下兩種方式:
//方法一:在根實(shí)例中注冊(cè)store選項(xiàng),該實(shí)例會(huì)注入到根組件下的所有子組件中this.$store.state.name?//方法二:使用mapState輔助函數(shù)import { mapState } from 'vuex'?export default {// ...computed: mapState({// 箭頭函數(shù)可使代碼更簡(jiǎn)練count: state => state.count,?// 傳字符串參數(shù) 'count' 等同于 `state => state.count`countAlias: 'count',?// 為了能夠使用 `this` 獲取局部狀態(tài),必須使用常規(guī)函數(shù)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呢?因?yàn)橛袝r(shí)候我們需要從state中派生出一些狀態(tài),例如對(duì)列表進(jìn)行過濾,同樣我們可與Java實(shí)現(xiàn)類比:
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歲及以下用戶對(duì)象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歲及以下用戶對(duì)象children: state => state.users,filter(user => user.age <= 18), }在Vue組件中我們可以通過屬性訪問或者通過mapGetters來獲取對(duì)象:
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中狀態(tài)的唯一方法,Vuex中的mutation類似于事件:每個(gè)mutation都有一個(gè)字符串的事件類型(type)和一個(gè)回調(diào)函數(shù)(handler)。這個(gè)回調(diào)函數(shù)就是我們實(shí)際進(jìn)行狀態(tài)更改的方法,并且他會(huì)接受state作為第一個(gè)參數(shù)。
mutation的實(shí)際使用類似于Java中的set方法,是設(shè)置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的使用方式,我們不能直接調(diào)用一個(gè)mutation handler,而是提交一個(gè)名為xxx的mutation,觸發(fā)相應(yīng)的mutation handler執(zhí)行具體的變更。
Users users = new Users(); users.setStatus();this.$store.commit("setStatus")在Java中set函數(shù)可以傳入?yún)?shù)進(jìn)而變更成員變量。
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);}}調(diào)用set函數(shù):
Users users = new Users();users.setUser(newUser);在Vuex中我們也可以通過提交載荷(Payload)的方式向store.commit傳入額外的參數(shù),即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函數(shù)的目的是相同,但mutation在使用中最大的原則 --- 必須是同步函數(shù)。
在mutation中混合異步調(diào)用會(huì)導(dǎo)致你的程序很難調(diào)試,當(dāng)我們調(diào)用了兩個(gè)包含異步回調(diào)的mutation來改變狀態(tài),我們無法知道什么時(shí)候回調(diào)以及哪個(gè)先回調(diào),因此在Vuex中,mutation都是同步事務(wù)。
Action
action類似于mutation是可“調(diào)用”的方法,兩者不同點(diǎn)在于:
- action提交mutation,而不直接變更狀態(tài);
- action可以包含任意異步操作。
這段代碼中我們注冊(cè)了一個(gè)簡(jiǎn)單的異步action,我們通過request向后端發(fā)送請(qǐng)求,請(qǐng)求新用戶,然后我們?cè)诨卣{(diào)函數(shù)中提交mutation變更狀態(tài)。
this.$store.dispatch('updateUser')action同樣可以通過提交載荷的方式進(jìn)行分發(fā):
//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
使用單一狀態(tài)樹,應(yīng)用的所有狀態(tài)都會(huì)集中到一個(gè)較大的對(duì)象,隨著應(yīng)用迭代變得越來越復(fù)雜,store對(duì)象會(huì)變得越來越臃腫。為了解決以上問題,Vuex允許我們將對(duì)象模塊(Module)化,每個(gè)模塊擁有自己的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 的狀態(tài)store.state.b // -> moduleB 的狀態(tài)在默認(rèn)情況下,模塊內(nèi)部的action、mutation和getter是注冊(cè)在全局命名空間的,這樣使得多個(gè)模塊能夠?qū)ν籱utation或action作出響應(yīng)。
目錄結(jié)構(gòu)/src|-main.js|-/store|-/modules|-user.js|-team.js|-product.js|-chat.js|-notification.js|-index.js以u(píng)ser.js為例,讓我們看一下一個(gè)完整的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歲及以下用戶對(duì)象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中將各個(gè)module注冊(cè)到store對(duì)象中:
//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},//嚴(yán)格模式:無論何時(shí)發(fā)生了狀態(tài)變更且不是由 mutation 函數(shù)引起的,將會(huì)拋出錯(cuò)誤。這能保證所有的狀態(tài)變更都能被調(diào)試工具跟蹤到。strict: true})?然后在main.js中將store放進(jìn)我們的Vue應(yīng)用程序中:
//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')至此,這便是一個(gè)完整的Vuex的使用實(shí)例,雖然在Vue中我們也可以通過屬性傳遞的方式在不同組件之間傳遞data,但是當(dāng)同一個(gè)data需要被多個(gè)組件同時(shí)調(diào)用,數(shù)據(jù)的一致性便很難保證,Vuex的引入則很好的解決了這一問題,Vuex中狀態(tài)的變化是全局的,是實(shí)時(shí)計(jì)算的,當(dāng)我們getter的計(jì)算依托于多個(gè)state時(shí),當(dāng)我們提交了新的commit變更狀態(tài),相應(yīng)的getter返回值也會(huì)變化,這讓我們不用過多分心于數(shù)據(jù)的一致性。
總結(jié)
以上是生活随笔為你收集整理的mount 返回状态_状态管理模式 — Vuex如何使用?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lede更改软件源_Linux的上传和下
- 下一篇: c mysql并行多条sql_Linu