vue2/vue3和uni-app小程序的http请求封装和路由配置

nextTick

vue的数据渲染是异步批量的,nextTick会在数据渲染完毕后立即执行

跨域

const cors = require('koa2-cors')

app.use(cors({
origin:function(ctx){
return 'http://1ocalhost:8080';
}
}))

动态路由权限

const router = require('koa-router')()
router.get('/user_router_auth',async(ctx,next)=>{
const {uid} = ctx.request.body;
if(uid){
let authRouterInfo = [];
ctx.body = authRouterInfo;
)else{
next();
}
})

父组件里引用子组件中的方法

先将子组件注册进父组件,在引入的子组件标签上写上ref="child",在父组件methods里写上一个方法,里面用this.$refs.child.子组件的方法名

异步编程Promise,async,await

用async将函数标记为异步操作,如果在其函数中并行两个请求,他会按顺序执行,解决方法是

async function f(){
const promiseA = fetch("http://...");
const promiseB = fetch("http://...");

const [a,b] = await Promise.all([promiseA,promiseB]);//提高性能
}

若在async函数中用到遍历,那么不能用forEach/map等,因为他会直接返回,尽管用了await,也不会等待所有异步操作都执行完毕,所以应该用for循环遍历;若是想要循环中的所有操作都并发执行,可以用for await,它也会等所有异步操作完成之后再向后执行

async function fn(){
[1,2,3].forEach(async (i) => {
await someAsyncOperation();
});
console.log("done");
f()

async function fn(){
const promises = [
someAsyncOperation(),
someAsyncOperation(),
someAsyncOperation()
];
for await (let result of promises){
//...
}
console.log("done");
fn()

vue2配置

config基本配置

const { defineConfig } = require('@vue/cli-service');
module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave: false,
  devServer:{
    proxy:{
      '/yigou':{
        target:'http://127.0.0.1:3000',
        pathRewrite:{'^/yigou':''}
      }
    }
  }
});

vue2-http配置

import axios from 'axios';
import { Message } from 'element-ui';
import store from '@/store';
import router from '@/router';

const instance = axios.create({
  baseURL: process.env.VUE_APP_URL,
});

// 1、请求拦截器:在请求之前,统一对请求数据处理:请求头的设置、loading的处理,比如:在请求头添加token
instance.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  store.commit('SET_LOADING', true);
  // console.log('config',config);
  // 当token存在的时候,在请求头中添加token,只要是需要token的接口,token都在请求拦截器中统一处理 
  if (store.state.token) {
    config.headers.authorization = 'Bearer ' + store.state.token;  //请求头加上token
  }

  return config;
}, function (error) {
  // 对请求错误做些什么: 发送请求失败
  store.commit('SET_LOADING', true);
  return Promise.reject(error);
});

// 2、响应拦截器:在服务端响应数据之后,统一对响应数据处理、loading的处理、响应失败的处理
instance.interceptors.response.use(function (response) {
  // 响应成功执行的函数
  const data = response.data;

  // console.log('响应成功执行的函数 data=', data);
  // currentRoute获取当前路由对象,从当前的路由对象中找到当前路径传递到login中
  // console.log('router.currentRoute=', router.currentRoute);
  if (data.err_no == 0) {
    // 响应成功,有数据
  } else if (data.err_no == 101) {
    // token验证失败:1、token不存在;2、token过期
    // 跳转到登录页面:登录页面的时候,把当前要去的页面地址带上,登录成功之后,再回跳过来
    router.push({ name: 'login', query: { redirect: router.currentRoute.path } });
  } else {
    // 响应失败,没有数据
  }

  Message.success('请求数据成功');
  store.commit('SET_LOADING', false);

  return data;
}, function (error) {
  // 响应失败执行的函数:请求已经成功发送,响应数据失败
  Message.error('请求数据失败');
  store.commit('SET_LOADING', false);
  return Promise.reject(error);
});

// 封装一个请求的函数
const callApi = (url, method = 'GET', data = {}) => {
  return instance({
    url,
    method,
    params: method === 'GET' ? data : '',// 如果是get请求,使用params传参
    data: method === 'POST' ? data : '',//如果是post请求,使用data传参
  });
}

// 发送get请求
export const getApi = (url, data) => callApi(url, 'GET', data);

// 发送post请求
export const postApi = (url, data) => callApi(url, 'POST', data);

vue2-router配置

import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

const router = new VueRouter({
	routes: [
		{path:'/',name:'home', component:()=>import('@/views/home.vue')},
		{path:'/login',name:'login', component:()=>import('@/views/login.vue')},
		{path:'/regist',name:'regist',component:()=>import('@/views/regist.vue')},
	],
});

router.beforeEach((to, from, next) => {
	if (to.meta.requiresAuth) {
	  // 需要登录之后才能跳转的页面
	  // 判断token是否存在,如果token存在,直接跳转,如果token不存在再跳转到登录页面
	  if (store.state.token) {
		// token存在,正常跳转 
		next();
	  } else {
		// token不存在,跳转到登录页面:登录页面的时候,把当前要去的页面地址带上,登录成功之后,再回跳过来
		router.push({ name: 'login', query: { redirect: to.path } });
	  } 
	} else {
	  // 不需要登录,正常执行
	  next();
	}
  })

export default router;

vue3 配置

vue3-router配置

import { createRouter, createWebHistory } from 'vue-router'


const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {path: '/',name: 'home',component: ()=> import ('../views/home.vue')
    // children:[
    //   {path:'',name:'login-page',component: ()=> import ('../views/login-page.vue')}
    // ],
  },
    {path:'/ranking-list',name:'ranking-list',component: ()=> import ('../views/ranking-list.vue')},
    {path:'/song-sheet',name:'song-sheet',component: ()=> import ('../views/song-sheet.vue')},
    {path:'/search',name:'search',component: ()=> import ('../views/search.vue')},
    // {path:'/home/login-page',name:'login-page',component: ()=> import ('../views/login-page.vue')}
  ]
})

export default router

vue3-http配置1

import axios from 'axios';
// import { Message } from 'element-ui';
// import store from '@/store/index';
import { useLoginStore } from "../stores/login";
const instance = axios.create({
    // baseURL:'http://127.0.0.1:3000',
    baseURL: import.meta.env.VITE_URL,
    timeout: 60 * 1000  
});

// instance.interceptors.response.setHeader("Access-Control-Allow-Origin", "*");
// instance.interceptors.response.setHeader("Access-Control-Allow-Credentials", "true");
// instance.interceptors.response.setHeader("Access-Control-Allow-Methods", "*");
// instance.interceptors.response.setHeader("Access-Control-Allow-Headers", "Content-Type,Access-Token");
// instance.interceptors.response.setHeader("Access-Control-Expose-Headers", "*");

// if (request.getMethod().equals("OPTIONS")) {
//     HttpUtil.setResponse(response, HttpStatus.OK.value(), null);
//     return;
// }

instance.interceptors.request.use(function(config){
    const loginStore = useLoginStore();
    
    // store.commit('SET_LOADING',true);
    if (loginStore.token) {
        config.headers.authorization = 'Bearer ' + loginStore.token;  //请求头加上token
      }
    return config;
},function(error){
    return Promise.reject(error);
});

instance.interceptors.response.use(function(response){
    // Message.success('请求成功')
//    store.commit('SET_LOADING',false); 
   const data = response.data;
   return data;
},function(error){
    // Message.fail('请求失败')
    return Promise.reject(error);
});

const callApi = (url,method='GET',data={}) => {
    data = Object.assign({}, {timestamp: Date.now()}, data);
    return instance({
        url,
        method,
        params:method === 'GET' ? data : '',
        data:method === 'POST' ? data : '',
        header:{
            cookie:{withCredentials: true}
        }
    })
}

export const getApi = (url,data) => callApi(url,'GET',data);
export const postApi = (url,data) => callApi(url,'POST',data);
//请求方法
export const roomListApi = (data) => getApi('/api/RoomApi/live/'+data)

vue3-http配置2

import axios from "axios";
import { getToken, setToken, removeToken } from "@/utils/auth";
import { baseURL } from './config'
import store from "../../store/index";
// create an axios instance
const service = axios.create({
    // baseURL: 'api',
    baseURL: baseURL,
    timeout: 6000 * 10, // request timeout
    // withCredentials: true, // send cookies when cross-domain requests
});

// request interceptor
service.interceptors.request.use(
    (config) => {
        // if (getToken()) {
        //     config.headers["set-cookies"] = getToken();
        // }
        // console.log(config, 88)
        console.log()
        if (store.state.user.userInfo.strCookie) {
            config.headers["set-cookies"] = getToken();
        } else {
            config.headers["set-cookies"] = store.state.user.userInfo.strCookie;

        }
        return config;
    },
    (error) => {
        return Promise.reject(error);
    }
);

// response interceptor
service.interceptors.response.use(
    (res) => {
        // console.log(res, 89899)
        if (res.headers.token) {
            setToken(res.headers.token);
        }
        // 未设置状态码则默认成功状态
        const code = res.data.code;
        if (code === -9999 || code === -99999) {
            //提示 todo
            removeToken();
            window.location.href = window.location.origin;
        } else {
            return res.data;
            // if (code === 200) {
            //     return res.data;
            // }else{
            //     debugger
            //     this.$message.error(res.data.msg)
            // } 
        }
    },
    (error) => {
        //提示 todo
        return Promise.reject(error);
    }
);

export default service;

//请求方法
import request from './request'
export function deleteOutInList(data) {
  return request({
    url: 'stock/delOutInInfo',
    method: 'POST',
    data,
  })
}

vue3-vite基本配置1

import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path';

// https://vitejs.dev/config/
// export default defineConfig({
//   plugins: [vue()],
//   resolve: {
//     alias: {
//       '@': fileURLToPath(new URL('./src', import.meta.url))
//     }
//   }
// })
export default defineConfig({
  plugins: [vue()],
  base: '/', // 基础路径的配置
  resolve: {
    alias: {
      // 路径别名
      '@': path.resolve(__dirname, 'src'),
    },
  },
  // 服务相关的一些配置
  server: {
    port: 8080,
    proxy: {
      // 1、简单写法
      // '/foo': 'http://localhost:4567',
      // 2、对象写法
      '/wangyi': {
        target: 'http://127.0.0.1:3000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/wangyi/, '')
      },
    }
  }
})

 vue3-vite基本配置2

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";

const baseUrl = {
  development: "./",
  beta: "/oyerp/",
  release: "./",
};

// https://vitejs.dev/config/
export default ({ mode }) => {
  return defineConfig({
    plugins: [vue()],
    base: baseUrl[mode],
    //引入全局样式
    css: {
      preprocessorOptions: {
        scss: {
          loader: 'sass-resources-loader',
          additionalData: `@import "/src/style/index.scss";`,
        },
      },
    },
    resolve: {
      alias: {
        "~": path.resolve(__dirname, "./"),
        "@": path.resolve(__dirname, "src"),
      },
    },
    server: {
      proxy: {
        "/api": {
          target: "http://oyerp.yanbaokeji.cn:8920/oyerp/",
          changeOrigin: true,
          rewrite: (path) => path.replace(/^\/api/, ""),
        },
      },
    },
  });
}

设置token

import Cookies from 'js-cookie'

const TokenKey = 'OY_ERP_TOKEN'

export function getToken() {
    // return 'eyJhbGciOiJIUzI1NiIsIlR5cGUiOiJKd3QiLCJ0eXAiOiJKV1QifQ.eyJleHBpcmVzIjoxNjM4MTY2MzkwMTM4LCJqc29uRGF0YSI6IntcImFjY291bnRJZFwiOjEsXCJncmFkZUlkXCI6MCxcInVzZXJJZFwiOjEsXCJ1c2VyVHlwZVwiOjF9In0.nz0EjG6YVQcEtPUP_4-SMY-h-xIvzAgvrGSe_245aKA'
    return Cookies.get(TokenKey)
}

export function setToken(token) {
    return Cookies.set(TokenKey, token)
}

export function removeToken() {
    return Cookies.remove(TokenKey)
}

uni-app小程序

uni-app小程序http请求1

import config from './config.js';
const request = async (method, url, data, header) => {
	const deurl = url;
	const headerDeault = {
		'Content-Type': 'application/json',
	};
	uni.showLoading()
	const res = await new Promise((resolve, reject) => {
		uni.request({
			url: url.indexOf('http:') == 0 || url.indexOf('https:') == 0 ? url : config
				.requestBaseUrl + url,
			method: method,
			withCredentials: true,
			data: data,
			header: header ? header : headerDeault,
			success: res => {
				
				if (res && res.data && res.statusCode === 200) {
					if (res.data.statusCode === 200) {
						resolve(res.data);
					} else if (res.data.code == 199) {
						uni.showToast({
							title: res.data.msg ? res.data.msg : 'error',
							duration: 2000,
							icon: 'none',
						});
						setTimeout(() => {
							uni.navigateTo({
								url:'/pages/login/codeLogin'
							})
						}, 1500);
					} else if (res.data.statusCode == 400) {
						uni.showToast({
							title: '参数有误',
							duration: 3000,
							icon: 'none'
						});
					} else {
						uni.showToast({
							title: res.data.errors ? res.data.errors : res.errors,
							duration: 3000,
							icon: 'none',
						});
						// reject(res.data);
					}
				} else {
					uni.showToast({
						title: res.data.errors ? res.data.errors : res.errors,
						duration: 3000,
						icon: 'none',
					});
				}
			},
			fail: err => {
				uni.showToast({
					title: '网络错误',
					icon: 'none',
					content: '网络请求超时,请稍后再试',
					icon: 'none',
					showCancel: false,
				});
				// reject(err);
			},
			complete: () => {
				uni.hideLoading();
			},
		});
	}).catch(e => {
		return e.data;
	});
	return res;
};


module.exports = request;

//页面请求
export function getWorkerOrderList(params) {
	return request("GET", "/WorkOrder/All", params);
}
export function getWorkerOrderDetails(bookingId) {
	return request("GET", `/WorkOrder/WorkOrderDetail?bookingId=${bookingId}`);
}
export function changeOrderAppointment(data) {
	return request("PUT", `/WorkOrder/Booking?bookingId=${data.bookingId}`,data.form);
}

 uni-app小程序http请求2

const baseURL = 'https://open.www.cn';
/**
 * 对于网络请求,设置参数默认值
 */
const DEFAULT_REQUEST_OPTIONS = {
  baseURL,
  timeout:1000*5,
	header: { 
    "Content-Type": "application/json",
    'x-token': 'x-token'  // token 看自己是否需要
  },
}
/**
 * 请求的封装
 * @param {String} url 请求的接口地址
 * @param {String} method 请求的方法
 * @param {Object} data 请求的参数
 * @param {Object} option 请求头的配置
 */
const request = (url, method='GET', data={}, option={}) => {
  uni.showLoading({
    title: '加载中...',
  });
  // 合并配置,在配置信息中提取需要的部分
  let { baseURL, header} = Object.assign({}, DEFAULT_REQUEST_OPTIONS, option)
  return new Promise((resolve, reject) => {
    uni.request({
      url: baseURL + url,
      data,
      header,
      method,
      success: res => {
        console.log('响应:',res);
        uni.hideLoading()
        if (res.statusCode === 200) {
          //200: 服务端业务处理正常结束
          resolve(res.data)
        } else {
          //其它错误,提示用户错误信息
          console.error(res);
          reject(res)
          if(res.statusCode == 404){
            uni.showToast({
              title: '数据不存在',
              icon:'none'
            })
          }
        }
      },
      fail: res => {
        console.error(res);
        uni.hideLoading()
        reject(res)
      }
    })
  })
}
/**
 * GET请求
 * @param {String} url 请求接口地址
 * @param {Object} data 请求参数
 * @param {Object} option 请求头的配置
 */
export const getApi = (url, data, option) => request(url, 'GET', data, option);
/**
 * POST请求
 * @param {String} url 请求接口地址
 * @param {Object} data 请求参数
 * @param {Object} option 请求头的配置
 */
export const postApi = (url, data, option) => request(url, 'POST', data, option);

uni-app小程序main.js文件

import App from './App'
import uView from '@/uni_modules/uview-ui'
// #ifndef VUE3
import Vue from 'vue'
Vue.use(uView)
Vue.config.productionTip = false
App.mpType = 'app'

try {
  function isPromise(obj) {
    return (
      !!obj &&
      (typeof obj === "object" || typeof obj === "function") &&
      typeof obj.then === "function"
    );
  }


  // 统一 vue2 API Promise 化返回格式与 vue3 保持一致
  uni.addInterceptor({
    returnValue(res) {
      if (!isPromise(res)) {
        return res;
      }
      return new Promise((resolve, reject) => {
        res.then((res) => {
          if (res[0]) {
            reject(res[0]);
          } else {
            resolve(res[1]);
          }
        });
      });
    },
  });
} catch (error) { }

const app = new Vue({
  ...App
})
app.$mount()
// #endif

// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
  const app = createSSRApp(App)
  return {
    app
  }
}
// #endif

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值