main.js
import { createApp } from 'vue'
import router from './router'
import App from './App.vue'
import 'element-plus/dist/index.css'
import ElementPlus from 'element-plus'
import axios from 'axios'
const app = createApp(App)
app.config.globalProperties.$axios = axios
app.use(router)
app.use(ElementPlus)
app.mount('#app')
App.vue
<template>
<div>
<router-view></router-view>
</div>
</template>
<script>
export default {
components: {},
};
</script>
<style>
* {
margin: 0;
padding: 0;
border: 0;
}
</style>
store.js
import { createApp } from 'vue'
import App from '../App.vue'
import Vuex from 'vuex'
const app = createApp(App)
app.use(Vuex)
export default new Vuex.Store({
state: {
//这里放全局参数
token: '111222'
},
mutations: {
//这里是set方法
},
getters: {
//这里是get方法
},
actions: {
//这个部分我暂时用不上
},
modules: {
//这里是方法
}
})
router.js
import { createRouter, createWebHistory } from 'vue-router'
const routerHistory = createWebHistory()
// - 定义路由组件规则
import Login from "@/views/login/index";
import Registered from "@/views/registered/index";
import NotFound from "@/views/NotFound";
const routes = [
// 路由重定向
{ path: "/", redirect: "/login" },
{ path: "/login", component: Login },
{ path: "/register", component: Registered },
// // 嵌套路由
// {
// path: "/users",
// component: Users,
// children: [
// {path:"list",name: "user_list",component: List,},
// { path: "add", component: Add },
// { path: "mod", component: Mod },
// { path: "del", component: Del },
// ],
// },
// 默认404路由
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
];
// - 创建路由实例
const router = new createRouter({
history: routerHistory,
routes,
});
// - 导出路由实例
export default router;
http.js
import axios from 'axios'
import router from '@/router/index'
import store from '@/store/index'
import { ElMessage } from 'element-plus'
console.warn(process.env.VUE_APP_API_URL)
/**
* 跳转登录页
* 携带当前页面路由,以期在登录页面完成登录后返回当前页面
*/
const toLogin = () => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
})
}
/**
* 请求失败后的错误统一处理
* @param {Number} status 请求失败的状态码
*/
const errorHandle = (status, other) => {
// 状态码判断
switch (status) {
// 401: 未登录状态,跳转登录页
case 401:
toLogin()
ElMessage({
type: 'error',
message: '请先登录'
})
break
// 403 token过期
// 清除token并跳转登录页
case 403:
ElMessage({
type: 'error',
message: '登录过期,请重新登录'
})
localStorage.removeItem('token')
store.commit('loginSuccess', null)
setTimeout(() => {
toLogin()
}, 1000)
break
// 404请求不存在
case 404:
ElMessage({
type: 'error',
message: '请求的资源不存在'
})
break
case 500:
ElMessage({
type: 'error',
message: '网络请求失败'
})
break
default:
console.log(other)
}
}
// 创建axios实例
var instance = axios.create({
baseURL: process.env.VUE_APP_API_URL,
timeout: 5000, // 请求超过5秒即超时返回错误
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
withCredentials: true
})
/**
* 请求拦截器
* 每次请求前,如果存在token则在请求头中携带token
*/
instance.interceptors.request.use(
config => {
// 登录流程控制中,根据本地是否存在token判断用户的登录情况
// 但是即使token存在,也有可能token是过期的,所以在每次的请求头中携带token
// 后台根据携带的token判断用户的登录情况,并返回给我们对应的状态码
// 而后我们可以在响应拦截器中,根据状态码进行一些统一的操作。
const token = store.state.token
token && (config.headers.token = token)
console.log(config);
return config
},
error => Promise.error(error)
)
// 响应拦截器
instance.interceptors.response.use(
// 请求成功
res => (
res.status === 200 ? Promise.resolve(res) : Promise.reject(res)
),
// 请求失败
error => {
const { response } = error
if (response) {
// 请求已发出,但是不在2xx的范围
errorHandle(response.status, response.data.message)
return Promise.reject(response)
} else {
// 处理断网的情况
// eg:请求超时或断网时,更新state的network状态
// network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
// 关于断网组件中的刷新重新获取数据,会在断网组件中说明
if (!window.navigator.onLine) {
ElMessage({
type: 'error',
message: '网络连接失败'
})
// store.commit('changeNetwork', false)
} else {
return Promise.reject(error)
}
}
}
)
export function get(url, fromdata) {
return axios({
method: 'get',
url: url,
params: fromdata,
});
return instance.get(url, params)
}
export function post(url, params) {
return instance.post(url, params)
}
export default instance
vue.config.js
// 这里的webpack配置会和公共的webpack.config.js进行合并
module.exports = {
// 执行 npm run build 统一配置文件路径(本地访问dist/index.html需'./')
// NODE_ENV:Node.js 暴露给执行脚本的系统环境变量。通常用于确定在开发环境还是生产环境
publicPath: process.env.NODE_ENV === 'production' ? '' : '/',
outputDir: 'dist', // 输出文件目录
assetsDir: 'static', // 放置静态资源
// indexPath: 'index.html', // 可以不设置一般会默认
// filenameHashing:true, // 文件命名
lintOnSave: false, //设置是否在开发环境下每次保存代码时都启用 eslint验证
productionSourceMap: false, //如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建
// runtimeCompiler: false, // 是否使用带有浏览器内编译器的完整构建版本
configureWebpack: { // 别名配置
resolve: {
alias: {
//'src': '@', 默认已配置
'api': '@/api',
'assets': '@/assets',
'common': '@/common',
'components': '@/components',
'views': '@/views',
'plugins': '@/plugins',
'utils': '@/utils',
'store': '@/store',
}
}
// 使用前面可加~
},
css: { // css相关配置
// 是否将组件中的 CSS 提取至一个独立的 CSS 文件中,生产环境下是 true,开发环境下是 false
extract: process.env.NODE_ENV === "production",
// 是否为 CSS 开启 source map。设置为 true 之后可能会影响构建的性能。
sourceMap: false,
// 启用 CSS modules for all css / pre-processor files.(预加载)
requireModuleExtension: true,
loaderOptions: {
sass: {
// data: `@import "@/assets/css/variables.scss";`
}
}
},
devServer: {
open: true, // 是否自动打开浏览器
port: 3000, // 设置端口号
overlay: false, // 如果你开始了eslint,不要让eslint在页面中遮罩,它错误会在console.log控制台打印
// host: 'localhost:3000', // ip
disableHostCheck: true, //是否关闭用于 DNS 重绑定的 HTTP 请求的 HOST 检查
hotOnly: false, // 热更新
https: false, // https:{type:Boolean}配置前缀
proxy: { //目的是解决跨域,若测试环境不需要跨域,则不需要进行该配置
'/game': { // 拦截以 /api 开头的url接口
target: 'http://localhost:9099/', //目标接口域名
changeOrigin: true, //是否跨域
ws: true, //如果要代理 websockets,配置这个参数
secure: false, // 如果是https接口,需要配置这个参数
// 标识替换
// 原请求地址为 /api/getData 将'/api'替换''时,
// 代理后的请求地址为: http://xxx.xxx.xxx/getData
// 若替换为'/other',则代理后的请求地址为 http://xxx.xxx.xxx/other/getData
pathRewrite: { // 标识替换
'^/api': '/' //重写接口 后台接口指向不统一 所以指向所有/
// '^/api': '/api/mock'
}
}
}
},
// 这个插件中添加的service worker只在生产环境中启用(例如,只有当你运行npm run build或yarn build时)。
// 不推荐在开发模式中启用service worker,因为它会导致使用以前缓存的资产而不包括最新的本地更改的情况。
pwa: {
// serviceWorker:false,
// 允许您从一个现有的service worker文件开始,并创建一个该文件的副本,并将“预缓存清单”注入其中。
// workboxPluginMode:'InjectManifest',
// workboxOptions: {
// //swSrc: './app/sw.js', /* Empty file. */
// },
iconPaths: {
favicon32: "favicon.ico",
favicon16: "favicon.ico",
appleTouchIcon: "favicon.ico",
maskIcon: "favicon.ico",
msTileImage: "favicon.ico"
}
}
}
api.js
import { get, post } from '@/api/http'
export const login = params => get('game/login', params)
export const register = params => get('/game/register', params)
Comments | NOTHING