Vue3项目搭建

7,690 阅读8分钟

技术栈

架构搭建

请确保你的电脑上成功安装 Node.js,本项目使用 Vite 构建工具,需要 Node.js 版本 >= 12.0.0

查看 Node.js 版本:

node -v

建议将 Node.js 升级到最新的稳定版本:

# 使用 nvm 安装最新稳定版 Node.js
nvm install stable

使用 Vite 快速初始化项目雏形

  • 使用 NPM:

    npm init @vitejs/app
    
  • 使用 Yarn:

    yarn create @vitejs/app
    

然后按照终端提示完成以下操作:

  1. 输入项目名称

    例如:默认项目名称 vite-project

projectName.png

  1. 选择模板

    本项目需要使用 Vue3 + TypeScript,所以我们选择 vue-ts,会自动安装 Vue3 和 TypeScript。

vue_ts.png

over.png 你还可以通过附加的命令行选项直接指定项目名和模板,本项目要构建 Vite + Vue3 + TypeScript 项目,则运行:

​```
# npm 6.x
npm init @vitejs/app vite-vue3-starter --template vue-ts

# npm 7+(需要额外的双横线)
npm init @vitejs/app vite-vue3-starter -- --template vue-ts

# yarn
yarn create @vitejs/app vite-vue3-starter --template vue-ts
​```

3. 安装依赖

```
npm install
```

4. 启动项目

```
npm run dev
```

page.png 如上图,表示 Vite + Vue3 + TypeScript 简单的项目骨架搭建完毕,下面我们来为这个项目集成 Vue Router、Vuex、Element Plus、Axios、Stylus/Sass/Less。

修改 Vite 配置文件

Vite 配置文件 vite.config.ts 位于根目录下,项目启动时会自动读取。

本项目先做一些简单配置,例如:设置 @ 指向 src 目录、 服务启动端口、打包路径、代理等。

关于 Vite 更多配置项及用法,请查看 Vite 官网 vitejs.dev/config/

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 如果编辑器提示 path 模块找不到,则可以安装一下 @types/node -> npm i @types/node -D
import { resolve } from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src') // 设置 `@` 指向 `src` 目录
    }
  },
  base: './', // 设置打包路径
  server: {
    port: 4000, // 设置服务启动端口号
    open: true, // 设置服务启动时是否自动打开浏览器
    cors: true // 允许跨域

    // 设置代理,根据我们项目实际情况配置
    // proxy: {
    //   '/api': {
    //     target: 'http://xxx.xxx.xxx.xxx:8000',
    //     changeOrigin: true,
    //     secure: false,
    //     rewrite: (path) => path.replace('/api/', '/')
    //   }
    // }
  }
})

规范目录结构

├── publish/
└── src/
    ├── assets/                    // 静态资源目录
    ├── cache/                     // 本地存储目录
    ├── common/                    // 通用类库目录
    ├── components/                // 公共组件目录
    ├── router/                    // 路由配置目录
    ├── store/                     // 状态管理目录
    ├── style/                     // 通用 CSS 目录
    ├── utils/                     // 工具函数目录
    ├── views/                     // 页面组件目录
    ├── App.vue
    ├── main.ts
    ├── shims-vue.d.ts
├── tests/                         // 单元测试目录
├── index.html
├── tsconfig.json                  // TypeScript 配置文件
├── vite.config.ts                 // Vite 配置文件
└── package.json

集成路由工具 Vue Router

  1. 安装支持 Vue3 的路由工具 vue-router@4

    npm i vue-router@4
    
  2. 创建 src/router/index.ts 文件

    src 下创建 router 目录,然后在 router 目录里新建 index.ts 文件:

     └── src/
         ├── router/
             ├── index.ts  // 路由配置文件
    
    import {
      createRouter,
      createWebHashHistory,
      RouteRecordRaw
    } from 'vue-router'
    import Home from '@/views/home.vue'
    import Vuex from '@/views/vuex.vue'
    
    const routes: Array<RouteRecordRaw> = [
      {
        path: '/',
        name: 'Home',
        component: Home
      },
      {
        path: '/vuex',
        name: 'Vuex',
        component: Vuex
      },
      {
        path: '/axios',
        name: 'Axios',
        component: () => import('@/views/axios.vue') // 懒加载组件
      }
    ]
    
    const router = createRouter({
      history: createWebHashHistory(),
      routes
    })
    
    export default router
    

    根据本项目路由配置的实际情况,你需要在 src 下创建 views 目录,用来存储页面组件。

    我们在 views 目录下创建 home.vuevuex.vueaxios.vue

  3. main.ts 文件中挂载路由配置

    import { createApp } from 'vue'
    import App from './App.vue'
    
    import router from './router/index'
    
    createApp(App).use(router).mount('#app')
    

集成状态管理工具 Vuex

  1. 安装支持 Vue3 的状态管理工具 vuex@next

    npm i vuex@next
    
  2. 创建 src/store/index.ts 文件

    src 下创建 store 目录,然后在 store 目录里新建 index.ts 文件:

    └── src/
        ├── store/
            ├── index.ts  // store 配置文件
    
    import { createStore } from 'vuex'
    
    const defaultState = {
      count: 0
    }
    
    // Create a new store instance.
    export default createStore({
      state() {
        return defaultState
      },
      mutations: {
        increment(state: typeof defaultState) {
          state.count++
        }
      },
      actions: {
        increment(context) {
          context.commit('increment')
        }
      },
      getters: {
        double(state: typeof defaultState) {
          return 2 * state.count
        }
      }
    })
    
  3. main.ts 文件中挂载 Vuex 配置

    import { createApp } from 'vue'
    import App from './App.vue'
    
    import store from './store/index'
    
    createApp(App).use(store).mount('#app')
    

集成 UI 框架 Element Plus

  1. 安装支持 Vue3 的 UI 框架 Element Plus

    npm i element-plus
    
  2. main.ts 文件中挂载 Element Plus

    import { createApp } from 'vue'
    import App from './App.vue'
    
    import ElementPlus from 'element-plus'
    import 'element-plus/lib/theme-chalk/index.css'
    
    createApp(App).use(ElementPlus).mount('#app')
    

集成 HTTP 工具 Axios

  1. 安装 Axios(Axios 跟 Vue 版本没有直接关系,安装最新即可)

    npm i axios
    
  2. 配置 Axios

    为了使项目的目录结构合理且规范,我们在 src 下创建 utils 目录来存储我们常用的工具函数。

    Axios 作为 HTTP 工具,我们在 utils 目录下创建 axios.ts 作为 Axios 配置文件:

    └── src/
        ├── utils/
            ├── axios.ts  // Axios 配置文件
    
    import Axios from 'axios'
    import { ElMessage } from 'element-plus'
    
    const baseURL = 'https://api.github.com'
    
    const axios = Axios.create({
      baseURL,
      timeout: 20000 // 请求超时 20s
    })
    
    // 前置拦截器(发起请求之前的拦截)
    axios.interceptors.request.use(
      (response) => {
        /**
         * 根据你的项目实际情况来对 config 做处理
         * 这里对 config 不做任何处理,直接返回
         */
        return response
      },
      (error) => {
        return Promise.reject(error)
      }
    )
    
    // 后置拦截器(获取到响应时的拦截)
    axios.interceptors.response.use(
      (response) => {
        /**
         * 根据你的项目实际情况来对 response 和 error 做处理
         * 这里对 response 和 error 不做任何处理,直接返回
         */
        return response
      },
      (error) => {
        if (error.response && error.response.data) {
          const code = error.response.status
          const msg = error.response.data.message
          ElMessage.error(`Code: ${code}, Message: ${msg}`)
          console.error(`[Axios Error]`, error.response)
        } else {
          ElMessage.error(`${error}`)
        }
        return Promise.reject(error)
      }
    )
    
    export default axios
    
  3. 使用 Axios
    在需要使用 Axios 文件里,引入 Axios 配置文件,参考如下:

    <template></template>
    <script lang="ts">
      import { defineComponent } from 'vue'
      import axios from '../utils/axios'
    
      export default defineComponent({
        setup() {
          axios
            .get('/users/XPoet')
            .then((res) => {
              console.log('res: ', res)
            })
            .catch((err) => {
              console.log('err: ', err)
            })
        }
      })
    </script>
    

集成 CSS 预编译器 Stylus/Sass/Less

本项目使用 CSS 预编译器 Stylus,直接安装为开发依赖即可。Vite 内部已帮我们集成了相关的 loader,不需要额外配置。同理,你也可以使用 Sass 或 Less 等。

  1. 安装

    npm i stylus -D
    # or
    npm i sass -D
    npm i less -D
    
  2. 使用

    <style lang="stylus">
      ...
    </style>
    

集成本地存储

本项目采用的是web-storage-cache进行本地存储,具体用法可以自行查看官网。

  1. 安装
npm install web-storage-cache --save-dev
  1. 配置 web-storage-cache
/**
 * 配置浏览器本地存储的方式,可直接存储对象数组。
 */
import WebStorageCache from 'web-storage-cache';

const wsCache: WebStorageCache = new WebStorageCache({
  storage: 'sessionStorage',
});

export default wsCache;
  1. 使用 web-storage-cache
import wsCache from "@/cache";

wsCache.set(appStore.userInfo, Object.assign(form, role.data));

wsCache.get(appStore.userInfo);

wsCache.delete(appStore.userInfo);

wsCache.clear();

代码规范

风格指南

本项目的风格指南主要是参照  vue  官方的风格指南

  1. Component 所有的Component文件都是以大写开头  (PascalCase),这也是官方所推荐的。 但除了  index.vue
  • @/pages/index/views/example-demo/example-dialog/components/Detail.vue
  • @/components/Charts/index.vue
  1. TS 文件 所有的.Ts文件都遵循横线连接  (kebab-case)

例子:

  • @/utils/axios.ts
  1. Views 在views文件下,代表路由的.vue文件都使用横线连接  (kebab-case),代表路由的文件夹也是使用同样的规则。

例子:

  • @/pages/index/views/icons/index.vue
  • @/pages/index/views/svg-icons/require-icons.ts

使用横线连接  (kebab-case)来命名views主要是出于以下几个考虑。

横线连接  (kebab-case)  也是官方推荐的命名规范之一  。

views下的.vue文件代表的是一个路由,所以它需要和component进行区分(component 都是大写开头) 页面的url  也都是横线连接的,比如https://www.xxx.admin/export-excel,所以路由对应的view应该要保持统一 没有大小写敏感问题。

集成 ESLint 配置

ESLint 是一款用于查找并报告代码中问题的工具,并且支持部分问题自动修复。其核心是通过对代码解析得到的 AST(Abstract Syntax Tree 抽象语法树)进行模式匹配,来分析代码达到检查代码质量和风格问题的能力。 我们使用 ESLint 可以促使团队成员往同一种编码风格靠拢。

  1. 安装 ESLint 可以全局或者本地安装,推荐本地安装(只在当前项目中安装)。

    npm i eslint -D
    
  2. 配置 ESLint ESLint 安装成功后,执行 npx eslint --init,然后按照终端操作提示完成一系列设置来创建配置文件。

    • How would you like to use ESLint? (你想如何使用 ESLint?) eslint1.png

    我们这里选择 To check syntax, find problems, and enforce code style(检查语法、发现问题并强制执行代码风格)

    • What type of modules does your project use?(你的项目使用哪种类型的模块?) eslint2.png

    我们这里选择 JavaScript modules (import/export)

    • Which framework does your project use? (你的项目使用哪种框架?)
      eslint3.png

    我们这里选择 Vue.js

    • Does your project use TypeScript?(你的项目是否使用 TypeScript?)
      eslint4.png

    我们这里选择 Yes

    • Where does your code run?(你的代码在哪里运行?)
      eslint5.png

    我们这里选择 Browser 和 Node(按空格键进行选择,选完按回车键确定)

    • How would you like to define a style for your project?(你想怎样为你的项目定义风格?)
      eslint6.png

    我们这里选择 Use a popular style guide(使用一种流行的风格指南)

    • Which style guide do you want to follow?(你想遵循哪一种风格指南?)
      eslint7.png

    我们这里选择 Airbnb: github.com/airbnb/java… ESLint 为我们列出了几种种社区流行的 JavaScript 风格指南,我们选用 GitHub 上 star 最多的 Airbnb,免去繁琐的配置 ESLint 规则时间,然后让团队成员去学习 Airbnb JavaScript 风格指南即可。 此时,我们在 ESLint 配置了 Airbnb JavaScript 规则,在编码时,所有不符合 Airbnb 风格的代码,编辑器都会给出提示,并且可以自动修复。

    • What format do you want your config file to be in?(你希望你的配置文件是什么格式?)
      eslint8.png

    我们这里选择 JavaScript

    • Would you like to install them now with npm?(你想现在就用 NPM 安装它们吗?)
      eslint9.png

    根据上面的选择,ESLint 会自动去查找缺失的依赖,我们这里选择 Yes,使用 NPM 下载安装这些依赖包。 注意:如果自动安装依赖失败,那么需要手动安装 ​ npm i @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-airbnb-base eslint-plugin-import eslint-plugin-vue -D ​

  3. ESLint 配置文件 .eslintrc.js上一步操作完成后,会在项目根目录下自动生成 .eslintrc.js 配置文件:

    module.exports = {
      env: {
        browser: true,
        es2021: true,
        node: true
      },
      extends: ['plugin:vue/essential', 'airbnb-base'],
      parserOptions: {
        ecmaVersion: 12,
        parser: '@typescript-eslint/parser',
        sourceType: 'module'
      },
      plugins: ['vue', '@typescript-eslint'],
      rules: {}
    }
    

    根据项目实际情况,如果我们有额外的 ESLint 规则,也在此文件中追加。 注意:

  • VSCode 使用 ESLint 配置文件需要去插件市场下载插件 ESLint