//cinema.wxml
<van-dropdown-menu>
<van-dropdown-item value="{{ value1 }}" options="{{ option1 }}" bind:change='select' />
</van-dropdown-menu>
<view class="bigbox">
<view class="bc-fff main" wx:for="{{list}}" wx:key="cinemaId">
<view class="first">
<view class="flex jc-sb">
<text>{{item.name}}</text>
<text class="f14 base"> ¥{{item.lowPrice}} <text class="f12">元起</text> </text>
</view>
<view class="f14 flex jc-sb mt-5">
<text>{{item.address}}</text>
<text>{{item.distance}}</text>
</view>
<view class="f12 mt-5">
<text class="box1">退</text>
<text class="box1 ml-5">改签</text>
<text class="box2 ml-5">小吃</text>
<text class="box2 ml-5">折扣卡</text>
</view>
<view class="mt-5 flex ai-c">
<image src="../../img/ka.png" alt="1"></image>
<text class="f14 text1">开卡特惠,首单1张最高立减4元</text>
</view>
</view>
</view>
</view>
<view class="flex ai-c jc-c" wx:if="{{show}}">加载完毕,没有更多了</view>
//cinema.wxss
.head {
height: 46px;
top: 0;
}
.head .left,
.head .right {
width: 60px;
}
.head image {
height: 20px;
width: 20px;
}
.bigbox {
margin-bottom: 60px;
}
.main {
border-bottom: 1px solid #f5f5f5;
}
.main .first {
padding: 15px;
}
.main .first .box1 {
border: 1px solid #589daf;
color: #589daf;
padding: 0px 5px;
}
.main .first .box2 {
border: 1px solid #ff9900;
color: #ff9900;
padding: 0px 5px;
}
.main .first image {
width: 15px;
height: 15px;
}
.main .first .text1 {
color: #999;
}
footer {
bottom: 0px;
height: 50px;
}
//app.wxss
/**app.wxss**/
.container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 200rpx 0;
box-sizing: border-box;
}
/* 公共样式 */
/* body的背景颜色 */
body {
background-color: rgb(244, 244, 244);
font-family: -apple-system,BlinkMacSystemFont,'Helvetica Neue',Helvetica,Segoe UI,Arial,Roboto,'PingFang SC',miui,'Hiragino Sans GB','Microsoft Yahei',sans-serif;
}
/* 文本居中 */
.ta-c {
text-align: center;
}
/* 相对定位 */
.po-r {
position: relative;
}
/* 绝对定位 */
.po-a{
position: absolute
}
/* 固定定位 */
.fixed {
position: fixed;
}
/* 隐藏 */
.dis-n {
display: none;
}
/* 宽度100% */
.w100 {
width: 100%;
}
.h100 {
height: 100%;
}
/* 颜色 */
.fff {
color: #fff;
}
.c9{
color: #999;
}
.bc-c9{
background-color: #999;
}
.bc-fff {
background-color: #fff;
}
.base {
color: #f03d37;
}
.bc-base {
background-color: #f03d37;
}
/* 字体 */
.f10 { font-size: 10px; }
.f12 { font-size: 12px; }
.f14 { font-size: 14px; }
.f16 { font-size: 16px; }
.f18 { font-size: 18px; }
.f20 { font-size: 20px; }
.f22 { font-size: 22px; }
.f24 { font-size: 24px; }
.f26 { font-size: 26px; }
.f28 { font-size: 28px; }
.f30 { font-size: 30px; }
.f32 { font-size: 32px; }
.f34 { font-size: 34px; }
.f36 { font-size: 36px; }
/* 弹性盒子 */
.flex { display: flex; }
.jc-c { justify-content: center; }
.jc-sb { justify-content: space-between; }
.jc-sa { justify-content: space-around; }
.ai-c { align-items: center; }
/* 盒子反向 */
.fd-c {
display: flex;
flex-direction: column;
}
/* 剩余空间分配 */
.fg1 { flex-grow: 1; }
/* margin */
.mt-5 {margin-top: 5px;}
.mt-10 {margin-top: 10px;}
.mt-15 {margin-top: 15px;}
.mt-20 {margin-top: 20px;}
.mt-25 {margin-top: 25px;}
.mt-30 {margin-top: 30px;}
.ml-5 {margin-left: 5px;}
.ml-10 {margin-left: 10px;}
.ml-15 {margin-left: 15px;}
.ml-20 {margin-left: 20px;}
.ml-25 {margin-left: 25px;}
.ml-30 {margin-left: 30px;}
.mr-5 {margin-right: 5px;}
.mr-10 {margin-right: 10px;}
.mr-15 {margin-right: 15px;}
.mr-20 {margin-right: 20px;}
.mr-25 {margin-right: 25px;}
.mr-30 {margin-right: 30px;}
.mb-5 {margin-bottom: 5px;}
.mb-10 {margin-bottom: 10px;}
.mb-15 {margin-bottom: 15px;}
.mb-20 {margin-bottom: 20px;}
.mb-25 {margin-bottom: 25px;}
.mb-30 {margin-bottom: 30px;}
.mb-55 {margin-bottom: 55px;}
/* padding */
.pt-5 {padding-top: 5px;}
.pt-10 {padding-top: 10px;}
.pt-15 {padding-top: 15px;}
.pt-20 {padding-top: 20px;}
.pt-25 {padding-top: 25px;}
.pt-30 {padding-top: 30px;}
.pl-5 {padding-left: 5px;}
.pl-10 {padding-left: 10px;}
.pl-15 {padding-left: 15px;}
.pl-20 {padding-left: 20px;}
.pl-25 {padding-left: 25px;}
.pl-30 {padding-left: 30px;}
.pr-5 {padding-right: 5px;}
.pr-10 {padding-right: 10px;}
.pr-15 {padding-right: 15px;}
.pr-20 {padding-right: 20px;}
.pr-25 {padding-right: 25px;}
.pr-30 {padding-right: 30px;}
.pb-5 {padding-bottom: 5px;}
.pb-10 {padding-bottom: 10px;}
.pb-15 {padding-bottom: 15px;}
.pb-20 {padding-bottom: 20px;}
.pb-25 {padding-bottom: 25px;}
.pb-30 {padding-bottom: 30px;}
.pb-40 {padding-bottom: 40px;}
.pb-50 {padding-bottom: 50px;}
.pl-16{
padding-left: 16px;
}
.pr-16{
padding-right: 16px;
}
步骤:
1.先将静态页面转换,css样式和公共样式导入进去
2.先获取本地的经纬度wx.getLocation({}),将其用函数封装,在函数onLoad(){}中调用
getLocation() {
wx.getLocation({
type: 'wgs84',
success: (res) => {
// res里面包含了经纬度
console.log("定位信息",res);
let {
latitude,
longitude
} = res;
this.setData({
location: {
latitude,
longitude
}
})
this.getList();
},
fail: (err) => {
this.setData({
city: '定位失败,请手动选择'
})
}
})
},
ps:定位当前经纬度,所在的城市 //本应用不需要
getCityName({
latitude,
longitude
}){
let url = `https://apis.map.qq.com/ws/geocoder/v1/?location=${latitude},${longitude}&key=3YKBZ-33W36-CGUSR-EKEXO-RC7QS-KNFRN`;
wx.request({
url,
success:(res)=>{
let cityName = res.data.result.ad_info.city;
this.setData({
cityName
});
this.getCinemaList() //调用函数发送请求获取列表
}
})
},
3.由于需要渲染的页面头部是个组件(下拉框可以选择城市的),组件可以查看
微信开放文档和Vant Weapp - 轻量、可靠的小程序 UI 组件库
//wxml页面
<van-dropdown-menu>
<van-dropdown-item value="{{ value1 }}" options="{{ option1 }}" bind:change='select' />
</van-dropdown-menu
//js页面
Page({
data: {
option1: [{
text: '深圳',
value: 0
},
{
text: '上海',
value: 1
},
{
text: '广州',
value: 2
}, {
text: '北京',
value: 3
},
],
value1: 0,
},
});
select(e) {
let index = e.detail; //绑定的点击事件,可以获取下标,方便渲染
this.setData({
index: index,
list:[] //为了后期的渲染,需要清空list,
})
this.getList();
},
4.当第二步获取当地经纬度,将调用函数this.getList(),不要在onLoad中调用,防止异步事件,结算经纬度的结果为NaN
getList() {
console.log("获取接口信息"); //用来调试异步问题,已解决
const params = {
//点击组件下拉框,之前的点击事件获取的下标,index,在option1里面都有对应的城市渲染。
cityName: this.data.option1[this.data.index].text,
currPage: this.data.currPage
};
app.get('/cinema/list', params).then(res => {
//用if判断数据是否渲染完毕了,完成将show改为true,将底部的view中的wx-if,渲染出来,
if(res.data.length === 0){
this.setData({
show:true
})
}
let cinemaList = res.data;
//用map来修改数组,计算distance,将它作为属性
cinemaList = cinemaList.map(item => {
// 计算两个坐标之间的距离
let lat1, lng1, lat2, lng2;
lat1 = item.latitude;
lng1 = item.longitude;
lat2 = this.data.location.latitude;
lng2 = this.data.location.longitude;
//将四个参数,输入,调用getDistance函数来求出距离
let distance = this.getDistance(lat1, lng1, lat2, lng2);
distance = distance.toFixed(2) + 'km';
return {
...item,
distance: distance
}
})
this.setData({
list:[
...this.data.list,
...cinemaList
]
}, () => {
wx.hideLoading()
})
}).catch(err => {
console.log(err);
})
},
调用函数来计算经纬度
getDistance(lat1, lng1, lat2, lng2) {
var radLat1 = lat1 * Math.PI / 180.0;
var radLat2 = lat2 * Math.PI / 180.0;
var a = radLat1 - radLat2;
var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
s = s * 6378.137; // EARTH_RADIUS;
s = Math.round(s * 10000) / 10000;
return s;
},
5.页面基本加载完毕,但下拉时会加载更多的数据
onReachBottom: function () {
this.setData({
currPage: this.data.currPage+1
});
this.getList()
},
所有的js代码
const app = getApp();
Page({
data: {
show: false,
list: [],
index: 0,
currPage: 1,
location:{},
option1: [{
text: '深圳',
value: 0
},
{
text: '上海',
value: 1
},
{
text: '广州',
value: 2
}, {
text: '北京',
value: 3
},
],
value1: 0,
},
onLoad() {
this.getLocation(); //获取定位信息
//计算距离
},
getLocation() {
wx.getLocation({
type: 'wgs84',
success: (res) => {
// res里面包含了经纬度
console.log("定位信息",res);
let {
latitude,
longitude
} = res;
this.setData({
location: {
latitude,
longitude
}
})
this.getList();
},
fail: (err) => {
this.setData({
city: '定位失败,请手动选择'
})
}
})
},
getList() {
console.log("获取接口信息");
const params = {
cityName: this.data.option1[this.data.index].text,
currPage: this.data.currPage
};
app.get('/cinema/list', params).then(res => {
if(res.data.length === 0){
this.setData({
show:true
})
}
let cinemaList = res.data;
cinemaList = cinemaList.map(item => {
// 计算两个坐标之间的距离
let lat1, lng1, lat2, lng2;
lat1 = item.latitude;
lng1 = item.longitude;
lat2 = this.data.location.latitude;
lng2 = this.data.location.longitude;
let distance = this.getDistance(lat1, lng1, lat2, lng2);
distance = distance.toFixed(2) + 'km';
return {
...item,
distance: distance
}
})
this.setData({
list:[
...this.data.list,
...cinemaList
]
}, () => {
wx.hideLoading()
})
}).catch(err => {
console.log(err);
})
},
getDistance(lat1, lng1, lat2, lng2) {
var radLat1 = lat1 * Math.PI / 180.0;
var radLat2 = lat2 * Math.PI / 180.0;
var a = radLat1 - radLat2;
var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
s = s * 6378.137; // EARTH_RADIUS;
s = Math.round(s * 10000) / 10000;
return s;
},
select(e) {
let index = e.detail;
this.setData({
index: index,
list:[]
})
this.getList();
},
onReachBottom: function () {
this.setData({
currPage: this.data.currPage+1
});
this.getList()
},
})