vuex
state:定義存貯數(shù)據(jù)的倉庫 ,可通過this.$store.state 或mapState訪問
getter:獲取 store 值,可認為是 store 的計算屬性,可通過this.$store.getter 或 mapGetters訪問
mutation:同步改變 store 值,為什么會設(shè)計成同步,因為mutation是直接改變 store 值, vue 對操作進行了記錄,如果是異步無法追蹤改變.可通過mapMutations調(diào)用
action:異步調(diào)用函數(shù)執(zhí)行mutation,進而改變 store 值,可通過 this.$dispatch或mapActions 訪問
modules:模塊,如果狀態(tài)過多,可以拆分成模塊,最后在入口通過...解構(gòu)引入
-
types.ts 定義靜態(tài)字符串常量 (src/store/types.ts)
export const LOGIN: string = 'LOGIN_DOCTOR'; export const REFRESH_TOKEN: string = 'REFRESH_TOKEN'; export const LOGOUT: string = 'LOGOUT_DOCTOR'; export const TITLE: string = '健康';
-
定義store (src/store.ts)
import Vue from 'vue'; import Vuex from 'vuex'; import * as types from './store/types'; Vue.use(Vuex); export default new Vuex.Store({ state: { // 用戶信息 user: {}, // token值 token: null, // 網(wǎng)站標(biāo)題 title: '', }, mutations: { [types.LOGIN]: (state, data) => { localStorage.token = data; state.token = data; }, [types.REFRESH_TOKEN]: (state, data) => { localStorage.token = data; state.token = data; }, [types.LOGOUT]: (state: any) => { localStorage.removeItem('token'); state.user = null; state.token = null; }, [types.TITLE]: (state, data) => { state.title = data; }, }, actions: { loginAction(state, payload:any) { console.log('loginAction) } }, modules: {}, });
-
在頁面中使用
<template> <div> {{token}} <div class='hello'> Token: <input v-model='token' type='text'> <div> <el-button type='primary' @click='changeName'>主要按鈕</el-button> </div> <div> <el-button type='danger' @click='logout'>注銷</el-button> </div> <div> <el-button type='danger' @click='getUserInfo'>獲取用戶信息</el-button> </div> </div> </div> </template> <script lang='ts'> import { Component, Vue } from 'vue-property-decorator'; import { State, Action } from 'vuex-class'; @Component({ components: { }, }) export default class Home extends Vue { // private token: string|null = this.$store.state.token; // 全局state action getters mutation的使用方法 @State('token') private token!: string; @Getter load!: boolean; /** // 上面兩句相當(dāng)于 computed: { token() { return this.$store.state.login }, load() { return this.$store.getters.load } }, **/ // 調(diào)用的時候: this.loginAction(paypload) 相當(dāng)于 this.$store.dispatch('loginAction', payload) @Action loginAction!: (payload: any) => void; // 調(diào)用的時候: this.logoutMutation() 相當(dāng)于 this.$store.commit(types.logout); @Mutation(types.LOGOUT) private logoutMutation!: () => void; // vue中data中的字段 private name!: string; private changeName() { this.name = `${this.name}hello world`; } private mounted() { // 相當(dāng)于 this.$store.dispatch('loginAction', payload); this.loginAction({a: '測試loginAction'}); } // 登出 private async logout() { const response = await UsersHttp.logout({}); if (response.status === 200) { // this.$store.commit(types.LOGOUT); this.logoutMutation(); this.$router.push({ path: '/', }); } } // 獲取用戶信息 private async getUserInfo() { const response = await UsersHttp.getUserInfo({}); if (response.data.status === 200) { console.log('測試數(shù)據(jù): 該模塊存在控empty-block'); } } } </script>
-
namespace局部module的狀態(tài)管理
import { Vue, Component, Prop, Watch } from 'vue-property-decorator'; import { State, Getter, Action, Mutation, namespace } from 'vuex-class'; const userModuleStore = namespace('userModuleStore'); @Component export default class ViewMenuConditionComponent extends Vue { //模塊內(nèi)getters用法挽唉, @userModuleStore.Getter('getUserProps1') props1; @userModuleStore.Getter('getUserProps2') props2; @Action('foo') actionFoo // 全局的action調(diào)用方法 @Mutation('foo') mutationFoo // 全局的mutation調(diào)用方法 created () { this.props1 // -> store.userStore.prop1 this.props2 // -> store.userStore.prop2 this.actionFoo({ value: true }) // -> store.dispatch('foo', { value: true }) this.mutationFoo({ value: true }) // -> store.commit('foo', { value: true }) } }
-
使用方法
import { Vue, Component, Prop, Watch } from 'vue-property-decorator' import { State, Getter, Mutation, Action } from 'vuex-class' import { Bind, Debounce } from 'lodash-decorators' import { UBT } from '@/decorator' import HelloWorld from '@/components/HelloWorld.vue' import BasicMixin from '@/mixin/PrintMixin' @Component({ components: { HelloWorld }, mixins: [BasicMixin] }) export default class EleComponent extends Vue { @Prop({ default: 'Hello' }) private text!: string @State(state => state.user) private user!: string @Getter('email') private email!: string private msg: string = 'Hello Element' private name: string = 'Typescript' private get userInfo (): string { return this.text + this.name } private set userInfo (val: string) { this.text = val } @Mutation('setUserEmail') private setUserEmail!: (email: string) => void @Action('getUserInfo') private getUserInfo!: (params: {token: string}) => Promise<any> @Watch('name', { deep: true }) private onNameChange () { console.log('name has been changed!') } @UBT('click', Date.now()) @Bind() @Debounce(300) private handleClick () { console.log('click', this.text) } }