vite+vue3从0开始搭建一个后管项目【学习随记二】

创建项目安装插件可以去【学习随记一】看下

1.路由配置

javascript 复制代码
**文件路径是router/index.ts**
import { createRouter, createWebHistory } from 'vue-router'
import { UserStore, userMenu } from '@/pinia'
import routes from './routes'
import MainRouter from './MainRouter'

const router = createRouter({
	history: createWebHistory(),
	routes: [...routes, ...MainRouter]
})

router.beforeEach((to, from, next) => {
	const setUserMenu = userMenu()
	const userStore = UserStore()
	if (to.name !== 'login' && !userStore.token) {
		next({ name: 'login' })
	} else {
		if (to.name === 'login') {
			userStore.clearToken()
			userStore.clearUserInfo()
			setUserMenu.clearMenuList()
		}
		next()
	}
})
export default router
javascript 复制代码
const routes = [
	{
		path: '/login',
		name: 'login',
		component: () => import('@/views/system/login/index.vue')
	},
	{
		path: '/:pathMatch(.*)*',
		name: '404',
		component: () => import('@/views/system/error/index.vue')
	}
]

export default routes

2.axios的封装

javascript 复制代码
import axios from 'axios'
import { showLoading, hideLoading } from './loading'
import { ElMessage } from 'element-plus'
import { UserStore } from '@/pinia'
let errormessage = ''
declare module 'axios' {
	interface AxiosInstance {
		(config: AxiosRequestConfig): Promise<any>
	}
}
//创建axios的一个实例
const instance = axios.create({
	baseURL: import.meta.env.VITE_BASE_URL, //接口统一域名
	timeout: 5000, //设置超时
	headers: {
		Accept: 'application/json',
		'Content-Type': 'application/json;charset=utf-8'
	}
})

//请求拦截器
instance.interceptors.request.use(
	(config: any) => {
		showLoading({
			lock: true,
			text: '加载中',
			background: 'rgba(0, 0, 0, 0.7)'
		})
		// 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
		const userStore = UserStore()
		config.headers.token = userStore.token || ''
		return config
	},
	error => {
		setTimeout(() => {
			hideLoading()
		}, 200)
		ElMessage.error(error)
		Promise.reject(error)
	}
	// 对请求错误做些什么
)

//响应拦截器
instance.interceptors.response.use(
	response => {
		setTimeout(() => {
			hideLoading()
		}, 200)
		const res = response.data
		return res
	},
	error => {
		console.log(error, '----错误信息')
		//响应错误
		if (error.response && error.response.status) {
			const status = error.response.status
			switch (status) {
				case 400:
					errormessage = '请求错误'
					break
				case 401:
					errormessage = '请求错误'
					break
				case 404:
					errormessage = '请求地址出错'
					break
				case 408:
					errormessage = '请求超时'
					break
				case 500:
					errormessage = '服务器内部错误!'
					break
				case 501:
					errormessage = '服务未实现!'
					break
				case 502:
					errormessage = '网关错误!'
					break
				case 503:
					errormessage = '服务不可用!'
					break
				case 504:
					errormessage = '网关超时!'
					break
				case 505:
					errormessage = 'HTTP版本不受支持'
					break
				default:
					errormessage = '请求失败'
			}
			ElMessage.error(errormessage)
			setTimeout(() => {
				hideLoading()
			}, 200)
			return Promise.reject(error)
		}
		return Promise.reject(error)
	}
)

export default instance

3.使用pinia来存储用户token和用户信息

javascript 复制代码
**文件路径是pinia/modules/user/index.ts**

import { defineStore } from 'pinia'
const UserStore = defineStore('layout', {
	state: () => {
		return {
			token: '',
			userInfo: {} as any
		}
	},
	actions: {
		setToken(token) {
			this.token = token
		},
		setUserInfo(userInfo) {
			this.userInfo = userInfo
		},
		clearToken() {
			this.token = ''
		},
		clearUserInfo() {
			this.userInfo = ''
		}
	},
	persist: {
		enabled: true,
		strategies: [
			{ key: 'token', storage: sessionStorage, paths: ['token'] },
			{ key: 'userInfo', storage: sessionStorage, paths: ['userInfo'] }
		]
	}
})

export default UserStore
javascript 复制代码
**文件路径是pinia/index.ts**
import UserStore from './modules/user'
export { UserStore }

4.接口使用

接下来就是正常的接口调用了,先联调一个登录接口

html 复制代码
<template>
  <div class="card_body">
    <div class="login_form">
      <el-form
        :model="user"
        :rules="loginRules"
        ref="loginFormRef"
      >
        <el-form-item
          label="账号:"
          prop="account"
        >
          <el-input
            size="large"
            v-model="user.account"
            clearable
          />
        </el-form-item>
        <el-form-item
          label="密码:"
          prop="password"
        >
          <el-input
            size="large"
            v-model="user.password"
            show-password
            clearable
          />
        </el-form-item>
        <el-row
          class="Submit"
          type="flex"
          justify="center"
        >
          <el-button
            type="primary"
            @click="onSubmit"
          >登录</el-button>
        </el-row>
      </el-form>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { reactive, ref } from 'vue'
import type { FormRules } from 'element-plus'
import { useRouter } from 'vue-router'
import { UserStore } from '@/pinia'
import { setUserInfo } from '@/api/login'

interface LoginformState {
	account: string
	password: string
}

const router = useRouter()
const setUserStore = UserStore()

const loginFormRef = ref()
const user: LoginformState = reactive({
	account: '',
	password: ''
})
const loginRules = reactive<FormRules>({
	account: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
	password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
})

const onSubmit = () => {
	loginFormRef.value.validate().then(async () => {
		const res = await setUserInfo(user)
		if (res.code == 200) {
			const { token, userInfo } = res.data
			setUserStore.setToken(token)
			setUserStore.setUserInfo(userInfo)
			router.push({ path: '/' })
		}
	})
}
</script>

<style lang="scss" scoped>
.card_body {
	display: flex;
	width: 100%;
	height: 100%;
	overflow: hidden;
	background-color: #a5c2cb8a;
	justify-content: center;
	align-items: center;
	.login_form {
		width: 500px;
		height: 400px;
		display: flex;
		justify-content: center;
		align-items: center;
		background-color: #a5c2cb8a;
		.el-input {
			width: 220px;
		}
		.Submit {
			margin-top: 50px;
		}
	}
}
</style>
相关推荐
粉末的沉淀1 天前
vue:Vite项目中高效管理纯色SVG图标的方案
前端·javascript·vue.js
卤蛋fg61 天前
vxe-table 列宽与行高拖拽调整:让表格布局极其灵活,拖拽功能非常强大
vue.js
向日的葵0061 天前
Vue 路由传参的三种方式(三)
vue.js·路由
如果超人不会飞1 天前
TinyVue Checkbox复选框组件使用指南
前端·vue.js
如果超人不会飞1 天前
TinyVue Radio单选框组件使用指南
vue.js
鲁班小子1 天前
Vite resolve.dedupe 使用教程
vue.js·vite
如果超人不会飞1 天前
TinyVue Input输入框组件使用指南
vue.js
如果超人不会飞1 天前
TinyVue Pager分页组件使用指南
前端·vue.js
大刚测试开发实战1 天前
TestHub重磅更新!AI用例生成增加流式输出、Markdown文档上传、模型配置检测、AI评审开关控制...
vue.js·后端·github
可别3901 天前
Vue 极简实现语音实时转写(录音转文字,低网络依赖、开箱即用)
前端·javascript·vue.js