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