uni.requet()、网络模块封装

1. uni-app网络请求

uni-app题拱了uni.requet()方法,发起网络请求:

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

2. uni.request()未封装VUE组件中的使用


getList:function(){
    var _self=this;
    var token = uni.getStorageSync(_self.sessionKey);
    uni.request({
        url: 'https://ceshi2.dishait.cn/api/v1',
        method: 'GET',
        data: {
            token : token,
            timestamp : timestamp
                   },
        success: res => {
            if (res.data.code == "401") {//登录失效
                //弹框提示
                uni.showToast({
                    title: res.data.msg,
                    mask: false,
                    duration: 1500
                });
            } else if (res.data.code == "0") {
                var data = res.data.data;
                _self.onlineNum = data.onlineNum;
                _self.machineNum = data.machineNum;
            }else {
                console.log("未处理的结果码");
            }
                    
        },
        fail: (e) => {
            console.log("getMachineNum fail:" + JSON.stringify(e));
        },
        complete: () => {}
    });
},

返回结果:

{
  "data": {
    "code": "0",
    "msg": "success",
    "data": {
      "machineNum": 124,
      "onlineNum": 1,
      
    }
  },
  "header": {
    "Server": "nginx/1.14.0",
    "Date": "Thu, 11 Apr 2019 03:08:20 GMT",
    "Content-Type": "application/json;charset=utf-8;",
    "Transfer-Encoding": "chunked",
    "Connection": "keep-alive",
    "X-Powered-By": "PHP/7.1.16"
  },
  "statusCode": 200,
  "cookies": [],
  "errMsg": "request:ok"
}

3.uniapp封装网络请求

1. 我们先通过Promise进行一次简单封装,新建request.js文件:


//options参数我们后面会说
function service(options = {}) {
return new Promise((resolved, rejected) => {
uni.request({
   url: options.url, //仅为示例,并非真实接口地址。
   data: options.data,
   header: {
       'content-type': 'application/x-www-form-urlencoded',
       'token': `${token}` //权限token 
   },
   success: (res) => {
      rejected(res.data);
   }.fail = (err) => {
   rejected(err)
 }
});
}
}
export default service;

2. 在common目录下新建config.js
放置我们的多环境变量,方便后期切换环境

export default {
	// api请求前缀
	// webUrl : 开发环境前缀,
	webUrl:'https://ceshi2.dishait.cn/api/v1',
	//testUrl : 测试环境前缀
	testUrl:'https://ceshi3.dishait.cn/api/v1',
	//proUrl : 生产环境前缀
	proUrl:'https://ceshi.dishait.cn/api/v1',
	// websocket地址
	websocketUrl:"wss://ceshi2.dishait.cn/wss",
}

 现在目录如下:

┌─common
│ ├─config.js //请求
│ ├─request.js //请求
┌─pages
│ ├─index
│ │ └─index.vue //页面文件
├─static
├─store
│ ├─index.js //vuex
├─main.js
├─App.vue
├─manifest.json
└─pages.json

3. 接下来我们对requst.js进行一次优化。

//把配置项单独处理

import $C from '@/common/config.js'; // 引入baseUrl
import $store from '@/store/index.js';//vuex

export default {
    //定义默认请求参数
	common:{
		method: 'GET',
		header:{
			"content-type":"application/json"
		},
		data:{}
	},
	request(options = {}){
		options.url = $C.webUrl + options.url
		options.method = options.method || this.common.method
		options.header = options.header || this.common.header
		
		// 验证权限token
		if(options.token){
			options.header.token = $store.state.token
			if(!options.header.token){
				return uni.showToast({
					title: '非法token,请重新登录',
					icon: 'none'
				});
			}
		}
		
		return new Promise((res,rej)=>{
			uni.request({
				...options,
				
				success: (result) => {
					// 返回原始数据
					// console.log(result);
					if(options.native){
						return res(result)
					}
					// 请求服务端失败
					if (result.statusCode !== 200 && !options.notoast) {
						uni.showToast({
							title:result.data.msg || '请求失败',
							icon: 'none'
						});
						return rej(result.data)
					}
					// 成功
					res(result.data.data)
				},
				fail:(error)=>{
					uni.showToast({
						title: error.errMsg || '请求失败',
						icon: 'none'
					});
					return rej()
				}
			});
		})
	},
	// 单独封装 get 方式请求
	get(url,data = {},options = {}){
		options.url = url
		options.data = data
		options.method = 'GET'
		return this.request(options)
	},
	// 单独封装 post 方式请求
	post(url,data = {},options = {}){
		options.url = url
		options.data = data
		options.method = 'POST'
		return this.request(options)
	},
	// 单独封装 文件上传 方式请求 ,不需要则可以暂时不封装
	upload(url,options = {}){
		options.url = $C.webUrl + url
		options.header = options.header || {}
		// 验证权限token
		if(options.token){
			options.header.token = $store.state.token
			if(!options.header.token){
				return uni.showToast({
					title: '非法token,请重新登录',
					icon: 'none'
				});
			}
		}
		
		return new Promise((res,rej)=>{
			uni.uploadFile({
				...options,
				success: (uploadFileRes) => {
					if(uploadFileRes.statusCode !== 200){
						return uni.showToast({
							title: '上传图片失败',
							icon: 'none'
						});
					}
					let data = JSON.parse(uploadFileRes.data)
					res(data)
				},
				fail:(err)=>{
					rej(err)
				}
			});
		})
		
	}
}

 4. 在main.js总,导入request.js ,并挂载到Vue原型上。

// 引入请求库
import $H from './common/request.js';
Vue.prototype.$H = $H
  1. 组件使用,login.vue
  2. <template>
    	<view>
    	
    		<view class="text-center" style="padding-top: 130rpx;padding-bottom: 70rpx;font-size: 55rpx;">账号密码登录</view>
    		
    		<view class="px-2">
    			<template>
    				<view class="mb-2">
    					<input type="text" v-model="username" placeholder="昵称/手机号/邮箱" class="border-bottom p-2"/>
    				</view>
    				<view class="mb-2 flex align-stretch">
    					<input type="text" v-model="password" placeholder="请输入密码" class="border-bottom p-2 flex-1"/>
    					<view class="border-bottom flex align-center justify-center font text-muted" style="width: 150rpx;">忘记密码?</view>
    				</view>
    			</template>
    			
    		</view>
    		
    		<view class="py-2 px-3">
    			<button class="text-white" style="border-radius: 50rpx;border: 0;" type="primary" :disabled="disabled" :class="disabled ? 'bg-main-disabled':'bg-main'" @click="submit" :loading="loading"> 登录 </button>
    		</view>
    		
    		<view class="flex align-center justify-center pt-2 pb-4">
    			<view class="text-primary font-sm" @click="changeStatus">
    				{{status?'账号密码登录':'验证码登陆'}}
    			</view>
    			<text class="text-muted mx-2">|</text>
    			<view class="text-primary font-sm">登录遇到问题</view>
    		</view>
    		
    		<view class="flex align-center justify-center">
    			<view style="height: 1rpx;background-color: #dddddd;width: 100rpx;"></view>
    			<view class="mx-2 text-muted">社交账号登录</view>
    			<view style="height: 1rpx;background-color: #dddddd;width: 100rpx;"></view>
    		</view>
    		
    		
    		<view class="flex align-center justify-center text-muted">
    			注册即代表同意<text class="text-primary">《xxx社区协议》</text>
    		</view>
    		
    	</view>
    </template>
    
    <script>
    
    	export default {
    		components: {
    			
    		},
    		data() {
    			return {
    				username:"",
    				password:""
    			}
    		},
    		methods: {	
    			// 提交
    			submit(){
    				let data ={
    						username:this.username,
    						password:this.password
    					}
    				// 提交后端
    				this.$H.post(url,data).then(res=>{
    					console.log(res);
    					// 修改vuex的state,持久化存储
    					this.$store.commit('login',res)
    				
    					uni.showToast({
    						title: '登录成功',
    						icon: 'none'
    					});
    				}).catch(err=>{
    					// 登录失败
                        console.log('登陆失败')
                    })		
    							
    			}
    		}
    	}
    </script>
    
    <style>
    
    </style>
    
    
    

上一篇:从Uniswap v3来看新的期权范式?


下一篇:uni-app更换头像(自用瞎写的)