->(1)vue3.0脚手架创建命令:(npm init vite 项目名称)
->(2)配置@路径:(在vue.config.js中配置)
(*vue.config.js写入代码)
`
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig({
resolve:{
alias:{
"@":path.resolve(__dirname,"src")
},
plugins: [
vue(),
]
}
`
->(3)安装router(安装指令:npm install vue-router@4 -S)
->(4)在src下创建router在创建index.js
(*index.js写入代码)
`
import { createRouter , createWebHistory } from 'vue-router'
//导入首页和登录页及404页面
import Layout from "@/pages/Home/index.vue"
import NotFound from "@/pages/404.vue"
import Login from "../pages/Login/index.vue"
const routes = [
{
path:'/',
component:Layout,
meta:{
title:"首页"
}
},
{
path:'/login',
component:Login,
meta:{
title:"登录"
}
}
]
const router = createRouter({
history:createWebHistory(),
routes
})
export default router
`
->(5)把安装的router导入到main.js中
(*)main.js代码如下 `
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router)
app.mount('#app')
`
->(6)安装store(安装指令: npm install vuex@next4.0)
->(7)在src下创建一个store文件夹,在创建index.js
(*index.js写入代码)
`
import { createApp } from "vue"
import { createStore } from 'vuex'
//创建一个store实例
const store = createStore({
state() {
return {
}
},
mutations:{
},
actions:{
}
})
export default store
然后在导入到main.js中
import store from "./store"
app.use(store)
`
->(8)封装axios接口
->(9)安装axios(安装指令:npm i axios)
->(10)在src下创建一个utils文件夹再创建一个request.js
(*request.js代码如下)
`
import axios from 'axios'
const myAxios = axios.create({
baseURL:'/api', //接口基地址(这个是后端跨域处理的api)
timeout:5000
})
//请求拦截器
myAxios.interceptors.request.use(config => {
return config
}, err => {
return Promise.reject(err)
})
//响应拦截器
myAxios.interceptors.response.use(function (response) {
return response.data.data //解析接口里面的data(因为后端返回的是data.dat所有解析后期调用方便些)
},function(error) {
//对响应的错误统一处理
return Promise.reject(error)
})
export default myAxios
`
->(11)在src下创建一个api文件夹再创建一个user.js文件
(*user.js写入代码如下(具体接口要看后端给定的接口文档))
`
import request from "@/utils/request.js"
//登录
export function Login(data) {
return request({
url:'/admin/login',
method:'POST',
data
})
}
//获取管理员信息和权限菜单
export function getinfo() {
return request({
url:'/admin/getinfo',
method:'POST'
})
}
//退出登录
export function Logout() {
return request({
url:'/admin/logout',
method:'POST'
})
}
`
->(12)在vue.config.js中配置跨域
`
export default defineConfig({
server:{
proxy:{
'/api':{
<!--项目地址-->
target:'http://ceshi13.dishait.cn',
changeOrigin:true,
rewrite:(path) => path.replace(/^\/api/,'')
}
}
}
})
`
->(13)使用cookie(安装指令: npm i @vueuse/integrations npm i universal-cookie)
->(14)在src/utils下创建一个auth.js
(*auth.js写入代码)
`
//导入cookie
import { useCookies } from "@vueuse/integrations/useCookies"
<!--设置token-->
const TokenKey = "admin-token"
const cookie = useCookies()
//获取token
export function getToken() {
return cookie.get(TokenKey)
//设置token
export function setToken(token) {
return cookie.set(TokenKey,token)
//清除token
export function removeToken() {
return cookie.remove(TokenKey)
}
}
}
`
->(15)在store调用用获取用户信息的接口
(*index.js写入代码)
`
import { createApp } from "vue"
import { createStore } from 'vuex'
//引入用户信息接口
import { getinfo } from "../api/user.js"
import { removeToken } from "@/utils/auth.js"
//创建一个store实例
const store = createStore({
state() {
return {
//用户信息
user:{}
}
},
mutations:{
//记录用户信息(存储token)
SET_USERINFO(state , user) {
state.user = user
}
},
<!--调用用户信息接口-->
actions:{
//获取当前登录用户信息
getinfo({ commit }) {
return new Promise((resolve,reject) => {
getinfo().then(res => {
commit("SET_USERINFO",res)
//请求成功调用
resolve(res)
}).catch(err => reject(err))
})
}
}
})
`
->(16)封装一个消息提示框,在src/utils下创建一个validate.js文件
(*validate.js写入代码如下)
`
import { ElNotification , ElMessageBox } from 'element-plus'
//消息提示的方法
export function toast(message , type = "success" , dangerouslyUseHTMLString = false) {
ElNotification({
message,
type,
dangerouslyUseHTMLString,
duration:3000
})
}
//确认消息
export function showModel(content = "提示的内容" , type = "warning" , title="") {
return ElMessageBox.confirm(
content,
title,
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type
})
}
`
->(16.1)在登录组件(login.vue)中写登录保存token
(*写入代码如下:)
`
<script setup>
// 登录接口
import { Login } from "@/api/user.js"
//引入路由
import { useRouter } from "vue-router";
//引入vuex
import { useStore } from "vuex"
import { setToken } from "@/utils/auth.js"
//引入封装的消息提示
import { toast } from '@/utils/validate.js'
const form = reactive({
username: '',
password: ''
})
const router = useRouter()
const store = useStore()
const formRef = ref(null)
const onSubmint = () => {
formRef.value.validate((valid) => {
if (valid) {
loading.value = true
Login({
username: form.username,
password: form.password
}).then(res => {
toast("登录成功")
//存储token和用户相关信息
setToken(res.token)
//跳转到首页
router.replace("/")
})
</script>
`
->(17)路由导航守卫(在src下创建permission.js)
(*permission.js代码如下)
`
import router from "./router"
import store from "./store"
import { getToken } from "./utils/auth.js"
import { toast } from "./utils/validate.js"
//全局前置守卫
router.beforeEach(async(to , from , next) => {
const token = getToken()
//没有登录强制跳转到登录页
if(!token && to.path !== "/login") {
toast("请先登录","error")
return next({ path:'/login' })
}
//防止重复登录判断
if(token && to.path == "/login") {
toast("请勿重复登录","error")
return next({ path:from.path ? from.path:'/'})
//如果用户登录了就自动获取用户信息,并存储在vuex当中
//因为是异步请求所以要加await
if(token) {
//调用用户接口
await store.dispatch("getinfo")
}
}
//设置页面标题
let title = (to.meta.title ? to.meta.title : "") + "-帝莎后台"
// console.log(to.meta.title)
document.title = title
next() //放行
})
})
`
->(18)完善拦截器和响应器(给后面的接口加上token请求头)
`
import axios from 'axios'
import { toast } from '@/utils/validate.js'
// 导入cookie
import { getToken } from "@/utils/auth.js"
// 请求拦截器
myAxios.interceptors.request.use(config => {
//使用cookie
const token = getToken()
<!--给后面的接口都添加请求头-->
if(token) {
config.headers['token'] = token
}
return config
}, err => {
return Promise.reject(err)
})
//响应拦截器
myAxios.interceptors.response.use(function (response) {
return response.data.data //解析接口里面的data
},function(error) {
//对响应的错误统一处理
toast(error.response.data.msg ||'请求失败',"error")
return Promise.reject(error)
})
export default myAxios
`
->(20)退出登录
`
<template>
<el-button @click="login">退出登录</el-button>
</template>
<script setup>
import { showModel , toast } from "@/utils/validate.js"
//引入路由
import { useRouter } from "vue-router";
//引入vuex
import { useStore } from "vuex"
// 退出登录的请求接口
import { Logout } from "@/api/user.js"
const store = useStore()
const router = new useRouter()
function logout() {
showModel("是否要退出登录").then(res => {
Logout().then(res => {
//清空token
// removeToken("SET_USERINFO",res.token)
//在vuex里面封装后直接调用vuex里面的方法
//清空token和清除当前用户状态
store.dispatch("logout")
//跳转回登录页
router.replace("/login")
toast("退出登录成功")
})
}
</script>