文章统计: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 相关方法
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)
最后更新时间:
贡献者: tomiaa