【问题标题】:Typescript stage mangement with quasar and vue not working类星体和 vue 的打字稿状态管理不起作用
【发布时间】:2021-05-04 19:30:16
【问题描述】:

我是 vuex 的新手,我无法设置它。 我的商店文件夹结构如下所示

  • 商店
  • 模块示例
    • index.ts
    • mutations.ts
    • getters.ts
    • state.ts
  • index.ts
  • store-flag.d.ts

文件如下所示: index.ts

import { store } from 'quasar/wrappers';
import Vuex from 'vuex';

import example from './module-example';
// import { ExampleStateInterface } from './module-example/state';

/*
 * If not building with SSR mode, you can
 * directly export the Store instantiation
 */

export interface StateInterface {
  // Define your own store structure, using submodules if needed
  // example: ExampleStateInterface;
  // Declared as unknown to avoid linting issue. Best to strongly type as per the line above.
  example: unknown;
}

export default store(function ({ Vue }) {
  Vue.use(Vuex);

  const Store = new Vuex.Store<StateInterface>({
    modules: {
     example
    },

    // enable strict mode (adds overhead!)
    // for dev mode only
    strict: !!process.env.DEBUGGING
  });

  if (process.env.DEV && module.hot) {
    module.hot.accept(['./showcase'], () => {
      const newShowcase = require('./showcase').default
      Store.hotUpdate({ modules: { showcase: newShowcase } })
    })
  }

  return Store;
});

商店标志.d.ts

/* eslint-disable */
// THIS FEATURE-FLAG FILE IS AUTOGENERATED,
//  REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING
import "quasar/dist/types/feature-flag";

declare module "quasar/dist/types/feature-flag" {
  interface QuasarFeatureFlags {
    store: true;
  }
}

index.ts

import { Module } from 'vuex';
import { StateInterface } from '../index';
import state, { ExampleStateInterface } from './state';
import getters from './getters';
import mutations from './mutations';

const exampleModule: Module<ExampleStateInterface, StateInterface> = {
  namespaced: true,
  getters,
  mutations,
  state
};

export default exampleModule;

mutations.ts

import { MutationTree } from 'vuex';
import state, { ExampleStateInterface } from './state';

const mutation: MutationTree<ExampleStateInterface> = {
  someMutation (state: ExampleStateInterface, token: ExampleStateInterface) {
    state = token
  }
};

export default mutation;

getters.ts

import { GetterTree } from 'vuex';
import { StateInterface } from '../index';
import { ExampleStateInterface } from './state';

const getters: GetterTree<ExampleStateInterface, StateInterface> = {
  getToken (state: ExampleStateInterface): string {
    return state.token
  },
  getUserName (state: ExampleStateInterface): string {
    return state.username
  },
  getRetrievalTime (state: ExampleStateInterface): Date {
    return state.retrievalTime
  }
};

export default getters;

state.ts

export interface ExampleStateInterface {
  token: string;
  username: string;
  retrievalTime: Date;
}

function state(): ExampleStateInterface {
  return { token:'dddddd', username: 'ddd', retrievalTime: new Date() }
};

export default state;

我可以像这样访问状态

console.log(this.$store.state.example.retrievalTime)

但是由于任何类型为any而返回错误

但是,我无法执行突变。我试过了,但似乎没有任何反应。

this.$store.commit('example/someMutation', { token:'new', username: 'new', retrievalTime: new Date() })

我无法在线找到任何适用于 quasar typescript 的示例。任何建议都可以接受。

【问题讨论】:

    标签: typescript vue.js vuex quasar-framework quasar


    【解决方案1】:

    这个问题已经 8 个月了,但我将分享我的解决方案,以使用新的 Composition API 在 Quasar 中使用 TypeScript 使用 Vuex:

    Vue 文件/页面非常简单直接:

    MyVuePage.vue:

    <template>
      <q-page padding>
        <!-- content -->
        <p>This is the survival page.</p>
        <p>This is my counter: {{ counter }}</p>
        <q-btn color="primary" label="Increment" @click="addToCounter(3)" />
      </q-page>
    </template>
    
    <script>
    import { defineComponent, computed } from 'vue';
    import { useStore } from 'src/store';
    
    export default defineComponent({
      name: 'Survival',
      setup() {
        const store = useStore();
    
        // store.getters['example/counter']
        // void store.commit('example/increment', val)
    
        return {
          counter: computed(() => store.state.example.counter),
          addToCounter: (val) => void store.dispatch('example/increment', val),
        };
      },
    });
    </script>
    

    我修改了默认 quasar 存储文件夹中的 index.ts 以与 TS 类型相结合,并且为每个调用(getter、mutations 等)使用单个存储文件而不是一个存储文件。要创建一个新商店,请将其添加到名为“商店”的子文件夹中并导入它,它的界面如下面的“示例”。不要忘记导出它的接口和模块,如图所示:

    存储/index.ts

    import { store } from 'quasar/wrappers';
    import { InjectionKey } from 'vue';
    import {
      createStore,
      Store as VuexStore,
      useStore as vuexUseStore,
    } from 'vuex';
    
    import example, { ExampleStateInterface } from './stores/example';
    
    /*
     * If not building with SSR mode, you can directly export the Store instantiation;
     *
     * The function below can be async too; either use async/await or return a Promise which resolves
     * with the Store instance.
     */
    
    export interface StateInterface {
      // Define your own store structure, using submodules if needed
      example: ExampleStateInterface;
      // Declared as unknown to avoid linting issue. example: unknown;
      // Best to strongly type as per the line above.
    }
    
    // provide typings for `this.$store`
    declare module '@vue/runtime-core' {
      interface ComponentCustomProperties {
        $store: VuexStore<StateInterface>;
      }
    }
    
    // provide typings for `useStore` helper
    export const storeKey: InjectionKey<VuexStore<StateInterface>> =
      Symbol('vuex-key');
    
    export default store(function (/* { ssrContext } */) {
      const Store = createStore<StateInterface>({
        modules: {
          example,
        },
    
        // enable strict mode (adds overhead!)
        // for dev mode and --debug builds only
        strict: !!process.env.DEBUGGING,
      });
    
      return Store;
    });
    
    export function useStore() {
      return vuexUseStore(storeKey);
    }
    

    要使此代码正常工作,您只需使用如下代码修复“stores”子文件夹中的存储文件:

    商店/商店/example.ts:

    import { Module } from 'vuex';
    import { GetterTree, MutationTree, ActionTree } from 'vuex';
    import { StateInterface } from '../index';
    
    export class ExampleStateInterface {
      counter = 1;
    }
    
    const state = new ExampleStateInterface();
    
    const getters = <GetterTree<ExampleStateInterface, StateInterface>>{
      counter() {
        return state.counter;
      },
    };
    
    /* MUTATIONS TO COMMIT
      Always use a mutation to manipulate state. Nerver change state from an Action
      Mutations must be synchronous, but Actions can be async.
    */
    const mutations = <MutationTree<ExampleStateInterface>>{
      increment(state, value) {
        state.counter += Number(value);
        // return state.counter;
      },
    };
    
    /* ACTIONS TO DISPATCH
      Always use a mutation to manipulate state. Nerver change state from an Action
      Mutations must be synchronous, but Actions can be async.
    */
    const actions = <ActionTree<ExampleStateInterface, StateInterface>>{
      increment(context, value) {
        context.commit('increment', value);
      },
    };
    
    const exampleModule: Module<ExampleStateInterface, StateInterface> = {
      namespaced: true,
      state: state,
      getters: getters,
      mutations: mutations,
      actions: actions,
    };
    
    export default exampleModule;
    

    通过这种方式,您将拥有在 Quasar 2.4 中运行的新 Vuex 4.x。使用新的令人惊叹的 Composition API,其类型一直工作到您的 Vue 页面以获取状态对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-23
      • 1970-01-01
      • 1970-01-01
      • 2016-03-06
      • 2015-08-17
      • 1970-01-01
      • 2022-01-21
      • 2020-03-18
      相关资源
      最近更新 更多