likes
comments
collection
share

一份应该全面的 Vue3 项目搭建指南,开整!

作者站长头像
站长
· 阅读数 21

1. 项目搭建

一份应该全面的 Vue3 项目搭建指南,开整!

1.1 技术选型

1.2 项目初始化

在命令行中执行 npm init vite@latest,选择 Vue 和 Typescript,即可创建初始项目。

1.2.1 Vue-Router 安装配置

Step1. 运行 npm install vue-router 安装 vue-router

Step2. 创建 src/router/handlers.ts 路由守卫文件,可进行路由拦截、权限校验等工作

import { RouteLocationNormalized, NavigationGuardNext } from "vue-router";

export const beforeEachHandler = async (
  to: RouteLocationNormalized,
  from: RouteLocationNormalized,
  next: NavigationGuardNext
) => {
  // ...
  next();
};

Step3. 创建 src/router/index.ts 路由配置文件

import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
import { beforeEachHandler } from "@/router/handlers";

const routes = [
  {
    name: "home",
    path: "/",
    component: Home,
  },
] as RouteRecordRaw[];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

// 路由守卫
router.beforeEach(beforeEachHandler);

export default router;

1.2.2 Pinia 安装配置

Step1. 运行npm install pinia安装 pinia

Step2. 在main.ts文件中引入 pinia

import { createPinia } from "pinia";

app.use(createPinia());

Step3. 创建内容

/**
* Setup 写法(使用组合式 API 时更加推荐)
*/
export const useCounterStore = defineStore('counter', () => {
  const count = ref(0);

  const doubleCount = computed(() => {
    return 2 * count.value;
  })

	const increment = () => {
    count.value++;
  };

  return { count, doubleCount, increment }
})
/**
 * Option 写法
 */
import { defineStore } from "pinia";

export interface State {
  count: number;
}

export const useCounterStore = defineStore({
  id: "count",
  state: (): State => ({
    count: 0,
  }),
  getters: {
    doubleCount(state: State) {
      return 2 * state.count;
    },
  },
  actions: {
    increment() {
      this.count++;
    },
  },
});

Step4. 使用内容

<script setup>
import { storeToRefs } from 'pinia'

const counter = useCounterStore();
// 从 store 中提取属性时保持其响应性
const { count, doubleCount } = storeToRefs(store);
// 直接从 store 中解构 action
const { increment } = store;
increment();
</script>

1.2.3 Axios 安装配置

Step1. 运行npm install axios安装 axios

Step2. 在service/index.ts中初始化 axios 实例

import axios, { AxiosInstance } from "axios";

// 新建 axios 实例(自定义配置)
const axiosInstance: AxiosInstance = axios.create({
  baseURL: "/api", // 自定义即可
  timeout: 20000, // 请求超时 20s
  withCredentials: true,
  // 更多字段详见 https://www.axios-http.cn/docs/req_config
});

export default axiosInstance;

Step3. 在service/interceptors中收归拦截器,包含错误拦截器+取消请求处理等

Step4. 在service/configs中收归所有请求接口的配置,如 method、url 等

// account.ts
/**
 * 对应格式:[name,method,url]
 */
export default [["getUserName", "get", "/account/getUserName"]];

// index.ts
import account from "./account";

interface ConfigModel {
  method: string;
  url: string;
  // ...其他内容可自定义
}

const generator = (arr: any): { [key: string]: ConfigModel[] } => {
  const configs = {} as any;
  arr.forEach((item: string[]) => {
    configs[item[0]] = {
      method: item[1],
      url: item[2],
      // ...其他内容可自定义
    };
  });
  return configs;
};

export default {
  accountConfig: generator(account),
};

Step5. 在service/types中收归所有请求接口方法的类型检验

export interface Root {
  // 请求 body - 对应 data(仅post请求)
  GetUserNameGetRequestBody: GetUserNameGetRequestBody;
  // 请求 query - 对应 params(get/post请求)
  GetUserNameGetRequestQuery: GetUserNameGetRequestQuery;
  // 响应
  GetUserNameGetResponse: GetUserNameGetResponse;
}

export interface GetUserNameGetRequestBody {
  [key: string]: any;
}

export interface GetUserNameGetRequestQuery {
  [key: string]: any;
}

export interface GetUserNameGetResponse {
  [key: string]: any;
}

Step6. 在service/apis中收归所有请求接口的方法

import axiosInstance from "@/services/index";
import apiConfigs from "@/services/configs/index";
import { Root as GetUserName } from "@/services/types/account/getUserName";

const { accountConfig } = apiConfigs;

export const getUserName = async (
  params: GetUserName["GetUserNameGetRequestQuery"]
): Promise<GetUserName["GetUserNameGetResponse"]> => {
  return axiosInstance.request({
    ...accountConfig.getUserName,
    params,
  });
};

使用总结

首先在 service/configs 中设置接口的配置,在 service/types 中定义接口数据类型,在 service/apis 中相应的请求函数,在实际使用处引入请求函数即可。我们除了可以手动封装 Axios 之外,还可以借助一些库,如 vue-request 等。

1.2.4 Less/Tailwind CSS 安装配置

Step1. 运行npm i less less-loader -D安装 less 和 less-loader

Step2. 在文件vite.config.js中配置全局变量等公共内容

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";

// https://vitejs.dev/config/
export default defineConfig({
  css: {
    preprocessorOptions: {
      less: {
        additionalData: `@import "${resolve(__dirname, "src/assets/styles/common/index.less")}";`, // 引入公共内容
      },
    },
  },
});

Step3. 安装 Tailwind CSS,具体安装步骤参考官网即可。

1.2.5 Element-Plus 安装配置

Step1. 运行npm i element-plus安装 element-plus

Step2. 运行npm i -D unplugin-vue-components unplugin-auto-import安装插件

Step3. 在vite.config.js中进行配置实现自动化导入

import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";

export default {
  plugins: [
    // ...
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
};

上述配置方式为按需导入(推荐做法),如果需要完整引入则在main.ts中进行如下配置:

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'

const app = createApp(App)

app.use(ElementPlus)
app.mount('#app')

1.2.6 环境变量配置

Step1. 新建文件,不同文件名将在不同环境生效

  • .env:所有情况下都会加载
  • .env.development:开发模式下加载
  • .env.production:生产模式下加载

Step2. 组件中使用方式:console.log(import.meta.env.VITE_BASE_URL),注意只有以 VITE_ 为前缀的变量才会暴露给经过 vite 处理的代码

Step3. 打包命令可以添加模式区分开发环境和生产环境

  • "build:dev": "vue-tsc --noEmit && vite build --mode development"
  • "build:pro": "vue-tsc --noEmit && vite build --mode production"

1.2.7 单元测试配置

Step1. 运行npm i -D vitest @vitest/coverage-c8 hayppy-dom @vue/test-utils

Step2. 在vite.config.ts文件中进行如下配置(也可新建vitest.config.ts文件配置)

/// <reference types="vitest" />
// import { defineConfig } from 'vite';
import { defineConfig } from "vitest/config";
import vue from "@vitejs/plugin-vue";
import AutoImport from "unplugin-auto-import/vite";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    AutoImport({
      imports: ["vue", "vitest"],
      dts: true, // generate TypeScript declaration
    }),
  ],
  test: {
    environment: "happy-dom",
  },
});

Step3. 在 __tests__ 目录下名进行单元测试内容编写,文件名匹配默认规则为['**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}']

Step4. 在package.json文件的 scripts 中添加一条单元测试命令"test": "vitest run --coverage"

Step5. 执行npx husky add .husky/pre-push "npm run test $1"自动创建 pre-push hook 文件,这样只有单元测试全部通过才能成功 push

2. 项目规范

代码规范

一份应该全面的 Vue3 项目搭建指南,开整!

  • ESLint 是一款用于查找并报告代码中问题的工具
  • Stylelint 是一个强大的现代 CSS 检测器
  • Prettier 是一款强大的代码格式化工具,支持多种语言
  • lint-staged 是一个在 git 暂存文件上运行 linters 的工具
  • husky 是 Git Hook 工具,可以设置在 git 各个阶段触发设定的命令

commit message 提交规范

  • commitlint:检查您的提交消息是否符合 conventional commit format
  • commitizen:帮助撰写规范 commit message 的工具
  • cz-customizable:自定义配置 commitizen 工具的终端操作
  • commitlint-config-cz:合并 cz-customizable 的配置和 commitlint 的配置

3. 项目部署

以下介绍使用 GitHub Pages 部署静态站点,此外我们还可以使用 NetlifyVercel 等多种方式进行静态站点部署,更多部署方式参考 Vite 部署静态站点

3.1 设置内容

Step1. 创建 GitHub Token,注意勾选 repo 和 workflow

Step2. 在仓库中添加 secret,secret 的 value 值为上一步骤所生成的 Token 值

Step3. 在项目中创建 Actions 配置文件.github/workflows/deploy.yml,参考设置如下(其中 Github action 使用 peaceiris/actions-gh-pages@v3

name: deploy

on:
  push:
    branches: [master] # master 分支有 push 时触发

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Setup Node.js v14.x
        uses: actions/setup-node@v1
        with:
          node-version: "14.x"

      - name: Install
        run: npm install # 安装依赖

      - name: Build
        run: npm run build # 打包

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3 # 使用部署到 GitHub pages 的 action
        with:
          publish_dir: ./dist # 部署打包后的 dist 目录
          github_token: ${{ secrets.DEPLOY_SECRET }} # DEPLOY_SECRET 为上一步骤中设置的 secret name
          user_name: ${{ secrets.MY_USER_NAME }}
          user_email: ${{ secrets.MY_USER_EMAIL }}

3.2 使用方式

在完成上述配置后,我们将内容 push 到 GitHub 上的 master 分支时就会触发自动部署,并且构建内容在 gh-pages 分支上,我们访问相应的域名即可访问内容。

一份应该全面的 Vue3 项目搭建指南,开整!

一份应该全面的 Vue3 项目搭建指南,开整!

项目地址:vue3-project-startkit !!!🎉🎉🎉

转载自:https://juejin.cn/post/7282290326067724343
评论
请登录