uniapp小程序开发记录
#uni.request的请求封装
uni.request不是异步的需要通过Promise封装后才可以实现then回调.
export default(requestUrl, type, params) {
return new Promise((resolve, reject) => {
uni.request({
header: {
authorization: getToken(),
},
url: requestUrl,
method: type,
data: params,
success(res) {
resolve(res);
},
fail(err) {
reject(err);
},
complete() {
uni.hideLoading();
},
});
});
}
#开发环境和正式环境请求地址处理
当开发环境和正式环境的后端请求地址不同时可以通过创建一个js文件,然后在里面进行判断处理,如下
// process.env.NODE_ENV === 'development' => 为开发环境时
const domain = process.env.NODE_ENV === 'development'?"开发环境后端地址":"线上后端地址"
export default domain
然后在封装请求的js文件中引入使用即可。
#地图的使用(map组件、高德地图api)
##map组件
map组件官方文档
// 常用的基础属性
/*
latitude:地图中心点的经度
longitude:地图中心点的纬度
scale:缩放级别,取值范围为5-18。默认为16
marker:标记点(可以用来展示附近的服务点如加油站、餐厅等等)
include-points:缩放视野以包含所有给定的坐标点
show-location:显示带有方向的当前定位点
...等
*/
<map
@markertap="handleMarkerTap"
style="width: 100%; height: 100%;"
:latitude="latitude"
:longitude="longitude"
:include-points="covers"
:markers="covers"
:scale="scale"
show-location='true'
></map>
map的当前位置经纬度获取可以通过uniapp已有的方法uni.getLocation,也可以使用Promise封装一下方便使用
getLocation官方文档
// 获取当前位置
getLocation() {
return new Promise((resolve, reject) => {
uni.showLoading({
title: '加载中'
});
uni.getLocation({
type: "gcj02",
altitude: true,
success: function(res) {
resolve(res);
},
fail:function(err) {
reject(err)
},
complete: function(res) {
uni.hideLoading()
}
});
});
},
##通过高德地图api获取附近地点
地图api封装,key需要自己申请
不清楚的可以参考高德Api的key申请
// 高德地图api
const mapApi = {
get(url, data) {
uni.showLoading({
title: "加载中...",
mask: true,
});
return new Promise((resolve, reject) => {
uni.request({
url,
data: { ...data, key: "申请的Key" },
header: { "content-type": "application/json" },
method: "GET",
dataType: "json",
responseType: "text",
success: (result) => {
resolve(result);
},
fail: (err) => {
reject(err);
},
complete: () => {
uni.hideLoading();
},
});
});
},
};
export default {
/**
* 根据关键字获取附近服务位置
* @param {*} data
* data参数必须包含 当前位置 location , 关键字 keywords,和用户申请的key
* 例如 data: { location: `${this.longitude},${this.latitude}`, keywords: "加油站", key: key}
*
* @returns
*/
getAround(data) {
return mapApi.get("https://restapi.amap.com/v3/place/around", data);
},
/**
*根据关键字搜索对应位置
* @param {*} data
* data参数包含key必填,keywords(查询关键字)或types(查询POI类型)二选一必填,city=>所选城市、不填则全国范围搜索
* @returns
*/
getPlace(data) {
return mapApi.get("https://restapi.amap.com/v3/place/text", data);
},
};
引入封装的方法,然后进行接口调用
// 引入mapApi
import mapApi from "@/api/map";
getAround() {
let params = {
keywords: this.keywords,
location: `${this.longitude},${this.latitude}`
};
mapApi.getAround(params).then(res => {
// 经纬度是通过location返回的,是一个用,分隔的字符串
// 将pois数据赋给cover后地图上就会标点出来
res.data.pois.forEach((item, index) => {
item.latitude = item.location.split(",")[1]
item.longitude = item.location.split(",")[0]
this.covers.push(item);
});
});
}
通过uni.openLocation唤起内置地图后可以打开手机地图软件进行精确导航
官方文档地址
// 传入目标地点的经纬度
uni.openLocation({
latitude: latitude,
longitude: longitude,
success: res => {
console.log("success", res);
},
fail: err => {
console.log("fail", err);
},
complete: () => {
console.log("complete");
}
});
#微信小程序权限配置
位置接口
可以在HBuilder中的manifest.json里进行设置
或者到manifest.json代码中加入
"permission": {
"scope.userLocation": {
"desc": "使用地图功能需要获取您的位置信息"
}
}
#上传图片到服务器
定义组件
<template>
<view class="page">
<view class="address-box add-box">
<!-- 没被禁用时
可以上传图片
禁用时,只能查看后端返回的详情数据图片
-->
<!-- 上传图片 开始 -->
<view class="add-img-box" v-if="!disabled">
<view class="add-img-item" v-for="(item, index) in imgList" :key="index">
<image class="add-img border" @tap="imgInfo(index)" :src="item.path" mode="aspectFill" />
<view @tap="delImg(index)" class="mine-iconfont icon_close"></view>
</view>
<view v-if="imgList.length < imgCount" class="add-img-item" @tap="openCamera">
<view class="add_img">
<view class="content">
<view class="mine-iconfont icon_add"></view>
<view class="text">上传照片</view>
</view>
</view>
</view>
<view class="tips">{{`最多可上传${imgCount}张照片`}}</view>
</view>
<!-- 上传图片 结束 -->
<!-- 已有图片展示 开始 -->
<view class="add-img-box" v-else>
<view class="add-img-item" v-for="(item, index) in file_list" :key="index">
<image
@tap="imgInfo(index)"
class="add-img border"
:src="`http://file.bmmyou.com/file/${item.response.data.url_name}`"
mode="aspectFill"
/>
</view>
</view>
<!-- 已有图片展示 结束 -->
</view>
</view>
</template>
<script>
import { uploadFile } from "@/utils/public";
export default {
props: {
// 是否禁用
disabled: {
type: Boolean,
default: false
},
// 服务器图片列表
file_list: {
type: Array
}
},
data() {
return {
imgList: [],
cloudimgList: ["../../../static/images/avator.png"],
imgCount: 5, //最多支持5张上传,可以修改
percent: "",
pic_list: []
};
},
watch: {
file_list: {
handler(newVal, oldVal) {
console.log(newVal);
},
deep: true,
immediate: true
}
},
onLoad(e) {},
methods: {
// 上传图片并将url集合返回给父组件
submit(e) {
this.imgList.forEach((img, index) => {
uploadFile("http://upload.bmmyou.com/index/uploadfile", img.path, {
devicetype: "app"
}).then(res => {
let json = {
response: { data: { url_name: JSON.parse(res.data).data.url_name } }
};
this.pic_list.push(json);
if (this.pic_list.length === this.imgList.length) {
this.$emit("handleSubmit", this.pic_list);
}
});
});
},
// 点击图片查看大图
imgInfo(i) {
let tempList = [];
if (this.disabled) {
this.file_list.forEach(img => {
tempList.push(
`http://file.bmmyou.com/file/${img.response.data.url_name}`
);
});
} else {
this.imgList.forEach(img => {
tempList.push(img.path);
});
}
//显示图片
uni.previewImage({
current: i,
loop: false,
urls: tempList,
indicator: "default"
});
},
// 删除图片
delImg(i) {
uni.showModal({
content: "确定删除这张图片吗?",
success: res => {
if (res.confirm) {
this.imgList.splice(i, 1);
} else if (res.cancel) {
}
}
});
},
// 选择本地图片上传
openCamera() {
let _self = this;
uni.chooseImage({
sourceType: ["album"],
count: this.imgCount,
sizeType: ["compressed"],
success: res => {
this.imgList = [...this.imgList, ...res.tempFiles];
const tempFilePaths = res.tempFilePaths;
},
error: function(e) {
console.log(e);
}
});
}
}
};
</script>
<style lang="scss" scoped>
.address-box {
display: flex;
flex-direction: row;
align-items: center;
padding: 15rpx 40rpx;
margin-bottom: 10px;
}
.add-box {
padding: 15rpx 0;
flex-wrap: wrap;
}
.border {
border: 2rpx solid rgba(0, 0, 0, 0.15);
}
.add-img-box {
display: flex;
padding-left: 10rpx;
flex-direction: row;
flex-wrap: wrap;
}
.add-img-item {
margin: 0 20rpx 20rpx 0;
position: relative;
.add_img {
width: 208rpx;
height: 208rpx;
position: relative;
border-radius: 8rpx;
background-color: rgba(0, 0, 0, 0.02);
border: 2rpx dashed rgba(0, 0, 0, 0.15);
}
.add_tips {
white-space: nowrap;
color: rgba(0, 0, 0, 0.45);
font-size: 28rpx;
margin-top: 16rpx;
}
}
.add-img-camera {
flex: 1;
}
.add-img {
width: 208rpx;
height: 208rpx;
}
.line {
height: 1px;
transform: scaleY(0.3);
background-color: rgba(0, 0, 0, 0.5);
}
.content {
display: flex;
flex-direction: column;
align-content: center;
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 0;
right: 0;
.icon_add {
color: rgba(0, 0, 0, 0.45);
font-size: 50rpx;
margin-bottom: 28rpx;
display: flex;
justify-content: center;
}
.text {
display: flex;
justify-content: center;
font-size: 28rpx;
color: rgba(0, 0, 0, 0.65);
}
}
.icon_close {
position: absolute;
color: rgba(204, 204, 204, 1);
font-size: 44rpx;
right: -22rpx;
transform: translateY(-50%);
top: 0;
}
</style>