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>
相关推荐
想你的风吹到了瑞士40 分钟前
变量提升&函数提升
前端·javascript·vue.js
独上归州2 小时前
Vue与React的Suspense组件对比
前端·vue.js·react.js·suspense
Komorebi⁼3 小时前
Vue核心特性解析(内含实践项目:设置购物车)
前端·javascript·vue.js·html·html5
明月清风徐徐3 小时前
Vue实训---0-完成Vue开发环境的搭建
前端·javascript·vue.js
CSDN专家-赖老师(软件之家)3 小时前
养老院管理系统+小程序项目需求分析文档
vue.js·人工智能·小程序·mybatis·springboot
明月清风徐徐4 小时前
Vue实训---2-路由搭建
前端·javascript·vue.js
王解4 小时前
速度革命:esbuild如何改变前端构建游戏 (1)
前端·vite·esbuild
DN金猿4 小时前
Vue移动端网页(H5)预览pdf文件(pdfh5和vue-pdf)(很详细)
前端·vue.js·pdf
qq_364371726 小时前
Vue 内置组件 keep-alive 中 LRU 缓存淘汰策略和实现
前端·vue.js·缓存
你挚爱的强哥12 小时前
✅✅✅【Vue.js】sd.js基于jQuery Ajax最新原生完整版for凯哥API版本
javascript·vue.js·jquery