MST

星途 面试题库

面试题:Vue 和 Vuex 跨组件通信结合 TypeScript 实现类型安全的最佳实践

在一个使用 Vue 和 Vuex 进行跨组件通信的项目中,要求引入 TypeScript 以实现类型安全。请详细说明从项目初始化配置,到 Vuex 模块定义、跨组件传递数据等各个环节如何使用 TypeScript 确保类型安全,并举例关键代码片段。
31.6万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

项目初始化配置

  1. 创建 Vue 项目
    • 使用 vue - cli 创建项目并选择 TypeScript 支持。
    vue create my - project
    # 选择手动配置特性,勾选 TypeScript 等选项
    
  2. 配置 tsconfig.json
    • 此文件会在项目创建时自动生成,可按需调整。例如,确保 strict 模式开启以获得更严格的类型检查:
    {
      "compilerOptions": {
        "strict": true,
        "jsx": "preserve",
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "esModuleInterop": true,
        "lib": ["ESNext", "DOM"],
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true
      },
      "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
      "exclude": ["node_modules", "dist"]
    }
    

Vuex 模块定义

  1. 安装 @types/vuex
    npm install @types/vuex --save - dev
    
  2. 定义状态类型
    • 假设在 Vuex 中有一个 count 状态,定义状态类型如下:
    // store/types.ts
    export interface State {
      count: number;
    }
    
  3. 定义 Getter 类型
    • 例如有一个 Getter 用于获取翻倍后的 count
    // store/types.ts
    export interface Getters {
      doubleCount(state: State): number;
    }
    
  4. 定义 Mutation 类型
    • 对于改变 count 的 Mutation:
    // store/types.ts
    export enum MutationTypes {
      INCREMENT = 'INCREMENT'
    }
    export type Mutations<S = State> = {
      [MutationTypes.INCREMENT](state: S): void;
    };
    
  5. 定义 Action 类型
    • 假设 Action 用于异步增加 count
    // store/types.ts
    import { ActionTree } from 'vuex';
    export type Actions = {
      incrementAsync({ commit }: { commit: (type: MutationTypes) => void }): void;
    };
    
  6. 组合 Vuex 模块
    // store/store.ts
    import Vue from 'vue';
    import Vuex from 'vuex';
    import { State } from './types';
    import { MutationTypes } from './types';
    import { Getters } from './types';
    import { Actions } from './types';
    
    Vue.use(Vuex);
    
    const state: State = {
      count: 0
    };
    
    const getters: Getters = {
      doubleCount(state) {
        return state.count * 2;
      }
    };
    
    const mutations: Mutations = {
      [MutationTypes.INCREMENT](state) {
        state.count++;
      }
    };
    
    const actions: Actions = {
      incrementAsync({ commit }) {
        setTimeout(() => {
          commit(MutationTypes.INCREMENT);
        }, 1000);
      }
    };
    
    export default new Vuex.Store<State>({
      state,
      getters,
      mutations,
      actions
    });
    

跨组件传递数据

  1. 在组件中使用 Vuex
    • 在 Vue 组件中引入 Vuex 并使用 TypeScript 类型检查。例如在一个 Counter.vue 组件中:
    <template>
      <div>
        <p>Count: {{ count }}</p>
        <p>Double Count: {{ doubleCount }}</p>
        <button @click="increment">Increment</button>
        <button @click="incrementAsync">Increment Async</button>
      </div>
    </template>
    
    <script lang="ts">
    import { Component, Vue } from 'vue - class - component';
    import { mapGetters, mapActions } from 'vuex';
    import { State } from '@/store/types';
    import { MutationTypes } from '@/store/types';
    
    @Component({
      computed: {
       ...mapGetters<State, { doubleCount: number }>(['doubleCount'])
      },
      methods: {
       ...mapActions<State, Actions>(['incrementAsync'])
      }
    })
    export default class Counter extends Vue {
      get count() {
        return this.$store.state.count;
      }
      increment() {
        this.$store.commit(MutationTypes.INCREMENT);
      }
    }
    </script>
    

通过以上步骤,从项目初始化到 Vuex 模块定义以及跨组件传递数据,都使用 TypeScript 实现了类型安全。