路由映射、动态路由、记住密码、权限管理
vue文件类型声明 env.d.ts
/// <reference types="vite/client" />
declare module "*.vue" {
import {DefineComponent} from "vue";
const component: DefineComponent
export default component
}
集成editorconfig文件,有助于不同的编辑器来保持统一的代码风格
vscode需要安装EditorConfig for VS Code插件
安装代码格式化工具npm install pretter -d
样式重构npm install normalizee.css
vite提供的环境变量:
let BASE_URL = 'http://codercba.com:8000'
const TIME_OUT = 10000
if (import.meta.env.DEV === 'development') {
BASE_URL = '开发环境ip'
} else if (import.meta.env.PROD === 'production') {
BASE_URL = '生产环境ip'
} else {
BASE_URL = '测试环境ip'
}
配置忽略文件:
"include": ["env.d.ts", "src/**/*", "src/**/*.vue","auto-imports .d.ts", "components .d.ts"]
强制清除本地包npm cachae clear --force
父组件点击执行子组件的函数
// 子组件导出函数
defineExpose({
loginActives
})
拿一个元素的实例
const accountRef = ref<InstanceType<typeof Account>>()
form通过验证
const formRef = ref<InstanceType<typeof ElForm>>()
const loginStore = useLoginStore()
function loginActives() {
formRef.value?.validate((valid) => {
if (valid) {
const name = account.name
const password = account.password
loginStore.loginAccountAction({name,password})
} else {
ElMessage.error('请输入正确的格式在操作')
}
})
}
动态组件
<component :is="item.icon.split('el-icon-')[1]">
将事件和状态传递给父组件
const emits = defineEmits(['foldChange'])
emits('foldChange',isFold.value)
重置操作
const formRef = ref<InstanceType<typeof ElForm>>()
function handleResetChange() {
formRef.value?.resetFields()
}
表单插槽
storeToRefs
当数据发生改变结构出来的数据是响应式的
import { storeToRefs } from 'pinia'
const { userList } = storeToRefs(systemStore)
时间格式化
导航守卫
// to:跳转的位置 from:从哪里跳转过来 返回值:决定导航的路径
router.beforeEach((to, from) => {
const token = localCache.getCache(LOGIN_TOKEN)
if (to.path === '/Home' && !token) {
// 登陆成功进入home页面
return '/login'
}
})
封装axios
serves -> index.ts
import HYRequest from './request'
import { BASE_URL1, TIME_OUT1 } from './config'
import { localCache } from '@/utils/cache'
const hyRequest = new HYRequest({
baseURL: BASE_URL1,
timeout: TIME_OUT1,
interceptors: {
requestInterceptor: (config) => {
const token = localCache.getCache('token')
if (token && config.headers) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
requestInterceptorCatch: (err) => {
return err
},
responseInterceptor: (res) => {
return res
},
responseInterceptorCatch: (err) => {
return err
}
}
})
export default hyRequest
serves -> config -> index.ts
export const BASE_URL1 = 'http://152.136.185.210:5000'
export const TIME_OUT1 = 10000
serves -> request -> index.ts
import axios from 'axios'
import type {AxiosInstance, AxiosRequestConfig, AxiosResponse} from 'axios'
interface HYInstanceInterceptors<T = AxiosResponse> {
requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig
requestInterceptorCatch?: (err: any) => any
responseInterceptor?: (res: T) => T
responseInterceptorCatch?: (err: any) => any
}
interface HYRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
interceptors?: HYInstanceInterceptors<T>
}
class HYRequest {
instance: AxiosInstance
constructor(config: HYRequestConfig) {
this.instance = axios.create(config)
// 全局的拦截器
this.instance.interceptors.request.use(
(config) => {
return config
},
(err) => {
return err
}
)
this.instance.interceptors.response.use(
(res) => {
return res.data
},
(err) => {
return err
}
)
// 实例的拦截器
this.instance.interceptors.request.use(
config.interceptors?.requestInterceptor,
config.interceptors?.requestInterceptorCatch
)
this.instance.interceptors.response.use(
config.interceptors?.responseInterceptor,
config.interceptors?.responseInterceptorCatch
)
}
request<T = any>(config: HYRequestConfig<T>) {
if (config.interceptors?.requestInterceptor) {
config = config.interceptors.requestInterceptor(config)
}
return new Promise<T>((resolve, reject) => {
this.instance
.request<any, T>(config)
.then((res) => {
if (config.interceptors?.responseInterceptor) {
res = config.interceptors.responseInterceptor(res)
}
resolve(res)
})
.catch((err: any) => {
if (config.interceptors?.responseInterceptorCatch) {
err = config.interceptors.responseInterceptorCatch(err)
}
reject(err)
})
})
}
get<T = any>(config: HYRequestConfig<T>) {
return this.request<T>({...config, method: 'GET'})
}
post<T = any>(config: HYRequestConfig<T>) {
return this.request<T>({...config, method: 'POST'})
}
delete<T = any>(config: HYRequestConfig<T>) {
return this.request<T>({...config, method: 'DELETE'})
}
patch<T = any>(config: HYRequestConfig<T>) {
return this.request<T>({...config, method: 'PATCH'})
}
}
export default HYRequest
网络请求
serves -> login -> login.ts
import hyRequest from "@/serves";
export function accountLoginRequest(account:{ name: string, password: string }) {
return hyRequest.post({
url:'http://152.136.185.210:5000/login',
data:account
})
}
store -> login -> login.ts
import {defineStore} from "pinia";
import {accountLoginRequest} from "@/serves/login/login";
export const useLoginStore = defineStore('login', {
state:() => ({
id:'',
token:'',
name:''
}),
actions:{
async loginAccountAction(account:{ name: string, password: string }) {
const loginResult = await accountLoginRequest(account)
this.id = loginResult.data.id
}
}
})
// 使用
useLoginStore().loginAccountAction({name,password})
封装本地缓存
enum CacheType {
local = 'local',
session = 'session'
}
class WQCache {
storage: Storage
constructor(type: CacheType) {
this.storage = type === CacheType.local ? localStorage : sessionStorage
}
setCache(key: string, value: any) {
this.storage.setItem(key, JSON.stringify(value))
}
getCache(key: string) {
const value = this.storage.getItem(key)
if (value) {
return JSON.parse(value)
}
}
deleteCache(key: string) {
this.storage.removeItem(key)
}
clearCache() {
this.storage.clear()
}
}
const localCache = new WQCache(CacheType.local)
const sessionCache = new WQCache(CacheType.session)
export { localCache, sessionCache }