1. 依赖配置
1.1. Vue-Router
/src/config/route/index.ts
import { createRouter, createWebHistory } from 'vue-router';
const route = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
name: 'index',
redirect: '/index',
component: () => import('@/components/index.vue'),
children: []
}
]
});
export default route;
- history: 可填写createWebHistory()和createWebHistory(),表象区别在于跳转时URL是否携带”#“,并且createWebHistory需要Nginx转发。
- routes: 组件路由声明,如路径、名称、重定向、组件、子路由信息等等。
/src/App.vue
<template>
<router-view />
</template>
1.2. Vuex
/src/plugins/store/index.ts
import Vuex from 'vuex';
export default new Vuex.Store({
state: {
"key":"value"
},
mutations: {
change(state, value){
state.key = value;
}
},
});
- state: 声明参数。
- mutations: 声明参数改变方法(只能通过该方法)
1.3. Axios
/src/plugins/axios/index.ts
import axios from 'axios';
const instance = axios.create({
// 接口域名
baseURL: import.meta.env.BASE_URL,
// 超时时限
timeout: 6000,
// 请求头
headers: {
'Content-Type': 'application/json;charset=UTF-8;',
},
});
// 请求拦截
instance.interceptors.request.use(
(config) => config,
(error) => Promise.reject(error)
);
// 响应拦截
instance.interceptors.response.use(
(response: any) => {},
(error) => Promise.reject(error)
);
export default instance;
1.4. Element-Plus
/src/config/ui/index.ts
import { App } from 'vue';
import {ElAlert,ElAffix,ElAside,ElAutocomplete,ElAvatar,ElBacktop,ElBadge,ElBreadcrumb,ElBreadcrumbItem,ElButton,ElButtonGroup,ElCalendar,ElCard,ElCarousel,ElCarouselItem,ElCascader,ElCascaderPanel,ElCheckbox,ElCheckboxButton,ElCheckboxGroup,ElCol,ElCollapse,ElCollapseItem,ElCollapseTransition,ElColorPicker,ElContainer,ElDatePicker,ElDescriptions,ElDescriptionsItem,ElDialog,ElDivider,ElDrawer,ElDropdown,ElDropdownItem,ElDropdownMenu,ElFooter,ElForm,ElFormItem,ElHeader,ElIcon,ElImage,ElInput,ElInputNumber,ElLink,ElMain,ElMenu,ElMenuItem,ElMenuItemGroup,ElOption,ElOptionGroup,ElPageHeader,ElPagination,ElPopconfirm,ElPopover,ElPopper,ElProgress,ElRadio,ElRadioButton,ElRadioGroup,ElRate,ElResult,ElRow,ElScrollbar,ElSelect,ElSelectV2,ElSlider,ElStep,ElSteps,ElSubMenu,ElSwitch,ElTabPane,ElTable,ElTableColumn,ElTabs,ElTag,ElTimePicker,ElTimeSelect,ElTimeline,ElTimelineItem,ElTooltip,ElTransfer,ElTree,ElUpload,ElInfiniteScroll,ElLoading,ElMessage,ElMessageBox,ElNotification} from 'element-plus';
import * as ElementPlusIcons from '@element-plus/icons-vue';
const components = [ElAlert,ElAffix,ElAside,ElAutocomplete,ElAvatar,ElBacktop,ElBadge,ElBreadcrumb,ElBreadcrumbItem,ElButton,ElButtonGroup,ElCalendar,ElCard,ElCarousel,ElCarouselItem,ElCascader,ElCascaderPanel,ElCheckbox,ElCheckboxButton,ElCheckboxGroup,ElCol,ElCollapse,ElCollapseItem,ElCollapseTransition,ElColorPicker,ElContainer,ElDatePicker,ElDescriptions,ElDescriptionsItem,ElDialog,ElDivider,ElDrawer,ElDropdown,ElDropdownItem,ElDropdownMenu,ElFooter,ElForm,ElFormItem,ElHeader,ElIcon,ElImage,ElInput,ElInputNumber,ElLink,ElMain,ElMenu,ElMenuItem,ElMenuItemGroup,ElOption,ElOptionGroup,ElPageHeader,ElPagination,ElPopconfirm,ElPopover,ElPopper,ElProgress,ElRadio,ElRadioButton,ElRadioGroup,ElRate,ElResult,ElRow,ElScrollbar,ElSelect,ElSelectV2,ElSlider,ElStep,ElSteps,ElSubMenu,ElSwitch,ElTabPane,ElTable,ElTableColumn,ElTabs,ElTag,ElTimePicker,ElTimeSelect,ElTimeline,ElTimelineItem,ElTooltip,ElTransfer,ElTree,ElUpload,ElInfiniteScroll,ElLoading,ElMessage,ElMessageBox,ElNotification];
const plugins = [ElInfiniteScroll,ElLoading,ElMessage,ElMessageBox,ElNotification];
export const ElementPlus = {
install: (app: App<Element>): void => {
// 组件
components.forEach((component) => {
app.component(component.name, component);
});
// 图标
for (const [key, component] of Object.entries(ElementPlusIcons)) {
app.component(key, component);
}
// 插件
plugins.forEach((plugin) => {
app.use(plugin);
});
},
};
1.5. Echarts
/src/plugins/echarts/echarts.vue
安装guid-typescript(创建唯一标识)
npm install guid-typescript
<template>
<div :style="{ height: height }" :id="id"></div>
</template>
<script lang="ts" setup>
import { onMounted, watch } from "vue";
import * as Echarts from "echarts";
import { Guid } from "guid-typescript";
const { height, option } = defineProps({
height: {
type: String,
required: false,
default: () => '300px'
},
option: {
type: Object,
required: true,
default: () => { }
}
});
// Id
const id = Guid.create().toString();
onMounted(() => {
const element = document.getElementById(id);
if (!element) {
throw new Error('Element is not defined');
}
const chart = Echarts.init(element);
chart.setOption(option);
// 窗口大小改变
window.onresize = () => chart.resize();
});
</script>
2. 系统配置
2.1. vite.config.ts
安装vite-plugin-style-import加载ELement-Plus CSS
npm install vite-plugin-style-import
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
import {
createStyleImportPlugin,
ElementPlusResolve,
} from 'vite-plugin-style-import';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
createStyleImportPlugin({
resolves: [ElementPlusResolve()], // vite2(新),配置更少
}),
],
server: {
host: '0.0.0.0', //解决“vite use `--host` to expose”
port: 80,
open: true,
proxy: {
'/api': {
target: '', // 目标地址
changeOrigin: true,
secure: false,
rewrite: (path) => path.replace('/api/', '/'),
},
},
},
resolve: {
alias: [
{
find: '@',
replacement: resolve(__dirname, 'src'),
},
],
},
});
2.2. tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"baseUrl": "./",
"paths": {
"@": ["src"],
"@/*": ["src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
}
- paths: 解决编译器警告不识别自定标签的路径问题。
- 其他: 略。
2.3. main.ts
/src/main.ts
import { createApp } from 'vue';
import App from './App.vue';
import Route from './config/route';
import { ElementPlus } from './config/ui';
import lang from 'element-plus/lib/locale/lang/zh-cn';
import 'dayjs/locale/zh-cn';
import 'element-plus/theme-chalk/src/base.scss';
// 1.路由; 2.UI&语言;
createApp(App).use(Route).use(ElementPlus, { lang }).mount('#app');
3. 目录结构
├── public
│ └── favicon.ico
├── src
│ ├── assets
│ ├── components
│ │ └── Index.vue
│ ├── config
│ │ ├── route
│ │ │ └── index.ts
│ │ └── ui
│ │ └── index.ts
│ ├── plugins
│ │ ├── axios
│ │ │ └── index.ts
│ │ ├── echarts
│ │ │ └── echarts.vue
│ │ └── store
│ │ └── index.ts
│ ├── App.vue
│ ├── env.d.ts
│ └── main.ts
├── index.html
├── package-lock.json
├── package.json
├── README.md
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts