1、检查是否安装pnpm (默认npm安装成功的情况下,也就是安装了node)
pnpm --version
当前是安装成功

a)、如果有安装的
Ⅰ、pnpm create vite
Ⅱ、
√ Project name: ... web_student // 直接输入你的项目名 注意命名规则
√ Select a framework: » Vue // 上下键选中vue即可
√ Select a variant: » TypeScript // 语言中选择ts
Scaffolding project in D:\project\2024\2024-11\2024-11-20\web_student...
Done. Now run:
cd web_student //进入项目以后
pnpm install // 下载项目依赖
pnpm run dev // 启动项目
D:\project\2024\2024-11\2024-11-20>
b)、如果没有安装
Ⅰ、查看npm的下载源
npm config get registry
Ⅱ、修改npm的下载源 (因为默认指向的是 国外的下载地址,指向淘宝下载地址,下载速度就会很快)
npm config set registry https://registry.npmmirror.com/
Ⅲ、下载pnpm
npm i -g pnpm
2、配置一下npm启动的时候 默认浏览器
{
"name": "web_student",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite --open", // --open 配置项目启动项
"build": "vue-tsc -b && vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.5.12"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.1.4",
"typescript": "~5.6.2",
"vite": "^5.4.10",
"vue-tsc": "^2.1.8"
}
}
3、在 Vue 3 和 Vite 项目中,你可以通过配置 vite.config.ts 文件来设置 @ 作为路径别名(Alias),用于引用 src 目录中的文件。这样可以简化导入路径,让代码更简洁和可维护。
a)完整示例:以下是一个完整的 vite.config.ts 配置示例:
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
// https://vite.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"), // 配置 @ 指向 src 目录
}, // __dirname 会报红需要使用pnpm 下载 npm install @types/node --save-dev
},
});
b)测试使用 当前目录结构

当前 Water.vue

当前使用 water组件
import Water from "@/components/Water.vue";

4、安装Element-plus,我使用的是 pnpm,并且顺便将 element-plus/icons一起引入
pnpm install element-plus @element-plus/icons-vue
a)配置Volar 支持
如果您使用 Volar,请在根目录下 tsconfig.json 中通过 compilerOptions.type 指定全局组件类型
// tsconfig.json
{
"compilerOptions": {
// ...
"types": ["element-plus/global"]
}
}
b)配置按需自动导入
首先你需要安装 unplugin-vue-components 和 unplugin-auto-import 这两款插件
pnpm install -D unplugin-vue-components unplugin-auto-import
c) 然后把下列代码插入到根目录下 vite.config.ts 文件中
import { defineConfig } from 'vite'
// 以下三项引入是为配置Element-plus自动按需导入
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
// ...
plugins: [
// 以下两项是为配置Element-plus自动按需导入
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
})
d)验证是否成功
Element-lus官网:https://element-plus.gitee.io/zh-CN/component/button.html
打开 Element-plus 官网吗,复制一点儿 el-button相关代码进 App.vue文件
// 这是 src目录下的 App.vue 文件
<script lang="ts" setup></script>
<template>
<div>
<h1>App页面</h1>
<el-row class="mb-4">
<el-button>Default</el-button>
<el-button type="primary">Primary</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">Info</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>
</el-row>
</div>
</template>
<style lang="scss" scoped></style>
e打开页面查看,成功展示相关组件,且控制台无报错,至此自动按需导入配置完成
5、配置项目中vue的自动引入 vue3 import { ref , ... } 引入繁琐问题
a)下载依赖
pnpm i unplugin-auto-import -D
b)修改配置vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
// 以下三项引入是为配置Element-plus自动按需导入
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(), // 以下两项是为配置Element-plus自动按需导入
AutoImport({
resolvers: [ElementPlusResolver()],
// 自动引入vue pinia 等
imports: ["vue", "vue-router", "pinia"],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"), // 配置 @ 指向 src 目录
},
},
});
c) 全部都配置好了 可是vscode报红

d)解决报红 找到tsconfig.json 添加一行配置 这样就可以了


e) 解决完成以后
6、配置eslintrc.cjs
D:\project\2024\2024-11\2024-11-20\web_student>pnpm i eslint -D // 下载eslint
Packages: +78
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 235, reused 175, downloaded 20, added 78, done
devDependencies:
+ eslint 9.15.0
Done in 8.3s
D:\project\2024\2024-11\2024-11-20\web_student>npx eslint --init // 安装 eslint 配置项
You can also run this command directly using 'npm init @eslint/config@latest'.
Need to install the following packages:
@eslint/create-config@1.4.0
Ok to proceed? (y) y // 是否要去下载 @eslint/create-config@1.4.0 是的
@eslint/create-config: v1.4.0
√ How would you like to use ESLint? · problems // 用eslint 发现并且提示问题
√ What type of modules does your project use? · esm // 项目使用过的类型
√ Which framework does your project use? · vue // 是否选择vue 是的
√ Does your project use TypeScript? · typescript // 是否使用ts 是的
√ Where does your code run? · browser // 是否在浏览器中使用 是的
The config that you've selected requires the following dependencies: //您选择的配置需要以下依赖项 同意就行
eslint, globals, @eslint/js, typescript-eslint, eslint-plugin-vue
√ Would you like to install them now? · No / Yes // 是否现在就下载
√ Which package manager do you want to use? · pnpm // 使用pnpm 进行下载就行
☕️Installing...
Packages: +24
++++++++++++++++++++++++
Progress: resolved 259, reused 208, downloaded 11, added 24, done
devDependencies:
+ @eslint/js ^9.15.0
+ eslint-plugin-vue 9.31.0
+ globals 15.12.0
+ typescript-eslint 8.15.0
Done in 7.2s
Successfully created D:\project\2024\2024-11\2024-11-20\web_student\eslint.config.js file.
a) 完成以上的步骤以后会生成 eslint.config.js 文件 这个是eslint9 以后的版本(我也找了很多资料最后在github中拔了一个项目以后才配置好的)
eslint.config.js 的配置 具体如下
// import globals from "globals";
// 预定义配置
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
import pluginVue from "eslint-plugin-vue";
// import babelParser from "@typescript-eslint/parser";
import commpnParser from "vue-eslint-parser";
import prettier from "eslint-plugin-prettier";
import babelEslintParser from "@babel/eslint-parser";
import { readFile } from "node:fs/promises";
// 配置文件自动引入的问题 报红的问题
const autoImport = JSON.parse(
await readFile(new URL("./.eslintrc-auto-import.json", import.meta.url))
);
// "@babel/eslint-parser";
// import customConfig from "./esconfig/custom_config.js";
export default [
// languageOptions:配置如何检查 js 代码
{
// 1.1 处理 与 JavaScript 相关的配置项
// - ecmaVersion
// - sourceType
// - globals
// - parser
// - parserOptions
// files: ["**/*.ts", "**/*.vue"],
// ignores: ["**/*.config.js"],
ignores: [
"**/*.config.js",
"dist/**",
"node_modules/**",
"!**/eslint.config.js",
"auto-imports.d.ts",
"components.d.ts",
],
languageOptions: {
// 1.11 定义可用的全局变量
globals: {
...autoImport.globals,
},
// 1.12 扩展
// ecmaVersion: "latest",
// sourceType: "module",
parser: commpnParser,
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
parser: "@typescript-eslint/parser",
jsxPragma: "React",
ecmaFeatures: {
jsx: true,
},
},
},
},
// 原来的extends替换为如下模式
pluginJs.configs.recommended, // eslint 推荐格则
...tseslint.configs.recommended,
...pluginVue.configs["flat/essential"],
{
plugins: {
prettier,
babelEslintParser,
},
rules: {
// 开启这条规则后,会将prettier的校验规则传递给eslint,这样eslint就可以按照prettier的方式来进行代码格式的校验
"prettier/prettier": "off",
// eslint(https://eslint.bootcss.com/docs/rules/)
"no-var": "error", // 要求使用 let 或 const 而不是 var
"no-multiple-empty-lines": ["warn", { max: 1 }], // 不允许多个空行
"no-unexpected-multiline": "error", // 禁止空余的多行
"no-useless-escape": "off", // 禁止不必要的转义字符
// typeScript (https://typescript-eslint.io/rules)
"@typescript-eslint/no-unused-vars": "error", // 禁止定义未使用的变量
"@typescript-eslint/prefer-ts-expect-error": "error", // 禁止使用 @ts-ignore
"@typescript-eslint/no-explicit-any": "off", // 禁止使用 any 类型
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-namespace": "off", // 禁止使用自定义 TypeScript 模块和命名空间。
"@typescript-eslint/semi": "off",
// eslint-plugin-vue (https://eslint.vuejs.org/rules/)
"vue/multi-word-component-names": "off", // 要求组件名称始终为 “-” 链接的单词
"vue/script-setup-uses-vars": "error", // 防止<script setup>使用的变量<template>被标记为未使用
"vue/no-mutating-props": "off", // 不允许组件 prop的改变
"vue/attribute-hyphenation": "off", // 对模板中的自定义组件强制执行属性命名样式
},
},
];
b) 启动项配置 pageckage.json
{
"name": "web_student",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite --open",
"build": "vue-tsc -b && vite build",
"preview": "vite preview",
"lint": "eslint src",
"fix": "eslint src --fix"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"element-plus": "^2.8.8",
"vue": "^3.5.12"
},
"devDependencies": {
"@babel/eslint-parser": "^7.25.9",
"@eslint/compat": "^1.2.3",
"@eslint/js": "^9.15.0",
"@types/node": "^22.9.1",
"@vitejs/plugin-vue": "^5.1.4",
"eslint": "^9.15.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-vue": "^9.31.0",
"globals": "^15.12.0",
"typescript": "~5.6.2",
"typescript-eslint": "^8.15.0",
"unplugin-auto-import": "^0.18.5",
"unplugin-vue-components": "^0.27.4",
"vite": "^5.4.10",
"vue-tsc": "^2.1.8"
}
}
c) tsconfig.json 配置这个可以@别名的问题
{
"compilerOptions": {
"target": "ESNext",
"jsx": "preserve",
"lib": ["DOM", "ESNext"],
"baseUrl": ".",
"module": "ESNext",
"moduleResolution": "node",
"paths": {
"~/*": ["src/*"],
"@/*": ["src/*"]
},
"resolveJsonModule": true,
"types": [],
"allowJs": true,
"strict": true,
"strictNullChecks": true,
"noUnusedLocals": true,
"importHelpers": true,
"outDir": "dist",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
},
"exclude": ["node_modules", "dist/**/*", "public/**/*"],
"vueCompilerOptions": {
"target": 3, // or 2.7 for Vue 2
"plugins": [
"@vue-macros/volar/define-props-refs",
"@vue-macros/volar/define-props"
]
}
}
这个时候 就可以 npm run fix 而且页面中别名引入和自动引入的爆红就可以解决
7、开始配置 全局的按需加载的echarts了
a) 下载 echarts
pnpm i echarts -S

b) src 中放 utils 文件夹 utils中放echarts.ts 文件
// 引入 echarts 核心模块。
import * as echarts from "echarts/core";
//引入柱状图和折线图组件。
import { BarChart, LineChart } from "echarts/charts";
// // 引入标题、提示框、网格、数据集和数据转换器组件。
import {
TitleComponent,
TooltipComponent,
GridComponent,
// 数据集组件
DatasetComponent,
// 内置数据转换器组件 (filter, sort)
TransformComponent,
// 坐标轴的值
LegendComponent,
ToolboxComponent,
MarkLineComponent,
} from "echarts/components";
// //引入标签布局和通用过渡动画特性。
// import { LabelLayout, UniversalTransition } from 'echarts/features';
// // 引入 Canvas 渲染器。
import { CanvasRenderer } from "echarts/renderers";
import type {
// 系列类型的定义后缀都为 SeriesOption
BarSeriesOption,
LineSeriesOption,
} from "echarts/charts";
import type {
// 组件类型的定义后缀都为 ComponentOption
TitleComponentOption,
TooltipComponentOption,
GridComponentOption,
DatasetComponentOption,
} from "echarts/components";
import type { ComposeOption } from "echarts/core";
// 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型
type ECOption = ComposeOption<
| BarSeriesOption
| LineSeriesOption
| TitleComponentOption
| TooltipComponentOption
| GridComponentOption
| DatasetComponentOption
>;
/**
注册必须的组件,包括标题、提示框、网格、数据集、数据转换器,
以及柱状图、折线图、标签布局、通用过渡动画和 Canvas 渲染器。
*/
echarts.use([
TitleComponent,
TooltipComponent,
GridComponent,
DatasetComponent,
TransformComponent,
BarChart,
LineChart,
// LabelLayout,
// UniversalTransition,
LegendComponent,
ToolboxComponent,
CanvasRenderer,
MarkLineComponent,
]);
// 导出
export default echarts;
c) main.ts 文件中进行全局引入
import { createApp } from "vue";
import "./style.css";
import App from "./App.vue";
//引入创建的echarts.ts文件
import echarts from "@/utils/echart";
const app = createApp(App);
// 全局配置
app.provide("$echarts", echarts);
app.mount("#app");
d) 直接使用echarts图表 Chart.vue
<script setup lang="ts">
const chartNode = ref<HTMLDivElement>();
const ECharts: any = inject("$echarts");
onMounted(() => {
const myChart = ECharts.init(chartNode.value);
const option = {
title: {
text: "Temperature Change in the Coming Week",
},
tooltip: {
trigger: "axis",
},
legend: {},
toolbox: {
show: true,
feature: {
dataZoom: {
yAxisIndex: "none",
},
dataView: { readOnly: false },
magicType: { type: ["line", "bar"] },
restore: {},
saveAsImage: {},
},
},
xAxis: {
type: "category",
boundaryGap: false,
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
},
yAxis: {
type: "value",
axisLabel: {
formatter: "{value} °C",
},
},
series: [
{
name: "Highest",
type: "line",
data: [10, 11, 13, 11, 12, 12, 9],
markPoint: {
data: [
{ type: "max", name: "Max" },
{ type: "min", name: "Min" },
],
},
markLine: {
data: [{ type: "average", name: "Avg" }],
},
},
{
name: "Lowest",
type: "line",
data: [1, -2, 2, 5, 3, 2, 0],
markPoint: {
data: [{ name: "周最低", value: -2, xAxis: 1, yAxis: -1.5 }],
},
markLine: {
data: [
{ type: "average", name: "Avg" },
[
{
symbol: "none",
x: "90%",
yAxis: "max",
},
{
symbol: "circle",
label: {
position: "start",
formatter: "Max",
},
type: "max",
name: "最高点",
},
],
],
},
},
],
};
myChart.setOption(option);
window.addEventListener("resize", () => {
myChart.resize();
});
});
</script>
<template>
<div class="chart" id="test" ref="chartNode"></div>
</template>
<style scoped>
.chart {
width: 50vw;
height: 50vh;
border: 1px solid #000;
}
</style>
e) app.vue开始用
<script setup lang="ts">
import Chart from "@/components/Chart.vue";
import Water from "@/components/Water.vue";
</script>
<template>
<Chart />
<Water></Water>
</template>
<style scoped>
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vue:hover {
filter: drop-shadow(0 0 2em #42b883aa);
}
</style>
页面中实际使用效果

8)配置反向代理
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
// 以下三项引入是为配置Element-plus自动按需导入
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
// https://vite.dev/config/
export default defineConfig({
server: {
host: "0.0.0.0",
port: 3000,
proxy: {
"/base": {
target: "https://xxxx",
changeOrigin: true, // 是否改变源地址
// secure: false,
rewrite: (path) => path.replace(/^\/base/, ""),
},
"/get": {
target: "https:xxxxx",
changeOrigin: true, // 是否改变源地址
// secure: false,
rewrite: (path) => path.replace(/^\/get/, ""),
},
},
},
plugins: [
vue(), // 以下两项是为配置Element-plus自动按需导入
AutoImport({
resolvers: [ElementPlusResolver()],
// 自动引入vue pinia 等
imports: ["vue", "vue-router", "pinia"],
eslintrc: {
enabled: false,
filepath: "./.eslintrc-auto-import.json",
globalsPropValue: true,
},
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"), // 配置 @ 指向 src 目录
},
},
});
9)配置生产依赖项和开发依赖项 主要就是接口这块的配置
开发接口配置 .env.development
VITE_APP_BASE_API = /
VITE_APP_BASE_API_WATER = '/base'
VITE_APP_BASE_API_SIMULATION = '/get'
生产接口的配置 .env.production
VITE_APP_BASE_API='/'
VITE_APP_BASE_API_WATER = '/old'
VITE_APP_BASE_API_SIMULATION = ''
api 接口的配置
下载 axios pnpm i axios -S

useApi 下的 index.ts
import type { AxiosRequestConfig } from 'axios'
import axios from 'axios'
import { ElMessage } from 'element-plus'
enum RequestEnums {
TIMEOUT = 60000,
FAIL = 500, // 请求失败
SUCCESS = 200 // 请求成功
}
export interface Response<T = any> {
code: number
data: T
message: string
success: boolean
}
export default function useApi(
prefix?: string,
headers?: {
[key: string]: any
}
) {
const http = axios.create({
timeout: RequestEnums.TIMEOUT,
headers: {
'Content-Type': 'application/json;charset=utf-8',
...(headers || {})
},
baseURL: prefix
})
http.interceptors.response.use((res: any) => {
if (res.status === RequestEnums.SUCCESS) {
if (res.data.code != RequestEnums.SUCCESS) {
ElMessage.error(res.data.message)
throw res
}
return res
} else {
throw res
}
})
http.interceptors.request.use((req: any) => {
if (req.headers['Content-Type'] === 'x-www-form-urlencoded') {
const formData = new FormData()
Object.keys(req.data).map((i) => {
formData.set(i, req.data[i])
})
req.data = formData
}
return req
})
return {
...http,
get<T = any>(url: string, params?: any, config?: AxiosRequestConfig<any>) {
return http
.get<Response<T>>(url, {
...config,
params
})
.then((res: any) => res.data)
},
post<T = any>(url: string, params?: any, config?: AxiosRequestConfig<any>) {
return http.post<Response<T>>(url, params, config).then((res: any) => res.data)
},
delete<T = any>(url: string, params?: any, config?: AxiosRequestConfig<any>) {
return http
.delete<Response<T>>(url, {
...config,
params
})
.then((res: any) => res.data)
},
put<T = any>(url: string, params?: any, config?: AxiosRequestConfig<any>) {
return http.put<Response<T>>(url, params, config).then((res: any) => res.data)
}
}
}
simulativeModeling.ts 文件
import useApi from './useApi'
const { VITE_APP_BASE_API_SIMULATION } = import.meta.env
const request = useApi()
/**
* @description 初始化当前的工况
*/
export const getConditionDataApi = (params: { code: string }) => {
return request.get(`${VITE_APP_BASE_API_SIMULATION}/base/ioc/queryPointLatestData`, params)
925





