所用的技术
- vue3
- element-plus
- axios
- pinia
- Eslint
准备工作
创建vue3项目
可以参考选择以下这几项
运行vue3项目
看到以下这个界面表示vue3项目创建成功
删除初始化的默认文件
删除以下文件
配置pinia
下列配置的优点
由 stores 统一维护,在 stores/index.js 中完成 pinia 初始化,交付 main.js 使用
由 stores/index.js 统一导出,导入路径统一 ./stores
,而且仓库维护在 stores/modules 中
添加src/stores/modules/user.js
import { defineStore } from 'pinia'
import { ref } from 'vue'
// 用户模块
export const useUserStore = defineStore(
'gs-user',
() => {
const token = ref('') // 定义 token
const setToken = (newToken) => (token.value = newToken) // 设置 token
return { token, setToken }
},
{
persist: true // 持久化
}
)
修改src/stores/index.js
// 从'pinia'库中引入创建Pinia实例的函数
import { createPinia } from 'pinia'
// 从'pinia-plugin-persistedstate'库中导入持久化插件
// import persist from 'pinia-plugin-persistedstate'
// 创建一个Pinia实例,用于状态管理
const pinia = createPinia()
// 使用持久化插件,使状态持久化
// pinia.use(persist)
// 导出Pinia实例,供其他模块使用
export default pinia
// 导出user模块中的所有内容,集成用户状态管理模块
export * from './modules/user.js'
修改一些文件
App.vue
<script setup></script>
<template>
<router-view></router-view>
</template>
<style scoped></style>
router/index.js
createRouter 创建路由实例,===> new VueRouter()
路由的两种模式
1. history模式: createWebHistory() http://xxx/user
2. hash模式: createWebHashHistory() http://xxx/#/user (在前缀加了’#‘)
一般使用history模式
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: []
})
export default router
src/main.js
import { createApp } from 'vue'
import pinia from '@/stores/index'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router)
app.use(pinia)
app.mount('#app')
新增目录api、utils
api:组织和封装与后端服务器进行交互的API接口
utils:用于存放和管理项目中可能频繁使用的工具函数或方法
引入element-plus
安装
可以选择以下方式
- npm install element-plus --save
- yarn add element-plus
- pnpm install element-plus
导入
完整导入
如果你对打包后的文件大小不是很在乎,那么使用完整导入会更方便。
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus)
自动导入(推荐)
需要安装unplugin-vue-components 和 unplugin-auto-import 这两款插件
npm install -D unplugin-vue-components unplugin-auto-import
然后把下列代码插入到 vite.config.js 配置文件中
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()]
}),
Components({
resolvers: [ElementPlusResolver()]
})
],
base: '/gs',
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
axios配置
安装
可以选择以下几种方式
- npm install axios
- yarn add axios
添加src/utils/request.js
import { useUserStore } from '@/stores'
import axios from 'axios'
import router from '@/router'
import { ElMessage } from 'element-plus'
// 设置后端地址
const baseURL = 'http://localhost:8090'
/**
* @description 创建axios实例
*/
const instance = axios.create({
baseURL,
timeout: 60000 // 设置响应时间:1min
})
/**
* @description 请求拦截器
*/
instance.interceptors.request.use(
(config) => {
const userStore = useUserStore()
// 添加token到http请求头的Authorization
if (userStore.token) {
config.headers.Authorization = userStore.token
}
return config
},
(err) => Promise.reject(err)
)
/**
* @description 响应拦截器
*/
instance.interceptors.response.use(
(res) => {
// 响应成功
if (res.data.code === 1) {
return res
}
ElMessage({ message: res.data.msg || '服务异常', type: 'error' })
return Promise.reject(res.data)
},
// 失败
(err) => {
ElMessage({
message: err.response.data.msg || '服务异常',
type: 'error'
})
console.log(err)
// 如果用户未登录,状态码为 401
if (err.response?.status === 401) {
router.push('/login')
}
return Promise.reject(err)
}
)
export default instance
export { baseURL }
配置路由
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
// 登录页
{ path: '/login', component: () => import('@/views/login/LoginPage.vue') },
// 布局页
{ path: '/', component: () => import('@/views/Hello/HelloPage.vue') }
]
})
export default router
封装后端登录api接口
添加 src/api/user.js
import request from '@/utils/request'
export const loginService = ({ username, password }) => {
return request.post('/user/login', { username, password })
}
添加页面
添加src/views/Hello/HelloPage.vue
<template>
<h1>欢迎,登录成功</h1>
</template>
添加src/views/login/LoginPage.vue
<script setup>
import { ref } from 'vue'
import { loginService } from '@/api/user'
import { useUserStore } from '@/stores'
import { useRouter } from 'vue-router'
const form = ref()
const router = useRouter()
const userStore = useUserStore()
const loginModel = ref({
username: '',
password: ''
})
// 非空校验
const rules = {
username: [{ required: true, message: '账号不能为空', trigger: 'blur' }],
password: [{ required: true, message: '密码不能为空', trigger: 'blur' }]
}
const login = async () => {
await form.value.validate()
const res = await loginService(loginModel.value)
console.log(res)
userStore.setToken(res.data.token)
ElMessage.success('登录成功')
router.push('/')
}
</script>
<template>
<div class="container">
<div class="login-wrapper">
<div class="header">登录</div>
<el-form
class="form-wrapper"
:model="loginModel"
:rules="rules"
ref="form"
>
<el-form-item label="账号:" prop="username">
<el-input
placeholder="请输入账号"
v-model="loginModel.username"
></el-input>
</el-form-item>
<el-form-item label="密码:" class="password" prop="password">
<el-input
placeholder="请输入密码"
type="password"
v-model="loginModel.password"
></el-input>
</el-form-item>
<el-form-item>
<el-button class="btn" @click="login">登录</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<style>
.container {
background-image: linear-gradient(to right, #fbc2eb, #a6c1ee);
width: 100%;
height: 100vh;
}
.login-wrapper {
background-color: #fff;
width: 358px;
height: 588px;
border-radius: 15px;
padding: 0 50px;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.header {
font-size: 38px;
font-weight: bold;
text-align: center;
line-height: 200px;
}
.password {
margin-top: 30px;
}
.btn {
color: #fff;
font-size: large;
margin-top: 40px;
height: 45px;
width: 100%;
background-image: linear-gradient(to right, #a6c1ee, #fbc2eb);
}
</style>
运行代码
npm run dev
打开http://localhost:5173/gs/login,看到以下图片页面部署成功
记得启动后端哦
账号密码正确:
密码错误:
账号错误: