vue3+typescript管理系统项目集成
项目集成
集成element-plus
1、安装
pnpm install element-plus @element-plus/icons-vue
2、main.ts文件配置
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css'
//@ts-ignore忽略当前文件ts类型的检测否则有红色提示(打包会失败)
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
app.use(ElementPlus, {
locale: zhCn
})
3、src/components的index.ts文件中将element-plus配置为全局组件
import type { App } from 'vue';
//引入element-plus提供的全部图标组件
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
export default {
install(app: App) {
//将element-plus提供图标注册为全局组件
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
}
}
src别名配置
1、vite.config.ts文件配置
import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
"@": path.resolve("./src") // 相对路径别名配置,使用 @ 代替 src
}
}
})
2、tsconfig.app.json配置
{
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "preserve",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"types": ["element-plus/global"],
"baseUrl": "./", // 解析非相对模块的基地址,默认是当前目录
"paths": { //路径映射,相对于baseUrl
"@/*": ["src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}
环境变量配置
1、.env.development文件配置
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'development'
VITE_APP_TITLE = '硅谷甄选运营平台'
VITE_APP_BASE_API = '/dev-api'
VITE_SERVE = 'http://sph-api.atguigu.cn'
2、.env.production文件配置
NODE_ENV = 'production'
VITE_APP_TITLE = '硅谷甄选运营平台'
VITE_APP_BASE_API = '/prod-api'
VITE_SERVE = 'http://sph-api.atguigu.cn'
3、.env.test文件配置
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'test'
VITE_APP_TITLE = '硅谷甄选运营平台'
VITE_APP_BASE_API = '/test-api'
VITE_SERVE = 'http://sph-api.atguigu.cn'
4、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"
},
import.meta.env获取环境变量
SVG图标配置
1、安装
pnpm install vite-plugin-svg-icons -D
2、配置vite.config.ts文件
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import path from 'path'
export default () => {
return {
plugins: [
createSvgIconsPlugin({
// Specify the icon folder to be cached
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
// Specify symbolId format
symbolId: 'icon-[dir]-[name]',
}),
],
}
}
3、main.ts文件配置
import 'virtual:svg-icons-register'
4、svg封装为全局变量
-
src/components目录创建SvgIcon/index.vue组件
<template> <div> <svg :style="{ width: width, height: height }"> <use :xlink:href="prefix + name" :fill="color"></use> </svg> </div> </template> <script setup lang="ts"> defineProps({ //xlink:href属性值的前缀 prefix: { type: String, default: '#icon-' }, //svg矢量图的名字 name: String, //svg图标的颜色 color: { type: String, default: "" }, //svg宽度 width: { type: String, default: '16px' }, //svg高度 height: { type: String, default: '16px' } }) </script> <style scoped></style>
-
src/components目录创建index.ts
import SvgIcon from './SvgIcon/index.vue'; import type { App, Component } from 'vue'; const components: { [name: string]: Component } = { SvgIcon }; export default { install(app: App) { Object.keys(components).forEach((key: string) => { app.component(key, components[key]); }) } }
-
main.ts文件配置
import gloablComponent from './components/index'; app.use(gloablComponent);
集成sass
1、src/styles目录创建reset.scss文件(代码参考npm官网)
2、src/styles目录创建index.scss文件
import '@/styles'
3、src/styles目录创建variable.scss文件(里面配置全局变量)
4、vite.config.ts文件配置
export default defineConfig((config) => {
css: {
preprocessorOptions: {
scss: {
javascriptEnabled: true,
additionalData: '@import "./src/styles/variable.scss";',
},
},
},
}
}
6mock数据
1、安装
pnpm install -D vite-plugin-mock mockjs
2、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',
}),
],
}
}
3、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} }
},
},
]
axios二次封装
1、安装
pnpm install axios
2、src/utils创建request.ts文件
import axios from "axios";
import { ElMessage } from "element-plus";
//创建axios实例
let request = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_API,
timeout: 5000
})
//请求拦截器
request.interceptors.request.use(config => {
return config;
});
//响应拦截器
request.interceptors.response.use((response) => {
return response.data;
}, (error) => {
//处理网络错误
let msg = '';
let status = error.response.status;
switch (status) {
case 401:
msg = "token过期";
break;
case 403:
msg = '无权访问';
break;
case 404:
msg = "请求地址错误";
break;
case 500:
msg = "服务器出现问题";
break;
default:
msg = "无网络";
}
ElMessage({
type: 'error',
message: msg
})
return Promise.reject(error);
});
export default request;