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
store.js
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" } } }
Comments | NOTHING