五.路由
执行下列命令安装依赖
pnpm i vue-router@4
在 src 新新建目录 router ,并新建 index.ts 文件, 内容如下:
import { RouteRecordRaw, createRouter, createWebHashHistory } from 'vue-router'
const modules = import.meta.glob('../views/**/**.vue')
const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'Login',
component: modules['../views/login/index.vue']
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
// 原来的 import 路由懒加载在开发环境可行,在生产环境不可行,故改为上面
// import.meta.glob 形式
修改入口文件main.ts
import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import router from './router'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.use(router).use(ElementPlus).mount('#app')
注意: 在App.vue 中添加路由出口
至此,路由的基本配置已经完成,更多配置信息,详见官网:router.vuejs.org/zh/guide/
六.统一封装请求 (axios)
执行下列命令安装依赖
pnpm i axios
pnpm i qs -D
pnpm i @types/qs -D
在 src 下新建目录 utils,并新建文件 http.ts,内容如下:
import axios, { AxiosResponse, AxiosRequestConfig } from 'axios'
import qs from 'qs'
/**
* 业务自定义状态码
* 1000 请求成功
* 5000 重定向
* 5002 重定向+提示(token获取失败)
* 5003 cookie中缺失appKey
* 5004 用户被拉入黑名单
* 4003 未授权
*/
// axios声明合并,在axios的配置项AxiosRequestConfig接口定义中自定义新值
declare module 'axios' {
export interface AxiosRequestConfig {
/**
* @description 设置为false,表示请求错误是用户自定义处理(true)还是全局处理(false)
*/
customError?: boolean
}
}
// 创建axios实例,此时的content-type已指定为json,如需使用form-data,请自行修改
const http = axios.create({
timeout: 10000,
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
// 表示跨域请求时是否需要使用凭证
withCredentials: true,
validateStatus(status) {
return status === 200 // 自定义状态码范围
},
paramsSerializer(params) {
// 序列化请求参数,避免get请求参数出现[],&,空格等识别错误的问题
return qs.stringify(params, { arrayFormat: 'brackets' })
},
transformRequest: [
data => {
// 转化为正常的json
data = JSON.stringify(data)
return data
}
]
})
// 请求拦截
http.interceptors.request.use(
(config: AxiosRequestConfig) => {
// do something
return config
},
(error: any) => {
Promise.reject(error)
}
)
// 响应拦截
http.interceptors.response.use(
async (response: AxiosResponse) => {
return Promise.reject(response)
},
(error: any) => {
// do something
return Promise.reject(error)
}
)
export default http
在请求拦截和响应拦截根据自己的需求加以修,之后在发请求时,可以直接运用以上封装的工具函数.
七.状态管理pinia
安装
pnpm i pinia@next
pnpm i pinia-plugin-persist 持久化插件
在 src 下新增 store 文件夹, 接着在 store 中新增 index.ts 文件,内容如下:
import type { App } from 'vue'
import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'
const store = createPinia()
store.use(piniaPluginPersist) //使用插件持久化
export function setupStore(app: App<Element>) {
app.use(store)
}
export default store
并在入口文件下 main.ts 中增加
import store from './store'
app.use(store)
pinia 基本已经配置完毕,如何使用可以参考官网: pinia.web3doc.top/introductio…
八.vue3中使用echarts图表
安装
pnpm i echarts
使用方式如下所示:
<!-- 线 + 柱混合图 -->
<template>
<div id="poy-charts" style="height: 200px; width: 300px" />
</template>
<script setup lang="ts">
import { nextTick, onMounted } from 'vue'
// 引入 echarts
import { init, EChartsOption } from 'echarts'
import * as echarts from 'echarts'
// const { mounted, chart, beforeDestroy, activated, deactivated } = resize()
// 初始化图表
function initChart() {
const barChart = init(document.getElementById('poy-charts') as HTMLDivElement)
barChart.setOption({
title: {
show: true,
text: '业绩总览',
x: 'center',
padding: 15,
textStyle: {
fontSize: 18,
fontStyle: 'normal',
fontWeight: 'bold',
color: '#337ecc'
}
},
grid: {
left: '2%',
right: '2%',
bottom: '10%',
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
}
},
legend: {
x: 'center',
y: 'bottom',
data: ['收入', '毛利润', '收入增长率', '利润增长率']
},
xAxis: [
{
type: 'category',
data: ['浙江', '北京', '上海', '广东', '深圳'],
axisPointer: {
type: 'shadow'
}
}
],
yAxis: [
{
type: 'value',
min: 0,
max: 10000,
interval: 2000,
axisLabel: {
formatter: '{value} '
}
},
{
type: 'value',
min: 0,
max: 100,
interval: 20,
axisLabel: {
formatter: '{value}%'
}
}
],
series: [
{
name: '收入',
type: 'bar',
data: [7000, 7100, 7200, 7300, 7400],
barWidth: 20,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#83bff6' },
{ offset: 0.5, color: '#188df0' },
{ offset: 1, color: '#188df0' }
])
}
},
{
name: '毛利润',
type: 'bar',
data: [8000, 8200, 8400, 8600, 8800],
barWidth: 20,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#25d73c' },
{ offset: 0.5, color: '#1bc23d' },
{ offset: 1, color: '#179e61' }
])
}
},
{
name: '收入增长率',
type: 'line',
yAxisIndex: 1,
data: [60, 65, 70, 75, 80],
itemStyle: {
color: '#67C23A'
}
},
{
name: '利润增长率',
type: 'line',
yAxisIndex: 1,
data: [70, 75, 80, 85, 90],
itemStyle: {
color: '#409EFF'
}
}
]
} as EChartsOption)
}
// 页面挂载时初始化图表
onMounted(() => {
nextTick(() => {
initChart()
})
})
</script>