文章统计:838字,预计阅读:2分钟。
项目配置 Vite+Element-plus+TS 二次封装
main.ts
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import ElementPlus from "element-plus";
import { useRegisterIcon } from "./utils";
import { createPinia } from 'pinia'
import "./style/index.scss"; // 样式入口文件
const app = createApp(App);
app.use(router).use(ElementPlus).use(useRegisterIcon).use(createPinia())
app.mount("#app");
- useRegisterIcon 全局注册 element 图标
import { App } from "vue";
import * as icons from "@element-plus/icons-vue";
/**
* 全局注册 element 图标
*/
export const useRegisterIcon = {
install(app: App) {
Object.keys(icons).forEach((key) => {
app.component("Icon" + key, icons[key]);
});
}
}
- 引入样式文件
// src\style\index.scss
@import "normalize.css"; // 样式重置
@import "./src/reset.scss"; // 全局样式
@import "element-plus/dist/index.css"; // element 组件默认样式
@import 'nprogress/nprogress.css'; // 进度条样式
@import './src/element'; // element 样式修改
// ./src/reset.scss
html,body,#app{
height: 100%;
}
svg{
width: 1em;
height: 1em;
}
定义 pinia
// src\stores\index.ts
import { defineStore } from 'pinia'
export const useStore = defineStore('main', {
})
配置路由
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
import nprogress from "nprogress";
import { Meta } from "@/types";
import container from '@/components/container/src/index.vue'
import { removeAll } from '@/utils'
declare module "vue-router" {
interface RouteMeta extends Meta {}
}
const routes: RouteRecordRaw[] = [
{
path: '/',
component: container,
meta:{
keepAlive: true
},
children: [
{
path: "/",
name: "index",
component: () => import("@/views/Home.vue"),
meta: {
title: "首页",
// keepAlive: true
},
},
]
},
{
path: "/404",
name: "404",
component: () => import("@/views/404.vue"),
meta: {
title: "404",
},
},
{
path: "/:pathMatch(.*)*",
redirect: "/404",
},
];
const router = createRouter({
history: createWebHashHistory(),
routes,
});
router.beforeEach((to, from, next) => {
removeAll()
nprogress.start();
next();
});
router.afterEach((to) => {
document.title = to.meta.title || '';
nprogress.done();
});
export default router;
- Meta 类型
// src\types\src\interface.ts
export interface Meta {
title?: string; // 网站标题
keepAlive?: boolean; // 缓存页面
}
tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"skipLibCheck": true,
"suppressImplicitAnyIndexErrors": true, // 跳过库检查
"baseUrl": "./",
"paths": { // 别名
"@/*": ["./src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
}
tsconfig.node.json
{
"compilerOptions": {
"composite": true,
"module": "esnext",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true, // 运行合成默认导入
},
"include": ["vite.config.ts"]
}
vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
import { visualizer } from "rollup-plugin-visualizer"; // 打包体积分析插件可视化工具,npm run build 后根目录生成 stats.html 浏览器打开
const resolve = (...rest) => path.resolve(__dirname, ...rest);
export default ({ mode }) => {
return defineConfig({
plugins: [vue(), visualizer()],
base: mode === "dev" ? "/" : "/shengchang", // 编译的 public 路径前缀
envDir: "./env/",
resolve: {
alias: {
// 别名
"@": resolve("src"),
},
},
server: {
port: 80,
host: "0.0.0.0", // 配合 package.json scripts中 --host 0.0.0.0 来允许通过ip地址来访问服务
proxy: {
// 开启代理
"/api": {
target: "https://xxxx.com",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
build: {
outDir: "dist", // 编译后的文件名
assetsDir: "assets", // 编译后静态文件的文件夹名称
},
});
};
env.d.ts
// src\env.d.ts
interface ImportMetaEnv { // 定义环境变量 ts 智能提示
readonly VITE_NODE_ENV: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
环境变量
// env\.env.dev 根目录 env文件夹下(vite.config.ts中设置的)
VITE_NODE_ENV=dev
utils 方法
项目创建只写了一部分
// src\utils\index.ts
export * from './src/debounce' // 防抖
export * from './src/throttle' // 节流
export * from './src/http' // 接口请求封装
export * from './src/cancelRequest' // 接口请求节流封装
export * from './src/vueuse' // vueuse 方法封装
export * from './src/element' // element 相关方法
- 防抖(debounce)节流(throttle)
- http 接口请求封装
- cancelRequest 接口请求节流封装
- element 相关方法示例:
import { App } from "vue";
import * as icons from "@element-plus/icons-vue";
/**
* 全局注册 element 图标
*/
export const useRegisterIcon = {
install(app: App) {
Object.keys(icons).forEach((key) => {
app.component("Icon" + key, icons[key]);
});
}
}
- vueuse 方法封装示例:
import { useClipboard, } from '@vueuse/core';
/**
* 复制文字
* @param text 要复制的内容
*/
export const handleClipboard = (text: string) => useClipboard().copy(text)