一、环境
node版本:

二、创建基本的文件目录结构
├── mock
├── src
│ ├── api
│ ├── http
│ ├── assets
│ ├── components
│ ├── layout
│ ├── router
│ ├── store
│ ├── styles
│ ├── utils
│ ├── views
│ ├── App.vue
│ ├── main.ts
├── .env.xxx
├── index.html
├── tsconfig.json
├── vite.config.ts
└── package.json
三、步骤
3.1、html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
</body>
<script src="./src/main.ts" type="module"></script>
</html>
3.2、App.vue文件
<template>
<div>
<router-view></router-view>
</div>
</template>
<script setup lang="ts">
</script>
<style lang="less" scoped>
</style>
3.3、tsconfig.json文件
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"allowJs": true,
"moduleResolution": "node",
"strict": true,
"forceConsistentCasingInFileNames": true,
"allowSyntheticDefaultImports": true,
"jsx": "preserve",
"sourceMap": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"experimentalDecorators": true,
"lib": [
"dom",
"esnext"
],
"noImplicitAny": false,
"skipLibCheck": true,
"types": [
"vite/client",
"element-plus/global"
],
"removeComments": true,
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
],
"#/*": [
"types/*"
]
},
"rootDirs": []
},
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
"types/**/*.d.ts",
"types/**/*.ts",
"build/**/*.ts",
"build/**/*.d.ts",
"mock/**/*.ts",
"vite.config.ts"
],
"exclude": [
"node_modules",
"dist",
"**/*.js"
]
}
3.4、vite.config.ts文件
import { defineConfig, loadEnv } from "vite";
import type { UserConfig, ConfigEnv } from "vite";
import { fileURLToPath } from "url";
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
const root = process.cwd();
const env = loadEnv(mode, root);
console.log(env);
return {
root,
base: "./",
publicDir: fileURLToPath(new URL("./public", import.meta.url)),
assetsInclude: fileURLToPath(new URL("./src/assets", import.meta.url)),
plugins: [
vue(),
vueJsx(),
],
server: {
https: false,
host: true,
port: 8080,
open: false,
cors: true,
proxy: {
'/agent': {
target: "http://www.birne9.com",
changeOrigin: true,
},
},
},
build: {
sourcemap: false,
chunkSizeWarningLimit: 10000,
rollupOptions: {
input: {
index: fileURLToPath(
new URL("./index.html", import.meta.url),
),
},
output: {
format: "esm",
chunkFileNames: "static/js/[name]-[hash].js",
entryFileNames: "static/js/[name]-[hash].js",
assetFileNames: "static/[ext]/[name]-[hash].[ext]",
},
},
},
resolve: {
alias: {
"@": fileURLToPath(new URL("./src", import.meta.url)),
"#": fileURLToPath(new URL("./types", import.meta.url)),
},
},
};
});
3.5、env.d.ts文件
interface ImportMetaEnv {
readonly VITE_APP_API_BASEURL: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
3.6、配置router
import { createRouter, RouteRecordRaw, createWebHashHistory } from "vue-router";
import NProgress from 'nprogress'
const routes:Array<RouteRecordRaw>=[{
path:"/",
name:'home',
component:()=>import('../views/home/index.vue')
},
{
path:"/about",
name:'about',
component:()=>import('../views/about/index.vue')
}]
const router=createRouter({
routes,
history:createWebHashHistory()
})
router.beforeEach((to,from,next)=>{
NProgress.start();
next();
})
router.afterEach((_to) => {
NProgress.done();
})
export default router;
3.7、配置仓库
import { createPinia } from "pinia";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);
export default pinia;
3.8、封装请求
import axios from "axios";
const service = axios.create({
baseURL:'/',
timeout:10000
});
service.interceptors.request.use(config => {
return config;
},err => {
Promise.reject(err);
})
service.interceptors.response.use(res => {
return res.data;
},err => {
Promise.reject(err);
})
export default service
3.9、引入重置样式reset.css
html,
body,
p,
ol,
ul,
li,
dl,
dt,
dd,
blockquote,
figure,
fieldset,
legend,
textarea,
pre,
iframe,
hr,
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0;
padding: 0;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-size: 100%;
font-weight: normal;
}
ul {
list-style: none;
}
button,
input,
select {
margin: 0;
}
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
img,
video {
height: auto;
max-width: 100%;
}
iframe {
border: 0;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
td,
th {
padding: 0;
}
3.10、一起引入到main.ts
import { createApp } from "vue";
import App from "./App.vue";
import './styles/index.css'
import router from './router/index'
import pinia from "./store";
const app=createApp(App)
app.use(router)
app.use(pinia)
app.mount("#app")
四、package.json
4.1、包的下载
"dependencies": {
"axios": "^1.6.7",
"element-plus": "^2.5.3",
"nprogress": "^0.2.0",
"pinia": "^2.1.7",
"pinia-plugin-persistedstate": "^3.2.1",
"vue": "^3.4.15",
"vue-router": "^4.2.5"
},
"devDependencies": {
"@types/node": "^20.11.10",
"@types/nprogress": "^0.2.3",
"@vitejs/plugin-vue": "^5.0.3",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"less": "^4.2.0",
"typescript": "^5.3.3",
"vite": "^5.0.12",
"vue-tsc": "^1.8.27"
}
4.2、脚本的配置
"dev": "vite --mode dev",
"dev:test": "vite --mode test",
"dev:stg": "vite --mode stg",
"dev:prod": "vite --mode prod",
"build": "vite build --mode dev",
"build:test": "vite build --mode test",
"build:stg": "vite build --mode stg",
"build:prod": "vite build --mode prod"