前言

只要是前端,不管什么框架和语言,都避免不了和服务端请求数据,以下是uniapp提供的APIuni.request

uni.request({
    url: 'https://www.example.com/request', //仅为示例,并非真实接口地址。
    data: {
        text: 'uni.request'
    },
    header: {
        'custom-header': 'hello' //自定义请求头信息
    },
    success: (res) => {
        console.log(res.data);
        this.text = 'request success';
    }
});

为了提高开发效率,封装可以使开发过程更加的酣畅淋漓。

实现

一般选择在外面的根目录下,创建utils文件夹,utils文件夹下创建http.jsrequest.js

  • utils/http.js
  • utils/request.js
request.js

封装request请求的文件

import config from "@/config";  // 配置文件
import storage from "./storage"; // 缓存封装

export default {
	console(options){
		if(config.debug){
			// console.log("<<===============================================>>");
			// console.log("request start");
			// console.log("header" + JSON.stringify(options.header));
			// console.log("method: " + options.method + " URL: " + options.url);
			// console.log(options.data);
			// console.log("request end");
			// console.log("<<===============================================>>");
		} 
	},
	domain(){
		return config.uni_app_web_api_url.replace("api","");
	},
	send(options={}){
        // loading加载
        uni.showLoading({
           title: '加载中'
        });
        
        // 拼接路劲,下面的配置文件会提到
		options.url = config.uni_app_web_api_url + '' + options.url;
        // 请求方式
		options.method = options.method || "GET";
		
        // 这里看项目的情况来定,如果是没有token,那就删除这里,上面的storage也不需要引入
		let users = storage.getJson("users");
		if(users != null){
			options.header = { "Auth-Token" : users.token };
		}
		
		this.console(options);  // 打印请求数据,调试用,上线可以注释
        
        // 发起Promise请求
		return new Promise((resolve, reject) =>{
			uni.request(options).then(data=>{
				var [error, res] = data;
				if(error != null){
					reject(error);
				}else{
                    // 相应拦截、根据后端的状态码来写,可以自行判断和封装
					if(res.data.status == '-1001'){
						uni.hideLoading();
						uni.navigateTo({
						    url: '/pages/Login/login/login'
						});
					}else{
						resolve(res.data); 
					}
				}
			});
		});
	},
	get(url="",data={}){
		return this.send({
			url: url,
			data: data
		});
	},
	post(url="",data={}){
		return this.send({
			url: url,
			data: data,
			method: "POST"
		});
	}
};
  • 平时用的多的主要还是getpost,因此就封装了两个,如果还有更多的,可以把里面的内容单独提取出来,然后再定义putdelete等方法
http.js

封装的api接口

import request from './request'

// get请求
export function getBannerList(params) {
    return new Promise((resolve, reject)=>{
        request.get("/banner/getList", params).then((result)=>{
            resolve(result)
        }).catch(err=>{
            reject(err)
        });
    });
}

// post请求
export function addBanner(params) {
    return new Promise((resolve, reject) => {
        request.post("/banner/add", params).then((result)=>{
            resolve(result);
        }).catch((error)=>{
            reject(error);
        });
    });
}

// 如果说比较懒,或者是不想这么麻烦,也可直接用这两个,调用的时候第一个参数换成接口地址即可
export function httpGet(url, params) {
  return new Promise((resolve, reject)=>{
      request.get(url, params).then((result)=>{
          resolve(result)
      }).catch(err=>{
          reject(err)
      });
  });
}

export function httpPost(url, params) {
  return new Promise((resolve, reject)=>{
      request.post(url, params).then((result)=>{
          resolve(result)
      }).catch(err=>{
          reject(err)
      });
  });
}

实际使用

在页面使用

<template>
  <view class="page"> </view>
</template>

<script>
export default {
  data() {
    return {
      bannerList: [],
    };
  },
  onLoad() {
    this.loadData();
  },
  methods: {
    loadData() {
      this.$http
        .getBannerList()
        .then((res) => {
          if (res.code == 1) {
            // 根据后端接口的情况,如果需要自己拼接,则自行拼接,不需要则删除
            res.banner.forEach((val) => {
              val = this.$config.uni_app_web_url + val;
            });

            this.bannerList = res.data;
              
          } else {
            // 提示网络错误
            uni.showToast({
              title: "网络错误,请重试~",
              icon: "none",
              duration: 2000,
            });
          }
        })
        .catch((error) => {
          console.log(error);
        });

    },
  },
};
</script>

<style scoped lang="scss">
</style>
  • 以下还有几个配置文件,磨刀不误砍柴工,都可以放在utils目录下

配置文件

config.js

此文件放在根目录,和main.js同级即可

export default {
	web_name: "网站名称", 
	
	uni_app_web_url: "http://baidu.com/", // h5域名PC域名,用于分享图片或者拼接图片时使用,结尾必须加 “/”
	uni_app_web_api_url: "http://baidu.com/api", // 请求接口的地址
	
	debug: true
}
storage.js

缓存封装,一些需要用的数据,可以放进去,类似token,语言,主题之类的。

export default {
	
	set(name,value){
		uni.setStorageSync(name,value);
	},
	
	setJson(name,value){
		uni.setStorageSync(name,JSON.stringify(value));
	},
	
	get(name){
		return uni.getStorageSync(name);
	},
	
	getJson(name){
		const content = uni.getStorageSync(name);
		if(!content){
			return null;
		}
		
		return JSON.parse(content);
	},
	
	remove(name){
		uni.removeStorageSync(name);
	},
	
	clear(){
		uni.clearStorageSync();
	}
};
main.js

这是根目录下的main.js

import Vue from 'vue';
import App from './App';

import * as http from './utils/http' // http请求接口
import * as utils from './utils/utils' // 工具文件
import * as common from './utils/common' // 公共文件
import store from './store' // vuex,不需要的可以自行删除
import storage from 'utils/storage' // 缓存文件
import config from '@/config' // 配置

// 定义全局
Vue.prototype.$store = store
Vue.prototype.$storage = storage
Vue.prototype.$http = http
Vue.prototype.$utils = utils
Vue.prototype.$common = common
Vue.prototype.$config = config

App.mpType = 'app'
const app = new Vue({
    ...App
})
app.$mount()

扩展

utils.js

很多可以公共使用的方法,为你准备好了

export function msg(content,time=3000){
	uni.showToast({
		icon:'none',
		title: content,
		duration: time
	});
}

export function showLoading(content="加载数据中...",mask=true){
	uni.showLoading({
	    title: content,
		mask: mask
	});
}

export function hideLoading(timer=0){
	if(timer > 0){
		var t = setTimeout(function () {
		    uni.hideLoading();
			clearTimeout(t);
		}, timer);
	}else{
		uni.hideLoading();
	}
}

export function in_array(search,array){
	let flag = false;
	for(let i in array){
		if(array[i]==search){
			flag = true;
			break;
		}
	}

	return flag;
}

export function isDataType(data,type){
	return Object.prototype.toString.call(data) === '[object '+type+']';
}

export function ltrim(str,char){
	let pos = str.indexOf(char);
	let sonstr = str.substr(pos+1);
	return sonstr;
}

export function rtrim(str,char){
	let pos = str.lastIndexOf(char);
	let sonstr = str.substr(0,pos);
	return sonstr;
}

/**
 * 保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面。
 */
export function navigateTo(url,params){
	uni.navigateTo({
		url: parseUrl(url,params)
	})
}

/**
 * 关闭当前页面,跳转到应用内的某个页面。
 */
export function redirectTo(url,params){
	uni.redirectTo({
		url: parseUrl(url,params)
	});
}

/**
 * 关闭所有页面,打开到应用内的某个页面。
 */
export function reLaunch(url,params){
	uni.reLaunch({
		url: parseUrl(url,params)
	});
}

/**
 * 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
 */
export function switchTab(url,params){
	uni.switchTab({
		url: parseUrl(url,params)
	});
}

/**
 * 关闭当前页面,返回上一页面或多级页面
 */
export function navigateBack(delta){
	uni.navigateBack({
		delta: delta
	});
}

/**
 * 预加载页面,是一种性能优化技术。被预载的页面,在打开时速度更快。
 */
export function preloadPage(url, params){
	uni.preloadPage({
		url: parseUrl(url,params)
	});
}

export function prePage(){
	let pages = getCurrentPages();
	let prePage = pages[pages.length - 2];
	// #ifdef H5
	return prePage;
	// #endif
	return prePage.$vm;
}

/**
 * rpx转px
 * @param int|float num
 */
export function rpx2px(num){
	// const info = uni.getSystemInfoSync()
	// let scale = 750 / info.windowWidth;
	// return (Number.isNaN(parseFloat(num)) ? 0 : parseFloat(num)) / scale;
	return uni.upx2px(num);
}

/**
 * @param int|float num
 */
export function px2rpx(num){
	return num/(uni.upx2px(num)/num);
}

/**
 * 获取窗口的宽高
 */
export function getSystemInfo(){
	const info = uni.getSystemInfoSync();
	return {
		w: info.windowWidth,
		h: info.windowHeight
	};
}

/**
 * 功能:路由解析并且拼接
 * 使用:parseUrl('home', {id:1,type: 'add'})
 * 得到:'/pages/home?id=1&type=add'
 */
function parseUrl(url,params){
	let arr = [];
	let string = '';
	for(let i in params){
		arr.push(i + "=" + params[i]);
	}
	
	string = "/pages/" + url;
	if(arr.length > 0){
		string += "?" + arr.join("&");
	}
	
	return string;
}
  • 使用

    this.$utils.msg("消息提示")
    this.$utils.navigateTo("login") // 页面跳转
    
store/index.js

根目录下创建store,里面的index.js,这里参考vuex

import Vue from 'vue'
import Vuex from 'vuex'
import storage from '../common/storage'

Vue.use(Vuex);

const store = new Vuex.Store({
	// 属性值
	state: {
		users: storage.getJson("users")
	},
	// 对外方问state属性内容
	getters: {
		getCart: state => {
			let users = storage.getJson("users");
			if(users == null){
				return 0;
			}

			return users.shop_count;
		}
	},
	// Mutation 必须是同步函数
	// 更改state属性内容
	// 使用:this.$store.commit("setUserInfo",{  });
	mutations: {
		UPDATEUSERS(state, data){
			state.users = data;
			storage.setJson("users",data);
		},
		DELETEUSERS(state,name){
			state.users = null;
			storage.remove(name);
		},
		UPDATECART(state, data){
			state.users.shop_count = data;
			let users = storage.getJson("users");
			users.shop_count = data;
			storage.setJson("users",users);
		}
	},
	// Action 可以包含任意异步操作
	// 通过 context.commit 可以方问mutations方法
	// 也可以获得getters内容
	// 通过 this.$store.dispatch("getUser") 来取得内容
	actions: {
		getCart(context){
			
		},
		usersStatus(context){
			return new Promise(function (resolve, reject) {
				if(storage.getJson("users") == null){
					reject();
				}else{
					resolve();
				}
			});
		}
	}
})

export default store
  • 参考vuex使用方式

这是比较全面的文件,大家可以根据自己的情况来引入文件,如果只是单单的接口请求,那就上面的几个文件,扩展文件不用即可。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐