声明本文章只是自己搭建后台框架得一个笔记,不作为任何项目搭建指南,大家看着乐呵乐呵就行。
一、安装对应依赖 Vue3 + Pinia + Vitest + ESlint + Prettier + Router
npm init vue@latest // Vue3 node_modules 需要Node 15.0.0版本以上支持
✔ Project name: … <项目名称>
✔ Add TypeScript? … No / Yes ---------------------------------------- #安装 TypeScript
✔ Add JSX Support? … No / Yes ---------------------------------------- #安装对 JSX 语法的支持
✔ Add Vue Router for Single Page Application development? … No / Yes - #安装 Vue Router 路由管理
✔ Add Pinia for state management? … No / Yes ------------------------- #安装 Pinia 状态管理
✔ Add Vitest for Unit testing? … No / Yes ---------------------------- #安装 Vitest 单元测试
✔ Add Cypress for both Unit and End-to-End testing? … No / Yes ------- #安装 Cypress 端到端测试
✔ Add ESLint for code quality? … No / Yes ---------------------------- #安装 ESLint 代码校验
✔ Add Prettier for code formatting? … No / Yes ----------------------- #安装 Prettier 统一代码规范
二、构建页面路由
// 这个文件存放所有的公共页面路由 login 404 500 等
export default [
{
path: '/login',
name: 'login',
meta: {
icon: '',
title: '登录',
},
component:() => import('../views/login/Login.vue')
},
{
path: '/about',
name: 'about',
component: () => import('../views/AboutView.vue')
}
]
import { createRouter, createWebHistory } from "vue-router";
import routers from "./routers";
import NProgress from 'nprogress';
import { USER_TOKEN } from "../utils/LocalDateName";
import { getStorage } from "../utils/PublicFunction";
const onAuthPage = ["/login"];
// 页面加载 进度条
NProgress.configure({
showSpinner: false, // true 开启loading false 关闭
});
const router = createRouter({
history: createWebHistory(), // hash模式:createWebHashHistory,history模式:createWebHistory
scrollBehavior(to, from, savedPosition) {
return savedPosition ? savedPosition : { left: 0, top: 0 }; // 页面初始化保留位置
},
routes: routers
});
// 创建路由守卫
router.beforeEach((to, from, next) => {
// 开启 进度条
NProgress.start()
// 当前路由 不为登录页面 且 没有token 回退到登录页面
if (!onAuthPage.includes(to.path) && !getStorage(USER_TOKEN)) {
next({ path: "/login", replace: true });
} else {
next();
}
});
router.afterEach((to)=>{
// 关闭 进度条
NProgress.done();
})
export default router;
三·创建公共存储函数
- src下创建 utils文件 创建 PublicFunction.js
/**
* 存储localStorage
*/
export const setStorage = (name, content) => {
if (!name) return;
if (content) {
content = JSON.stringify(content);
}
window.localStorage.setItem(name, content);
};
/**
* 获取 localStorage
*/
export const getStorage = (name) => {
if (!name) return;
return JSON.parse(window.localStorage.getItem(name));
};
/**
* 删除 localStorage
*/
export const removeStorage = (name) => {
if (!name) return;
window.localStorage.removeItem(name);
};
/**
* 存储 sessionStorage
*/
export const setSessionStorage = (name, content) => {
if (!name) return;
if (content) {
content = JSON.stringify(content);
}
window.sessionStorage.setItem(name, content);
};
/**
* 获取 sessionStorage
*/
export const getSessionStorage = (name) => {
if (!name) return;
return JSON.parse(window.sessionStorage.getItem(name));
};
/**
* 删除 sessionStorage
*/
export const removeSessionStorage = (name) => {
if (!name) return;
window.sessionStorage.removeItem(name);
};
/**
* 返回顶部
*/
export const scrollToTop = () => {
const c = document.documentElement.scrollTop || document.body.scrollTop;
if (c > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, c - c / 8);
}
};
/**
* 复制字符串到剪贴板
*/
export const copyToClipboard = str => {
const el = document.createElement("textarea");
el.value = str;
el.setAttribute("readonly", "");
el.style.position = "absolute";
el.style.left = "-9999px";
document.body.appendChild(el);
const selected = document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false;
el.select();
document.execCommand("copy");
document.body.removeChild(el);
if (selected) {
document.getSelection().removeAllRanges();
document.getSelection().addRange(selected);
}
};
四、创建公共CSS文件
/*
全局公共样式类方法
*/
/*浏览器滚动条*/
::-webkit-scrollbar {
width: 6px;
height: 8px;
background-color: transparent;
}
::-webkit-scrollbar-track {
background-color: transparent;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background-color: rgba(144, 147, 153, .5);
}
li {
list-style: none;
}
/* 字体大小*/
.fs-10 {
display: inline-block;
font-size: 12px;
-webkit-text-size-adjust: none;
-webkit-transform: scale(0.83, 0.83);
}
.fs-12 {
font-size: 12px;
}
.fs-14 {
font-size: 14px;
}
.fs-16 {
font-size: 16px;
}
.fs-18 {
font-size: 18px;
}
.fs-20 {
font-size: 20px;
}
.fs-22 {
font-size: 22px;
}
.fs-24 {
font-size: 24px;
}
.fs-26 {
font-size: 26px;
}
.fs-28 {
font-size: 28px;
}
.fs-30 {
font-size: 30px;
}
.fs-32 {
font-size: 32px;
}
.fs-34 {
font-size: 34px;
}
.fs-36 {
font-size: 36px;
}
.fs-38 {
font-size: 38px;
}
.fs-40 {
font-size: 40px;
}
.fs-48 {
font-size: 48px;
}
/* 颜色相关 */
.cl-main {
color: #117AEC
}
.cl-main-second {
color: #29a7e1;
}
.cl-link {
color: #117AEC;
}
.cl-fff {
color: #fff;
}
.cl-000 {
color: #000;
}
.cl-222 {
color: #222;
}
.cl-333 {
color: #333;
}
.cl-26 {
color: #262626;
}
.cl-444 {
color: #444;
}
.cl-666 {
color: #666;
}
.cl-999 {
color: #999;
}
.cl-ccc {
color: #ccc;
}
.cl-eee {
color: #eee;
}
.cl-59 {
color: #595959;
}
.cl-8c {
color: #8c8c8c;
}
.cl-26 {
color: #262626;
}
.cl-bf {
color: #bfbfbf;
}
.cl-eee {
color: #eee;
}
.cl-danger {
color: #FF2B00;
}
.cl-warning {
color: orange;
}
.cl-success {
color: #16D9A8;
}
/*margin-top*/
.mt-5 {
margin-top: 5px;
}
.mt-10 {
margin-top: 10px;
}
.mt-15 {
margin-top: 15px;
}
.mt-20 {
margin-top: 20px;
}
.mt-25 {
margin-top: 25px;
}
.mt-30 {
margin-top: 30px;
}
.mt-35 {
margin-top: 35px;
}
.mt-40 {
margin-top: 40px;
}
.mt-45 {
margin-top: 45px;
}
.mt-50 {
margin-top: 50px;
}
.mt-55 {
margin-top: 55px;
}
.mt-60 {
margin-top: 60px;
}
.mt-65 {
margin-top: 65px;
}
.mt-70 {
margin-top: 70px;
}
.mt-75 {
margin-top: 75px;
}
.mt-80 {
margin-top: 80px;
}
.mt-85 {
margin-top: 85px;
}
.mt-90 {
margin-top: 90px;
}
.mt-95 {
margin-top: 95px;
}
.mt-100 {
margin-top: 100px;
}
.mt-130 {
margin-top: 130px;
}
.mt-150 {
margin-top: 150px;
}
/*margin-right*/
.mr-5 {
margin-right: 5px;
}
.mr-10 {
margin-right: 10px;
}
.mr-15 {
margin-right: 15px;
}
.mr-20 {
margin-right: 20px;
}
.mr-25 {
margin-right: 25px;
}
.mr-30 {
margin-right: 30px;
}
.mr-35 {
margin-right: 35px;
}
.mr-40 {
margin-right: 40px;
}
.mr-45 {
margin-right: 45px;
}
.mr-50 {
margin-right: 50px;
}
.mr-55 {
margin-right: 55px;
}
.mr-60 {
margin-right: 60px;
}
.mr-65 {
margin-right: 65px;
}
.mr-70 {
margin-right: 70px;
}
.mr-75 {
margin-right: 75px;
}
.mr-80 {
margin-right: 80px;
}
.mr-85 {
margin-right: 85px;
}
.mr-90 {
margin-right: 90px;
}
.mr-95 {
margin-right: 95px;
}
.mr-100 {
margin-right: 100px;
}
/*margin-bottom*/
.mb-5 {
margin-bottom: 5px;
}
.mb-10 {
margin-bottom: 10px;
}
.mb-15 {
margin-bottom: 15px;
}
.mb-20 {
margin-bottom: 20px;
}
.mb-25 {
margin-bottom: 25px;
}
.mb-30 {
margin-bottom: 30px;
}
.mb-35 {
margin-bottom: 35px;
}
.mb-40 {
margin-bottom: 40px;
}
.mb-45 {
margin-bottom: 45px;
}
.mb-50 {
margin-bottom: 50px;
}
.mb-55 {
margin-bottom: 55px;
}
.mb-60 {
margin-bottom: 60px;
}
.mb-65 {
margin-bottom: 65px;
}
.mb-70 {
margin-bottom: 70px;
}
.mb-75 {
margin-bottom: 75px;
}
.mb-80 {
margin-bottom: 80px;
}
.mb-85 {
margin-bottom: 85px;
}
.mb-90 {
margin-bottom: 90px;
}
.mb-95 {
margin-bottom: 95px;
}
.mb-100 {
margin-bottom: 100px;
}
/*margin-left*/
.ml-5 {
margin-left: 5px;
}
.ml-10 {
margin-left: 10px;
}
.ml-15 {
margin-left: 15px;
}
.ml-20 {
margin-left: 20px;
}
.ml-25 {
margin-left: 25px;
}
.ml-30 {
margin-left: 30px;
}
.ml-35 {
margin-left: 35px;
}
.ml-40 {
margin-left: 40px;
}
.ml-45 {
margin-left: 45px;
}
.ml-50 {
margin-left: 50px;
}
.ml-55 {
margin-left: 55px;
}
.ml-60 {
margin-left: 60px;
}
.ml-65 {
margin-left: 65px;
}
.ml-70 {
margin-left: 70px;
}
.ml-75 {
margin-left: 75px;
}
.ml-80 {
margin-left: 80px;
}
.ml-85 {
margin-left: 85px;
}
.ml-90 {
margin-left: 90px;
}
.ml-95 {
margin-left: 95px;
}
.ml-100 {
margin-left: 100px;
}
/*padding*/
.pd-5 {
padding: 5px;
}
.pd-10 {
padding: 10px;
}
.pd-15 {
padding: 15px;
}
.pd-20 {
padding: 20px;
}
.pd-25 {
padding: 25px;
}
.pd-30 {
padding: 30px;
}
.pd-35 {
padding: 35px;
}
.pd-40 {
padding: 40px;
}
.pd-45 {
padding: 45px;
}
.pd-50 {
padding: 50px;
}
.pd-55 {
padding: 55px;
}
.pd-60 {
padding: 60px;
}
.pd-65 {
padding: 65px;
}
.pd-70 {
padding: 70px;
}
.pd-75 {
padding: 75px;
}
.pd-80 {
padding: 80px;
}
.pd-85 {
padding: 85px;
}
.pd-90 {
padding: 90px;
}
.pd-95 {
padding: 95px;
}
.pd-100 {
padding: 100px;
}
/*padding-top*/
.pt-5 {
padding-top: 5px;
}
.pt-10 {
padding-top: 10px;
}
.pt-15 {
padding-top: 15px;
}
.pt-20 {
padding-top: 20px;
}
.pt-25 {
padding-top: 25px;
}
.pt-30 {
padding-top: 30px;
}
.pt-35 {
padding-top: 35px;
}
.pt-40 {
padding-top: 40px;
}
.pt-45 {
padding-top: 45px;
}
.pt-50 {
padding-top: 50px;
}
.pt-55 {
padding-top: 55px;
}
.pt-60 {
padding-top: 60px;
}
.pt-65 {
padding-top: 65px;
}
.pt-70 {
padding-top: 70px;
}
.pt-75 {
padding-top: 75px;
}
.pt-80 {
padding-top: 80px;
}
.pt-85 {
padding-top: 85px;
}
.pt-90 {
padding-top: 90px;
}
.pt-95 {
padding-top: 95px;
}
.pt-100 {
padding-top: 100px;
}
/*padding-right*/
.pr-5 {
padding-right: 5px;
}
.pr-10 {
padding-right: 10px;
}
.pr-15 {
padding-right: 15px;
}
.pr-20 {
padding-right: 20px;
}
.pr-25 {
padding-right: 25px;
}
.pr-30 {
padding-right: 30px;
}
.pr-35 {
padding-right: 35px;
}
.pr-40 {
padding-right: 40px;
}
.pr-45 {
padding-right: 45px;
}
.pr-50 {
padding-right: 50px;
}
.pr-55 {
padding-right: 55px;
}
.pr-60 {
padding-right: 60px;
}
.pr-65 {
padding-right: 65px;
}
.pr-70 {
padding-right: 70px;
}
.pr-75 {
padding-right: 75px;
}
.pr-80 {
padding-right: 80px;
}
.pr-85 {
padding-right: 85px;
}
.pr-90 {
padding-right: 90px;
}
.pr-95 {
padding-right: 95px;
}
.pr-100 {
padding-right: 100px;
}
/*padding-bottom*/
.pb-5 {
padding-bottom: 5px;
}
.pb-10 {
padding-bottom: 10px;
}
.pb-15 {
padding-bottom: 15px;
}
.pb-20 {
padding-bottom: 20px;
}
.pb-25 {
padding-bottom: 25px;
}
.pb-30 {
padding-bottom: 30px;
}
.pb-35 {
padding-bottom: 35px;
}
.pb-40 {
padding-bottom: 40px;
}
.pb-45 {
padding-bottom: 45px;
}
.pb-50 {
padding-bottom: 50px;
}
.pb-55 {
padding-bottom: 55px;
}
.pb-60 {
padding-bottom: 60px;
}
.pb-65 {
padding-bottom: 65px;
}
.pb-70 {
padding-bottom: 70px;
}
.pb-75 {
padding-bottom: 75px;
}
.pb-80 {
padding-bottom: 80px;
}
.pb-85 {
padding-bottom: 85px;
}
.pb-90 {
padding-bottom: 90px;
}
.pb-95 {
padding-bottom: 95px;
}
.pb-100 {
padding-bottom: 100px;
}
/*padding-left*/
.pl-5 {
padding-left: 5px;
}
.pl-10 {
padding-left: 10px;
}
.pl-15 {
padding-left: 15px;
}
.pl-20 {
padding-left: 20px;
}
.pl-25 {
padding-left: 25px;
}
.pl-30 {
padding-left: 30px;
}
.pl-35 {
padding-left: 35px;
}
.pl-40 {
padding-left: 40px;
}
.pl-45 {
padding-left: 45px;
}
.pl-50 {
padding-left: 50px;
}
.pl-55 {
padding-left: 55px;
}
.pl-60 {
padding-left: 60px;
}
.pl-65 {
padding-left: 65px;
}
.pl-70 {
padding-left: 70px;
}
.pl-75 {
padding-left: 75px;
}
.pl-80 {
padding-left: 80px;
}
.pl-85 {
padding-left: 85px;
}
.pl-90 {
padding-left: 90px;
}
.pl-95 {
padding-left: 95px;
}
.pl-100 {
padding-left: 100px;
}
.wd-100p {
width: 100%;
}
/*flex 布局*/
.flex {
display: flex;
}
.flex-inline {
display: inline-flex;
}
.flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.flex-row {
display: flex;
flex-direction: row;
}
.flex-row-warp {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.flex-row-space-between {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.flex-row-space-around {
display: flex;
flex-direction: row;
justify-content: space-around;
}
.flex-column {
display: flex;
flex-direction: column;
}
.flex-1 {
flex: 1;
}
.flex-2 {
flex: 2;
}
.flex-3 {
flex: 3;
}
.flex-4 {
flex: 4;
}
.flex-5 {
flex: 5;
}
.wrap {
flex-wrap: wrap;
}
.align-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.justify-right {
justify-content: flex-end;
}
/*其他*/
.font-bold {
font-weight: bold;
}
.font-italic {
font-style: italic;
}
.font-normal {
font-weight: normal;
}
.text-center {
text-align: center;
}
.text-right {
text-align: right;
}
.text-left {
text-align: left;
}
.line-through {
text-decoration: line-through;
}
.underline {
text-decoration: underline;
}
.clear:after {
content: "";
height: 0;
display: table;
clear: both;
visibility: hidden;
}
.left {
float: left;
}
.right {
float: right;
}
.inline {
display: inline;
}
.block {
display: block;
}
.inline-block {
display: inline-block;
}
.display-none {
display: none!important;
}
.position-relative {
position: relative;
}
.position-absolute {
position: absolute;
}
.vtc-mid {
vertical-align: middle;
}
.vtc-btm {
vertical-align: bottom;
}
.vtc-sup {
vertical-align: super;
}
.vtc-sub {
vertical-align: sub;
}
.vtc-top {
vertical-align: top;
}
.vtc-text-btm {
vertical-align: text-bottom;
}
.cursor-p {
cursor: pointer;
}
.cursor-m {
cursor: move;
}
.border-box {
box-sizing: border-box;
}
.text-line {
text-decoration: underline;
}
.over-hide {
overflow: hidden;
}
.ellipsis {
text-overflow: ellipsis;
white-space: nowrap;
}
/*width*/
.width-50 {
width: 50px;
}
.width-60 {
width: 60px;
}
.width-80 {
width: 80px;
}
.width-100 {
width: 100px;
}
.width-150 {
width: 150px;
}
.width-200 {
width: 200px;
}
.width-250 {
width: 250px;
}
.width-300 {
width: 300px;
}
.width-350 {
width: 350px;
}
.width-400 {
width: 400px;
}
.width-500 {
width: 500px;
}
.width-600 {
width: 600px;
}
.width-800 {
width: 800px;
}
.require::before {
display: inline-block;
margin-right: 4px;
color: #ff4d4f;
font-size: 14px;
font-family: SimSun,sans-serif;
line-height: 1;
content: '*';
}
#k_s_ol_chatWinSm_imgDiv,
#k_s_ol_inviteWin_fl,
#ks_dir_t_cg,
#ks_dir_t_cls {
display: none;
}
/* nprogress css start*/
#nprogress {
pointer-events: none;
}
#nprogress .bar {
background: #117AEC;
position: fixed;
z-index: 1031;
top: 0;
left: 0;
width: 100%;
height: 2px;
}
#nprogress .peg {
display: block;
position: absolute;
right: 0px;
width: 100px;
height: 100%;
box-shadow: 0 0 10px #29d, 0 0 5px #117AEC;
opacity: 1.0;
-webkit-transform: rotate(3deg) translate(0px, -4px);
-ms-transform: rotate(3deg) translate(0px, -4px);
transform: rotate(3deg) translate(0px, -4px);
}
#nprogress .spinner {
display: block;
position: fixed;
z-index: 1031;
top: 15px;
right: 15px;
}
#nprogress .spinner-icon {
width: 18px;
height: 18px;
box-sizing: border-box;
border: solid 2px transparent;
border-top-color: #117AEC;
border-left-color: #117AEC;
border-radius: 50%;
-webkit-animation: nprogress-spinner 400ms linear infinite;
animation: nprogress-spinner 400ms linear infinite;
}
.nprogress-custom-parent {
overflow: hidden;
position: relative;
}
.nprogress-custom-parent #nprogress .spinner,
.nprogress-custom-parent #nprogress .bar {
position: absolute;
}
@-webkit-keyframes nprogress-spinner {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes nprogress-spinner {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* nprogress css end*/
/* ant css start*/
.ant-table td {
white-space: nowrap;
}
/* ant css end*/
项目创建路由和公共变量创建完毕