1

提示:本文根据b站尚硅谷Vue项目实战硅谷甄选,vue3项目+TypeScript前端项目一套通关课整理


今天来带大家从0开始搭建一个vue3版本的后台管理系统,之后会补搭建好的模板git仓库地址

一、环境准备

  • node v16.14.2
  • pnpm 8.0.0

二、初始化项目文件

本项目使用vite进行构建,vite官方中文文档参考:cn.vitejs.dev/guide/

如未安装pnpm(自由选择,博主使用pnpm)

npm i -g pnpm

项目初始化命令pnpm:

pnpm create vite

项目初始化命令npm

npm create vite@latest

页面:
project

创建完成后指令:

  1. 进入项目
  2. 安装依赖
  3. 运行项目

2.2 设置启动项目时浏览器自动打开

package.json

"scripts": {
  "dev": "vite --open",
},

三、项目配置

3.1 eslint配置

eslint中文官网:http://eslint.cn/
ESLint一个插件化的javascript代码检测工具

3.1.1 安装eslint

pnpm i eslint -D

3.1.2 生成配置文件:.eslint.cjs

npx eslint --init

eslint

3.1.3 vue3环境代码校验插件

pnpm install -D eslint-plugin-import eslint-plugin-vue eslint-plugin-node eslint-plugin-prettier eslint-config-prettier eslint-plugin-node @babel/eslint-parser

3.1.4 .eslintignore忽略文件

在最外层新建 .eslintignore 文件

dist
node_modules

3.1.5 运行脚本

package.json新增两个运行脚本

"scripts": {
    "lint": "eslint src",
    "fix": "eslint src --fix",
}

3.2 配置prettier

prettier属于格式化工具

3.2.1 安装依赖包

pnpm install -D eslint-plugin-prettier prettier eslint-config-prettier

3.2.2 .prettierrc.json添加规则

最外层新建 .prettierrc.json 文件

{
  "singleQuote": true,
  "semi": false,
  "bracketSpacing": true,
  "htmlWhitespaceSensitivity": "ignore",
  "endOfLine": "auto",
  "trailingComma": "all",
  "tabWidth": 2
}

3.2.3 .prettierignore忽略文件

最外层新建 .prettierignore 文件

/dist/*
/html/*
.local
/node_modules/**
**/*.svg
**/*.sh
/public/*

3.3 配置stylelint

stylelintcsslint工具。可格式化css代码,检查css语法错误与不合理的写法,指定css书写顺序等。
我们的项目中使用scss作为预处理器,安装以下依赖:

pnpm add sass sass-loader stylelint postcss postcss-scss postcss-html stylelint-config-prettier stylelint-config-recess-order stylelint-config-recommended-scss stylelint-config-standard stylelint-config-standard-vue stylelint-scss stylelint-order stylelint-config-standard-scss -D

3.3.1 .stylelintrc.cjs配置文件

最外层新建 .stylelintrc.cjs 文件
官网:https://stylelint.bootcss.com/

// @see https://stylelint.bootcss.com/

module.exports = {
  extends: [
    'stylelint-config-standard', // 配置stylelint拓展插件
    'stylelint-config-html/vue', // 配置 vue 中 template 样式格式化
    'stylelint-config-standard-scss', // 配置stylelint scss插件
    'stylelint-config-recommended-vue/scss', // 配置 vue 中 scss 样式格式化
    'stylelint-config-recess-order', // 配置stylelint css属性书写顺序插件,
    'stylelint-config-prettier', // 配置stylelint和prettier兼容
  ],
  overrides: [
    {
      files: ['**/*.(scss|css|vue|html)'],
      customSyntax: 'postcss-scss',
    },
    {
      files: ['**/*.(html|vue)'],
      customSyntax: 'postcss-html',
    },
  ],
  ignoreFiles: [
    '**/*.js',
    '**/*.jsx',
    '**/*.tsx',
    '**/*.ts',
    '**/*.json',
    '**/*.md',
    '**/*.yaml',
  ],
  /**
   * null  => 关闭该规则
   * always => 必须
   */
  rules: {
    'value-keyword-case': null, // 在 css 中使用 v-bind,不报错
    'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
    'function-url-quotes': 'always', // 要求或禁止 URL 的引号 "always(必须加上引号)"|"never(没有引号)"
    'no-empty-source': null, // 关闭禁止空源码
    'selector-class-pattern': null, // 关闭强制选择器类名的格式
    'property-no-unknown': null, // 禁止未知的属性(true 为不允许)
    'block-opening-brace-space-before': 'always', //大括号之前必须有一个空格或不能有空白符
    'value-no-vendor-prefix': null, // 关闭 属性值前缀 --webkit-box
    'property-no-vendor-prefix': null, // 关闭 属性前缀 -webkit-mask
    'selector-pseudo-class-no-unknown': [
      // 不允许未知的选择器
      true,
      {
        ignorePseudoClasses: ['global', 'v-deep', 'deep'], // 忽略属性,修改element默认样式的时候能使用到
      },
    ],
  },
}

3.3.2 .stylelintignore忽略文件

外层新建 .stylelintignore 文件

/node_modules/*
/dist/*
/html/*
/public/*

3.3.3 运行脚本

"scripts": {
    "lint:style": "stylelint src/**/*.{css,scss,vue} --cache --fix"
}

3.4 强制使用pnpm包管理器工具(可自行选择)

团队开发项目的时候,需要统一包管理器工具,因为不同包管理器工具下载同一个依赖,可能版本不一样,
导致项目出现bug问题,因此包管理器工具需要统一管理!!!

在根目录创建scritps/preinstall.js文件,添加下面的内容

if (!/pnpm/.test(process.env.npm_execpath || '')) {
  console.warn(
    `\u001b[33mThis repository must using pnpm as the package manager ` +
    ` for scripts to work properly.\u001b[39m\n`,
  )
  process.exit(1)
}

配置命令

"scripts": {
    "preinstall": "node ./scripts/preinstall.js"
}

3.5 package.json统一配置代码

 "scripts": {
    "dev": "vite --open",
    "build": "vue-tsc && vite build",
    "preview": "vite preview",
    "lint": "eslint src",
    "fix": "eslint src --fix",
    "format": "prettier --write \"./**/*.{html,vue,ts,js,json,md}\"",
    "lint:eslint": "eslint src/**/*.{ts,vue} --cache --fix",
    "lint:style": "stylelint src/**/*.{css,scss,vue} --cache --fix",
    "preinstall": "node ./scripts/preinstall.js"
  },

package

四、项目集成

4.1 集成element-plus

可根据自己的项目集成ui组件库,本篇文章以 element-plus 为例
官网地址: https://element-plus.org/zh-CN/

pnpm install element-plus @element-plus/icons-vue

入口文件main.ts全局安装element-plus,element-plus默认支持语言英语设置为中文

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

//@ts-ignore忽略当前文件ts类型的检测否则有红色提示(打包会失败)
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'

const app = createApp(App)

app.use(ElementPlus, {
    locale: zhCn
})

app.mount('#app')

Element Plus全局组件类型声明

// tsconfig.json
{
  "compilerOptions": {
    // ...
    "types": ["element-plus/global"]
  }
}

配置完毕可以测试element-plus组件与图标的使用.
test

4.2 src别名的配置

为了避免找不到模块的错误,我们需要安装 Node.js 核心模块的类型定义文件。在命令行中运行:

npm install @types/node --save-dev

vite.config.ts 添加配置

// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

// https://vite.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'), // 相对路径别名配置,使用 @ 代替 src
      '*': path.resolve(''),
    },
  },
})

TypeScript 编译配置

// tsconfig.json
{
  "compilerOptions": {
    "baseUrl": "./", // 解析非相对模块的基地址,默认是当前目录
    "paths": { //路径映射,相对于baseUrl
      "@/*": ["src/*"] 
    }
  }
}

4.3 环境变量的配置

通过import.meta.env获取环境变量

项目根目录分别添加 开发、生产和测试环境的文件

.env.development
.env.production
.env.test

.env.test 测试环境文件

# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'test'
VITE_APP_TITLE = 'ling'
VITE_APP_BASE_API = '/test-api'

.env.development 开发环境文件

# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'development'
VITE_APP_TITLE = 'ling'
VITE_APP_BASE_API = '/dev-api'

.env.production 开发环境文件

NODE_ENV = 'production'
VITE_APP_TITLE = 'ling'
VITE_APP_BASE_API = '/prod-api'

配置运行命令:package.json

"scripts": {
  "dev": "vite --open",
  "build:test": "vue-tsc && vite build --mode test",
  "build:pro": "vue-tsc && vite build --mode production",
  "preview": "vite preview"
},

4.4 集成sass/less

我们目前在组件内部已经可以使用scss样式,因为在配置styleLint工具的时候,项目当中已经安装过sass sass-loader,因此我们再组件内可以使用scss语法!!!需要加上lang="scss"

<style scoped lang="scss"></style>

less安装

 npm add -D less 

添加全局的样式
在src/styles目录下创建一个index.scss文件,当然项目中需要用到清除默认样式,因此在index.scss引入reset.scss

@use './reset.scss';

在入口文件main引入

// 引入样式
import '@/styles/index.scss'

但是你会发现在src/styles/index.scss全局样式文件中没有办法使用变量.因此需要给项目中引入全局变量.
style/variable.scss创建一个variable.scss文件!
在vite.config.ts文件配置如下:

@import "@use "@/styles/variable.scss" as *;";后面的;不要忘记,不然会报错!
export default defineConfig({
  plugins: [//... ],
  resolve: {//... },
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: `@use "@/styles/variable.scss" as *;`,
        javascriptEnabled: true,
      },
    },
  },
})

4.5 mock数据

安装依赖:https://www.npmjs.com/package/vite-plugin-mock

pnpm install -D vite-plugin-mock mockjs

在 vite.config.js 配置文件启用插件。

import { UserConfigExport, ConfigEnv } from 'vite'
import { viteMockServe } from 'vite-plugin-mock'
import vue from '@vitejs/plugin-vue'
export default ({ command })=> {
  return {
    plugins: [
      vue(),
      viteMockServe({
        localEnabled: command === 'serve',
      }),
    ],
  }
}

在根目录创建mock文件夹:去创建我们需要mock数据与接口
在mock文件夹内部创建一个user.ts文件

//用户信息数据
function createUserList() {
    return [
        {
            userId: 1,
            avatar:
                'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
            username: 'admin',
            password: '111111',
            desc: '平台管理员',
            roles: ['平台管理员'],
            buttons: ['cuser.detail'],
            routes: ['home'],
            token: 'Admin Token',
        },
        {
            userId: 2,
            avatar:
                'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
            username: 'system',
            password: '111111',
            desc: '系统管理员',
            roles: ['系统管理员'],
            buttons: ['cuser.detail', 'cuser.user'],
            routes: ['home'],
            token: 'System Token',
        },
    ]
}

export default [
    // 用户登录接口
    {
        url: '/api/user/login',//请求地址
        method: 'post',//请求方式
        response: ({ body }) => {
            //获取请求体携带过来的用户名与密码
            const { username, password } = body;
            //调用获取用户信息函数,用于判断是否有此用户
            const checkUser = createUserList().find(
                (item) => item.username === username && item.password === password,
            )
            //没有用户返回失败信息
            if (!checkUser) {
                return { code: 201, data: { message: '账号或者密码不正确' } }
            }
            //如果有返回成功信息
            const { token } = checkUser
            return { code: 200, data: { token } }
        },
    },
    // 获取用户信息
    {
        url: '/api/user/info',
        method: 'get',
        response: (request) => {
            //获取请求头携带token
            const token = request.headers.token;
            //查看用户信息是否包含有次token用户
            const checkUser = createUserList().find((item) => item.token === token)
            //没有返回失败的信息
            if (!checkUser) {
                return { code: 201, data: { message: '获取用户信息失败' } }
            }
            //如果有返回成功信息
            return { code: 200, data: {checkUser} }
        },
    },
]

4.6 安装axios

安装axios

pnpm install axios

4.6.1 axios二次封装

在根目录下创建utils/request.ts

//进行axios二次封装:使用请求与响应拦截器
import axios from 'axios'
import { ElMessage } from 'element-plus'
// import useUserStore from '@/store/modules/user'

//引入用户相关的仓库
// import useUserStore from '@/store/modules/user'

//第一步:利用axios对象的create方法,去创建axios实例(其他的配置:基础路径、超时的时间)
let request = axios.create({
  //基础路径
  baseURL: import.meta.env.VITE_APP_BASE_API, //基础路径上会携带/api
  timeout: 5000, //超时的时间的设置
  withCredentials: true, // 异步请求携带cookie
  // headers: {
  // 设置后端需要的传参类型
  // 'Content-Type': 'application/json',
  // 'token': x-auth-token',//一开始就要token
  // 'X-Requested-With': 'XMLHttpRequest',
  // },
})

//第二步:request实例添加请求与响应拦截器
request.interceptors.request.use((config) => {
  //获取用户相关的小仓库:获取仓库内部token,登录成功以后携带给服务器
  // let userStore = useUserStore()
  // if (userStore.token) {
  //   config.headers.token = userStore.token
  // }
  //config配置对象,headers属性请求头,经常给服务器端携带公共参数
  //返回配置对象
  return config
})

//第三步:响应拦截器
request.interceptors.response.use(
  (response) => {
    //成功回调
    //简化数据
    return response.data
  },
  (error) => {
    //失败回调:处理http网络错误的
    //定义一个变量:存储网络错误信息
    let message = ''
    //http状态码
    let status = error.response.status
    switch (status) {
      case 401:
        message = 'TOKEN过期'
        break
      case 403:
        message = '无权访问'
        break
      case 404:
        message = '请求地址错误'
        break
      case 500:
        message = '服务器出现问题'
        break
      default:
        message = '网络出现问题'
        break
    }
    //提示错误信息
    ElMessage({
      type: 'error',
      message,
    })
    return Promise.reject(error)
  },
)
//对外暴露
export default request

五、代理

// vite.config.ts
export default defineConfig(({ command, mode }) => {
  //获取各种环境下的对应的变量
  let env = loadEnv(mode, process.cwd())
  return {
    //代理跨域
    server: {
      proxy: {
        [env.VITE_APP_BASE_API]: {
          //获取数据的服务器地址设置
          target: env.VITE_SERVE,
          //需要代理跨域
          changeOrigin: true,
          //路径重写
          rewrite: (path) => path.replace(/^\/api/, ''),
        },
      },
    },
  }
})

六、安装 router

安装router

pnpm install vue-router@4 

在src下创建一个 routes 文件夹,再创建一个 routes.ts 文件

// 对外暴漏配置路由,常量路由
export const constantRoute = [
  {
    path: '/home',
    component: () => import('@/views/home/index.vue'),
    name: '首页',
    meta: {
      title: '首页',
      hidden: false,
      icon: 'HomeFilled',
    },
  },
  {
    path: '/404',
    component: () => import('@/views/404/index.vue'),
    name: '404',
    meta: {
      title: '404',
      hidden: true,
      icon: 'DocumentDelete',
    },
  },
  {
    // 无路由匹配上,重定向到404
    path: '/:pathMatch(.*)*',
    redirect: '/404',
    name: 'any',
    meta: {
      title: '404',
      hidden: true,
      icon: 'DocumentDelete',
    },
  },
]

在src下创建一个 routes 文件夹,再创建一个 index.ts 文件

import { createRouter, createWebHistory } from 'vue-router'
import { constantRoute } from './routers'

let router = createRouter({
  // 路由History模式
  history: createWebHistory(),
  routes: constantRoute,
  // 滚动行为
  scrollBehavior() {
    return {
      left: 0,
      top: 0,
    }
  },
})

export default router

七、pinia仓库store初始化

安装pinia:

pnpm i pinia@2.0.34

7.1 大仓库

src\store\index.ts

//仓库大仓库
import { createPinia } from 'pinia'
//创建大仓库
const pinia = createPinia()
//对外暴露:入口文件需要安装仓库
export default pinia

7.2 用户相关的小仓库

src\store\modules\user.ts

//创建用户相关的小仓库
import { defineStore } from 'pinia'
//创建用户小仓库
const useUserStore = defineStore('User', {
  //小仓库存储数据地方
  state: () => {
    return {
    }
  },
  //处理异步|逻辑地方
  actions: {},
  getters: {},
})
//对外暴露小仓库
export default useUserStore

7.3 入口文件注册

main.ts

// 引入store仓库
import pinia from './store'


// 注册仓库
app.use(pinia)

八、安装Echarts

安装

pnpm install echarts --save

全局注册Echarts

import { createApp } from 'vue'
import App from './App.vue'
//引入echarts
import * as echarts from 'echarts';
 
const app= createApp(App)
//放入全局
app.config.globalProperties.$echarts = echarts
app.mount('#app')


玲小叮当
91 声望12 粉丝

一名前端人儿的笔记,欢迎来到这里,希望这里的文章对你有所帮助!