如何使用 vue + typescript 編寫頁面 ( vuex裝飾器部分 )

董輝輝發表於2019-02-16

簡單瞭解一下vuex

是vue提供的一款store,用來儲存頁面共享資料

何時需要vuex

一般來說,資料分為兩種方式

  1. 自有資料,即元件本身持有資料,表現即 data部分
  2. 外部資料,可由prop標籤屬性,inject父級注入,vuex提供。

元件本身自身持有資料內容,並不需要外部的參與的情況下,不需要外部資料。但是在一般來說,使用外部資料比較常見。 prop與父級緊密相關

使用inject注入時,無法有效追蹤層級時,查詢內容提供者容易出錯,通常不建議跨多個層級使用

使用vuex好處

  1. 統一資料來源,方便查詢 對標Provide/Inject
  2. 方便資料共享,對標Prop 子-父 傳遞資料

不方便的地方

暫時還沒有發現,發現了再補充

使用vuex要考慮的地方

使用vuex的目的就是提高資料的複用性,但是不可以盲目使用vuex。

  • 和元件自生無關的資料,可以放在store裡。
  • 在不同頁面需要引用相同資料時,需要放在store裡,以減少網路請求的次數。
  • 單純的父子傳遞資料,不一定要放在store裡

基礎內容

開打demo的store.ts 檔案作為參照


export default new Vuex.Store({
  state: { /* 狀態庫 */ },
  mutations: { /* 同步計算庫 使用commit觸發 */ },
  actions: { /* 非同步計算庫 使用dispatch觸發 */ },
  getters: { /* 計算屬性  */ },
  modules: { /* 分模組 */
    test: {
      namespaced: true, /* 開啟module模式 */
      state: {
        foo: "this is foo"
      },
      getters: {
        getFoo(state) { 
          return state.foo;
        }
      },
      mutations: {
        setFoo(state, foo) {
          state.foo = foo;
        }
      },
      actions: {
        setFoo({ commit }, foo) {
          setTimeout(() => {
            commit('setFoo',foo)
          }, 1e3);
        }
      }
    }
  }
})
複製程式碼

認識vuex的裝飾器 vuex-class

import {
  State,
  Getter,
  Action,
  Mutation,
  namespace
} from 'vuex-class'
複製程式碼

1. @namespace 名稱空間

在我們開啟module模式的時候,從模組下對映需要使用到namespace

State外,其餘可以行內書寫方式直接引用,不需要引入 namespace

namespace的兩種使用方式

  1. 直接裝飾器方式,可以簡單使用
@Component
class MyComponent extends Vue{
    @namespace('test').State foo!: string;
}
複製程式碼
  1. 引用裝飾器方式,這種方式適合多個需要引用時簡化書寫namespace
const TestModule = namespace("test")

@Component
class MyComponent extends Vue{
    @TestModule.State foo!: string;
}
複製程式碼

2. @State 狀態對映

  • 直接對映 @State foo@State("foo") foo 相同
@Component
class MyComponent extends Vue{
    @namespace('test').State foo!: string;
}
複製程式碼
  • 獲取計算後的state

state對映到元件時,是放在computed下的,因此本身為計算屬性。

@Component
class MyComponent extends Vue{
    /* 只從 state 獲取*/
    @namespace('test').State(state=>state.foo) foo!: string;
    /*從state和getters上獲取*/
    @namespace('test').State((state,getters)=>state.foo+'getter:'+getters.getFoo) svsgfoo!: string;
}
複製程式碼
  • 內部使用namespace 如果不想在外部使用namespace,可以使用引數傳遞namespace
@Component
class MyComponent extends Vue{
    @State("foo",{namespace:"test"}) foo!: string;
}
複製程式碼

3. @Getter 計算屬性

和State類似,但是不支援再次計算。

@Component
class MyComponent extends Vue{
   @Getter("test/getFoo") namefoo!:string;
   @Getter("getFoo",{namespace:"test"}) foo!:string;
   @namespace("test").Getter getFoo!:string;
}
複製程式碼

4. @Action 非同步計算庫

書寫方式和Getter類似

@Component
class MyComponent extends Vue{
   @Action("test/setFoo") setFoo!: Function;
}

複製程式碼
  • action可以配合promise + async/await 一同使用
actions:{
    async queryState({commit},token){
        let result = await Axios.get("url",{data:{ token }})
        commit('state',result.data)
        return result.data
    }
}
複製程式碼
@Component
class MyComponent extends Vue{
   private token:string="best";
   @Action queryState!: Function;
   
   async onQueryStateClick(){
       let data = await this.queryState(this.token)
       // todo ...
   }
}
複製程式碼

5. @Mutation 同步計算庫

書寫方式和Action類似

@Component
class MyComponent extends Vue{
   @Action("test/setFoo") setFoo!: Function;
}

複製程式碼

但是mutation會立即返回結果,因此非同步請求應該放在action中

更多內容 :vuex可以參照這裡,vuex裝飾器具體可參照 vuex-class

上一章:如何使用 vue + typescript 編寫頁面 ( 基礎裝飾器部分 )

相關文章