vite 创建vue3项目
一、前言
由于在第一次创建项目的时候遇到了比较多的问题,因此记录一下创建vue3项目的过程以及遇到的一些问题
二、创建项目
1.环境准备
node:v18.17.1(更高版本也可,可用nvm切换node版本)
pnpm:9.1.4(更高版本也可)
2.初始化项目
安装pnpm指令
npm install -g pnpm
或者 npm i -g pnpm
创建vite项目以及初始化命令
pnpm create vite
初始化后根据提示输入
//进入项目文件夹
cd vite-vue-project
//安装node_modules运行依赖
pnpm install 或 pnpm i
//启动项目
pnpm run dev
三、项目配置
1.javascript代码检测工具配置(eslint)
1.1安装eslint
npm i eslint@latest -D
或
pnpm add eslint@latest -D / pnpm install eslint@latest -D
或
yarn add eslint@latest -D
latest是下载最新版本,可以替换成你想要下载的版本
如:pnpm i eslint@8.8.0 -D
可以下载8.8.0版本的eslint
1.2 初始化eslint
npx eslint --init
执行后会出现一下步骤
安装完成后 (在项目根目录会出现.eslintrc.cjs或.eslintrc.js文件)
如果没有则手动创建一个.eslintrc.cjs
若为.eslintrc.js需要改名为.eslintrc.cjs
1.3 安装vite-plugin-eslint
// 该包是用于配置vite运行的时候自动检测eslint规范,不符合页面会报错
pnpm add vite-plugin-eslint@latest -D
// 安装最新版eslint-plugin-vue
pnpm add eslint-plugin-vue@latest -D
配置vite.config.js
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import eslintPlugin from 'vite-plugin-eslint' //导入包
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
eslintPlugin({
include: ['src/**/*.js', 'src/**/*.vue', 'src/*.js', 'src/*.vue']
})
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
1.4 安装 eslint-parser (ESLint解析器)
pnpm add @babel/core -D // 某些代码需要调用 Babel 的 API 进行转码,就要使用@babel/core模块。
pnpm add @babel/eslint-parser@latest -D
1.5 安装prettier (用于规范代码格式)
pnpm add prettier -D
pnpm add prettier-eslint -D
pnpm add eslint-config-prettier -D // eslint兼容的插件
pnpm add eslint-plugin-prettier -D // eslint的prettier
1.6 配置prettier
在项目根目录创建文件 .prettierrc.cjs
// 在项目根目录创建文件 .prettierrc
// 以下配置视自己情况而定,并步是每个都需要的
module.exports = {
tabWidth: 2, // 使用4个空格缩进
semi: false, // 代码结尾是否加分号
trailingComma: 'none', // 代码末尾不需要逗号
singleQuote: true, // 是否使用单引号
printWidth: 100, // 超过多少字符强制换行
arrowParens: 'avoid', // 单个参数的箭头函数不加括号 x => x
bracketSpacing: true, // 对象大括号内两边是否加空格 { a:0 }
endOfLine: 'auto', // 文件换行格式 LF/CRLF
useTabs: false, // 不使用缩进符,而使用空格
quoteProps: 'as-needed', // 对象的key仅在必要时用引号
jsxSingleQuote: false, // jsx不使用单引号,而使用双引号
jsxBracketSameLine: false, // jsx标签的反尖括号需要换行
rangeStart: 0, // 每个文件格式化的范围是文件的全部内容
rangeEnd: Infinity, // 结尾
requirePragma: false, // 不需要写文件开头的 @prettier
insertPragma: false, // 不需要自动在文件开头插入 @prettier
proseWrap: 'preserve', // 使用默认的折行标准
htmlWhitespaceSensitivity: 'css' // 根据显示样式决定html要不要折行
}
1.7配置配置 .eslintrc.cjs
module.exports = {
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended", // 使用推荐的eslint
'plugin:vue/vue3-recommended', // 使用插件支持vue3
// 如果你没有安装第7步,以下两个包不要引入,否则报错
'plugin:prettier/recommended',
'eslint-config-prettier'
],
"parserOptions": {
"ecmaVersion": 13,
"sourceType": "module",
"ecmaFeatures": {
"modules": true,
'jsx': true
},
"requireConfigFile": false,
"parser": '@babel/eslint-parser'
},
// eslint-plugin-vue
'plugins': [
'vue', // 引入vue的插件 vue <==> eslint-plugin-vue
// 这个包需要安装了第7步的三个包再引入
'prettier' // 引入规范插件 prettier <==> eslint-plugin-prettier
],
'globals': {
defineProps: 'readonly',
defineEmits: 'readonly',
defineExpose: 'readonly',
withDefaults: 'readonly'
},
// 这里时配置规则的,自己看情况配置
"rules": {
"no-self-assign": "off",
'semi': ['warn', 'never'], // 禁止尾部使用分号
'no-console': 'warn', // 禁止出现console
'no-debugger': 'warn', // 禁止出现debugger
'no-duplicate-case': 'warn', // 禁止出现重复case
'no-empty': 'warn', // 禁止出现空语句块
'no-extra-parens': 'warn', // 禁止不必要的括号
'no-func-assign': 'warn', // 禁止对Function声明重新赋值
'no-unreachable': 'warn', // 禁止出现[return|throw]之后的代码块
'no-else-return': 'warn', // 禁止if语句中return语句之后有else块
'no-empty-function': 'warn', // 禁止出现空的函数块
'no-lone-blocks': 'warn', // 禁用不必要的嵌套块
'no-multi-spaces': 'warn', // 禁止使用多个空格
'no-redeclare': 'warn', // 禁止多次声明同一变量
'no-return-assign': 'warn', // 禁止在return语句中使用赋值语句
'no-return-await': 'warn', // 禁用不必要的[return/await]
'no-self-compare': 'warn', // 禁止自身比较表达式
'no-useless-catch': 'warn', // 禁止不必要的catch子句
'no-useless-return': 'warn', // 禁止不必要的return语句
'no-mixed-spaces-and-tabs': 'warn', // 禁止空格和tab的混合缩进
'no-multiple-empty-lines': 'warn', // 禁止出现多行空行
'no-trailing-spaces': 'warn', // 禁止一行结束后面不要有空格
'no-useless-call': 'warn', // 禁止不必要的.call()和.apply()
'no-var': 'warn', // 禁止出现var用let和const代替
'no-delete-var': 'off', // 允许出现delete变量的使用
'no-shadow': 'off', // 允许变量声明与外层作用域的变量同名
'dot-notation': 'warn', // 要求尽可能地使用点号
'default-case': 'warn', // 要求switch语句中有default分支
'eqeqeq': 'warn', // 要求使用 === 和 !==
'curly': 'warn', // 要求所有控制语句使用一致的括号风格
'space-before-blocks': 'warn', // 要求在块之前使用一致的空格
'space-in-parens': 'warn', // 要求在圆括号内使用一致的空格
'space-infix-ops': 'warn', // 要求操作符周围有空格
'space-unary-ops': 'warn', // 要求在一元操作符前后使用一致的空格
'switch-colon-spacing': 'warn', // 要求在switch的冒号左右有空格
'arrow-spacing': 'warn', // 要求箭头函数的箭头前后使用一致的空格
'array-bracket-spacing': 'warn', // 要求数组方括号中使用一致的空格
'brace-style': 'warn', // 要求在代码块中使用一致的大括号风格
'camelcase': 'warn', // 要求使用骆驼拼写法命名约定
'indent': ['warn', 4], // 要求使用JS一致缩进4个空格
'max-depth': ['warn', 4], // 要求可嵌套的块的最大深度4
'max-statements': ['warn', 100], // 要求函数块最多允许的的语句数量20
'max-nested-callbacks': ['warn', 3], // 要求回调函数最大嵌套深度3
'max-statements-per-line': ['warn', { max: 1 }], // 要求每一行中所允许的最大语句数量
"quotes": ["warn", "single", "avoid-escape"], // 要求统一使用单引号符号
"vue/require-default-prop": 0, // 关闭属性参数必须默认值
"vue/singleline-html-element-content-newline": 0, // 关闭单行元素必须换行符
"vue/multiline-html-element-content-newline": 0, // 关闭多行元素必须换行符
// 要求每一行标签的最大属性不超五个
'vue/max-attributes-per-line': ['warn', { singleline: 5 }],
// 要求html标签的缩进为需要4个空格
"vue/html-indent": ["warn", 4, {
"attribute": 1,
"baseIndent": 1,
"closeBracket": 0,
"alignAttributesVertically": true,
"ignores": []
}],
// 取消关闭标签不能自闭合的限制设置
"vue/html-self-closing": ["error", {
"html": {
"void": "always",
"normal": "never",
"component": "always"
},
"svg": "always",
"math": "always"
}]
}
}
1.8配置VScode
安装“ESLint”插件 和 “Prettier code”插件
最后再重新安装依赖,防止有些依赖包降低或者升级带来的报错
pnpm i
或
npm i
最后
// 配置vscode
// 打开:设置 -> 文本编辑器 -> 字体 -> 在 settings.json 中编辑
// settings.json文件
{
// vscode默认启用了根据文件类型自动设置tabsize的选项
"editor.detectIndentation": false,
// 重新设定tabsize
"editor.tabSize": 4,
// 每次保存的时候自动格式化
"editor.formatOnSave": true,
// 每次保存的时候将代码按eslint格式进行修复
"eslint.autoFixOnSave": true,
// 添加vue支持
"eslint.validate": [
"javascript",
"javascriptreact",
{
"language": "vue",
"autoFix": true
}
],
// #让prettier使用eslint的代码格式进行校验
"prettier.eslintIntegration": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"eslint.codeActionsOnSave.rules": null
}
四、element-plus集成
1.导入element-plus指令
pnpm i element-plus
安装完成后在main.js中导入element-plus
//引入element-plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(ElementPlus)
2.导入element-plus图标
pnpm i @element-plus/icons-vue
需要的页面导入对应的图标,下面就是Edit图标的导入
<script setup>
import { Edit } from '@element-plus/icons-vue'
</script>
3.配置element-plus国际化,下面配置的是中文
// 引入element-plus国际化
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
const app = createApp(App)
app.use(ElementPlus, {
location: zhCn // element-plus国际化配置
})
五、配置生产环境.env.production、测试环境.env.development
.env.production 生产环境加载
.env.development 测试开发环境加载
在文件里面配置如下
在.env文件
VUE_APP_NAME='vue测试名称'
.env.development文件:
NODE_ENV = development
VUE_APP_URL = 'developmentURL' //自定义变量 必须要以VUE_APP_开头定义
.env.production 文件:
NODE_ENV = production
VUE_APP_URL = 'productionURL' //自定义变量 必须要以VUE_APP_开头定义
下面我们就需要配置 package.json 添加如下字段
"scripts": {
"build-development": "vue-tsc && vite build --mode development",
"bulid:pro": "vue-tsc && vite build --mode production",
},
六、封装Svg组件
1.安装 vite-plugin-svg-icons:
npm install vite-plugin-svg-icons -D
2.在 vite 配置文件中添加插件
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
import path from "path";
export default defineConfig({
plugins: [
vue(),
createSvgIconsPlugin({
// 指定目录(svg存放目录)
iconDirs: [path.resolve(process.cwd(), "src/assets/svgs")],
// 使用 svg 图标的格式(name为图片名称)
symbolId: "icon-[name]",
//生成组件插入位置 只有两个值 boby-last | body-first
inject: 'body-last'
})
],
})
3.在main.ts文件中全局导入
import 'virtual:svg-icons-register';
4.封装svg组件,封装svg组件,可修改宽高和颜色
<template>
<svg
aria-hidden="true"
:width="width"
:height="height"
:fill="color"
>
<use :xlink:href="`#icon-${name}` fill = "颜色"/>
</svg>
</template>
<script setup lang="ts">
defineProps<{
name: string,
width: string,
height: string,
color?: string
}>();
</script>
5.使用
<template>
<SvgIcon name="close" width="24" height="24"></SvgIcon>
</template>
<script setup>
import SvgIcon from "@/components/svg-icon/svg-icon.vue";
</script>
七、mock接口(模拟接口)
1.安装依赖
pnpm install -D vite-plugin-mock mockjs
2.在vit.config.js配置文件启用插件
// mock插件提供方法
import { viteMockServe } from 'vite-plugin-mock'
export default defineConfig(({ command }) => {
return {
plugins: [
viteMockServe({
localEndabled: command === 'serve' // 保证开发阶段可以使用mock接口
})
],
})
3.在根目录创建mock文件夹:去创建我们需要的mock数据与接口
例: 在mock文件夹内部创建一个user.js文件,内容如下
// 用户信息数据
// 此函数执行会返回一个数组,数组里面包含俩个用户信息
function createUserList() {
return [
{
userId: 1,
avatar: 'https://pic.cnblogs.com/avatar/1808605/20230206194007.png',
username: 'munaiyi',
password: '123456',
desc: '平台管理员',
roles: ['平台管理员'],
buttons: ['cuser.detail'],
routes: ['home'],
token: 'Admin Token'
},
{
userId: 1,
avatar: 'https://c-ssl.dtstatic.com/uploads/item/202004/14/20200414210134_qbeyi.thumb.400_0.jpg',
username: 'system',
password: '123456',
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 } }
}
}
]
八、axios二次封装
1.安装依赖
pnpm i axios
在开发项目的时候避免不了与后端进行交豆,因此我们需要使用axios插件实现发送网络请求。在开发项目的时候我们经常会把axios进行二次封装。
目的:
1:使用请求拦截器,可以在请求拦截器中处理一些业务(开始进度条、请求头携带公共参数)
2:使用响应拦截器,可以在响应拦截器中处理一些业务(进度条结束、简化服务器返回的数据、处理htp网络错误)
在根目录下创建utils/request.ts
error部分自行修改
// 进行axios的二次封装:使用请求与响应拦截器
import axios from 'axios'
import { ElMessage } from 'element-plus'
// 第一步: 利用axios对象的create方法,创建axios实例
const service = axios.create({
// 基础路径
baseURL: import.meta.env.VITE_APP_BASE_API, // 基础路径上带/api
timeout: 5000 // 超时的时间设置
})
// 第二步: request 实例添加请求与响应拦截器
service.interceptors.request.use(config => {
// 返回配置对象
return config
})
// 第三步 :响应拦截器
service.interceptors.response.use(
response => {
// 成功回调
// 简化数据
return response.data
},
error => {
// 失败的回调:处理http网络错误
// 定义一个变量:存储网络错误的信息
let message = ''
// http状态码
const 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 service