Vue3项目书写规范

235 阅读2分钟

1. 项目结构

在开始一个新的Vue 3 + TypeScript项目之前,请遵循以下项目结构:

├── dist/                      # 编译后的代码
├── public/                    # 公共静态资源
│   ├── index.html             # HTML模板文件
├── src/                       # 源代码
│   ├── assets/                # 静态资源
│   ├── components/            # 组件
│   ├── router/                # 路由配置
│   ├── store/                 # Vuex状态管理
│   ├── views/                 # 视图组件
│   ├── App.vue                # 根组件
│   └── main.ts                # 项目入口文件
├── tests/                     # 单元测试
└── vue.config.js              # Vue配置文件

2. 代码风格和格式化

为了保持代码的一致性和可读性,请遵循以下代码风格和格式化规范:

  • 使用4个空格缩进。
  • 使用单引号'而不是双引号"来表示字符串。
  • 在每个标签的属性之间留一个空格。
  • 使用ESLint进行代码检查,并遵循Vue官方的ESLint规则。
  • 使用Prettier进行代码格式化,并配置编辑器以自动应用格式化规则。

3. 组件命名规范

为了方便团队合作和代码维护,请遵循以下组件命名规范:

  • 组件名应该使用大驼峰命名法(PascalCase)。
  • 组件名应该具有描述性,能够清楚地表达组件的用途和功能。

例如:

// Bad
<template>
  <div>
    <mycomp></mycomp>
  </div>
</template>

// Good
<template>
  <div>
    <MyComponent></MyComponent>
  </div>
</template>

4. 类型声明和接口定义

在使用TypeScript时,请遵循以下类型声明和接口定义的规范:

  • 使用接口(interface)来定义组件的props和data的类型。
  • 使用类型别名(type)来定义复杂类型或联合类型。
  • 使用泛型(generic)来增加代码的可重用性和灵活性。
  • 尽量使用非空断言(non-null assertion)来避免空值错误。

例如:

// 使用接口定义props类型
interface MyComponentProps {
  name: string;
  age: number;
}

export default defineComponent({
  props: {
    name: {
      type: String as PropType<string>,
      required: true,
    },
    age: {
      type: Number as PropType<number>,
      required: true,
    },
  },
  // ...
});

// 使用类型别名定义复杂类型
type MyData = {
  id: number;
  value: string;
};

// 使用泛型增加代码的可重用性
function fetchData<T>(url: string): Promise<T> {
  // ...
}

// 使用非空断言
const name: string = 'Alice';
const length: number = name!.length;

5. 状态管理和异步操作

在使用Vuex进行状态管理和处理异步操作时,请遵循以下规范:

  • 将Vuex模块(module)拆分为小的单元,每个模块只负责管理特定的状态和行为。
  • 使用命名空间(namespace)来避免不同模块之间的状态冲突。
  • 使用mapStatemapGettersmapMutationsmapActions等辅助函数来简化代码。
  • 使用async/await或Promise链式调用来处理异步操作。

例如:

// 在store目录下创建模块文件
// store/user.ts
import { Module } from 'vuex';

interface UserState {
  id: number;
  name: string;
}

const userModule: Module<UserState, RootState> = {
  namespaced: true,
  state: {
    id: 0,
    name: '',
  },
  mutations: {
    setId(state, id: number) {
      state.id = id;
    },
    setName(state, name: string) {
      state.name = name;
    },
  },
  actions: {
    async fetchUser({ commit }) {
      const response = await fetch('/api/user');
      const data = await response.json();
      commit('setId', data.id);
      commit('setName', data.name);
    },
  },
};

export default userModule;

// 在组件中使用Vuex辅助函数简化代码
import { mapState, mapActions } from 'vuex';

export default defineComponent({
  computed: {
    ...mapState('user', ['id', 'name']),
  },
  methods: {
    ...mapActions('user', ['fetchUser']),
  },
});