一、首页布局

pages.json的代码如下
- {
- "pages": [
- {
- "path": "pages/main/main",
- "style": {
- "navigationBarTitleText": "点餐小程序",
- "navigationStyle": "custom", "enablePullDownRefresh": true
- }
- }
- ],
- "globalStyle": {
- "navigationBarTextStyle": "black",
- "navigationBarTitleText": "点餐小程序",
- "navigationBarBackgroundColor": "#F8F8F8",
- "backgroundColor": "#F8F8F8", "onReachBottomDistance": 50
- }
- }
- navigationStyle属性值为custom,设置成自定义导航;
- enablePullDownRefresh属性值为true,表示下拉刷新;
- onReachBottomDistance属性值未50,表示上拉触底事件触发时距底部的距离,单位为px;
二、异步数据流对接配合地图定位显示附近的商铺

uni-app已内置Vuex,无须安装即可使用。
1.首先配置Vuex,在根目录创建store->index.js
- import Vue from "vue";
- import Vuex from "vuex";
-
- Vue.use(Vuex);
-
- const store=new Vuex.Store({
- modules:{}
- });
-
- export default store;
2.将Vuex注册到Vue中,main.js文件中的代码如下:
- import Vue from 'vue'
- import App from './App'
- import store from "./store";
-
- Vue.config.productionTip = false
-
- App.mpType = 'app'
-
- const app = new Vue({
- ...App,
- store
- })
- app.$mount()
3.封装request()方法:在static->js->utils->request.js文件
- function request(url,method="get",data={}){
- return new Promise(((resolve, reject) => {
- uni.request({
- url: url,
- data: data,
- method:method.toLocaleUpperCase(),
- header: {
- 'content-type': 'application/x-www-form-urlencoded'
- },
- success: (res) => {
- resolve(res.data)
- },
- fail:(res)=>{
- reject(res)
- }
- });
- }))
- }
- export {
- request
- }
4.配置公共的参数,其中存放接口地址。在static->js->conf->config.js文件
- let baseApi="https://diancan.glbuys.com/api";
- export default {
- baseApi
- }
5.请求服务端数据:根目录创建api文件夹,在该文件夹下创建business/index.js文件。
- import config from "../../static/js/conf/config";
- import {request} from "../../static/js/utils/request";
-
- //显示首页商家列表
- export function getShopData(data){
- return request(config.baseApi+"/v1/business/shop","get",data)
- }
6.与Vuex对接:store->business->index.js
- import {getShopData} from "../../api/business";
- export default {
- namespaced: true,
- state:{
- shops:[]
- },
- mutations:{
- //设置商铺列表
- ["SET_SHOPS"](state,payload){
- state.shops=payload.shops;
- }
- },
- actions:{
- //显示首页商家列表
- getShop(conText,payload){
- getShopData(payload).then(res=>{
- if(res.code==200){
- conText.commit("SET_SHOPS",{shops:res.data});
- }
- })
- }
- }
- }
7.首页是自定义导航,需要先解决iPhoneX“刘海”的兼容性问题。
由于这个项目会有多个页面需要自定义导航,因此我们需要一个全局变量去识别是否在iPhoneX中,全局首选Vuex。
store->system->index.js中:
- export default {
- namespaced:true,
- state:{
- isIpx:false, //是否iPhoneX
- platform:1//平台类型。值:1:微信小程序,2:微信公众号
- },
- mutations:{
- //设置isIpx
- ["SET_IPX"](state,payload){
- state.isIpx=payload.isIpx;
- }
- }
- }
注册到Vuex中,store->index.js文件中新增代码如下:
- import Vue from "vue";
- import Vuex from "vuex";
- import system from "./system";
- import business from "./business";
-
- Vue.use(Vuex);
-
- const store=new Vuex.Store({
- modules:{
- system,
- business
- }
- });
-
- export default store;
判断是否在iPhoneX中进行,在App.vue中新增代码如下:
- onLaunch: function() {
- uni.getSystemInfo({
- success: res=> {
- if(res.model.indexOf('iPhone X')>-1){
- this.$store.commit("system/SET_IPX",{isIpx:true});
- }
- }
- });
- },
将Vuex的数据对接到pages/main/main.vue中,该文件中的代码如下:
(1)使用getSetting()方法获取用户的当前设置,利用返回值res.authSetting['scope.userLocation']判断用户是否开启地理位置。
如果没有开启,使用openSetting()方法调起客户端小程序设置界面。
用户开启地理位置后,使用getLocation()方法获取地理位置。
注意:为例定位准确,务必使用GCJ-02获取坐标,最后调用getShop()方法获取商品列表数据
(2)如果用户没有关闭地理位置功能。可以直接获取地理位置并获取商铺列表数据。
- <template>
- <view class="page">
- <view class="status_bar">view>
- <view class="header">
- <view :class="{'search-header':true,ipx:isIpx}">
- <view class="search-wrap">
- <view class="icon">view>
- <view class="text">请输入商家名或菜品view>
- view>
- view>
- view>
- <view class="shop-main">
- <view class="shop-list" v-for="item in shops" :key="item.branch_shop_id">
- <view class="shop-wrap">
- <view class="image">
- <image :src="item.logo">image>
- view>
- <view class="shop-info">
- <view class="shop-name">{{item.branch_shop_name}}view>
- <view class="distance">{{item.distance}}view>
- <view class="address">{{item.address}}view>
- <view class="pack-btn">自提view>
- view>
- view>
- view>
- view>
- view>
- template>
-
- <script>
- import {mapState,mapActions} from "vuex";
- export default {
- data() {
- return {
-
- }
- },
- onLoad() {
- this.lng=0;//经度
- this.lat=0;//纬度
- },
- onShow(){
- uni.getSetting({
- success:(res)=> {
- //用户没有开启地位位置
- if(!res.authSetting['scope.userLocation']){
- uni.showModal({
- title: '开启获取地理位置',
- content: '请打开"位置信息"权限,找到附近的店铺',
- success: (res)=> {
- if (res.confirm) {
- //调起客户端小程序设置界面
- uni.openSetting({
- success:(res2)=> {
- //如果用户打开了地理位置
- if(res2.authSetting['scope.userLocation']){
- uni.getLocation({
- type: 'gcj02',
- success: (res)=> {
- this.lng=res.longitude;
- this.lat=res.latitude;
- this.getShop({page:1,lng:this.lng,lat:this.lat});
- }
- });
- }
- }
- });
- }
- }
- });
- }
- }
- })
- uni.getLocation({
- type: 'gcj02',
- success: (res)=> {
- this.lng=res.longitude;
- this.lat=res.latitude;
- this.getShop({page:1,lng:this.lng,lat:this.lat});
- }
- });
- },
- methods: {
- ...mapActions({
- getShop:"business/getShop"
- })
- },
- computed:{
- ...mapState({
- isIpx:state=>state.system.isIpx,
- shops:state=>state.business.shops
- })
- },
- onShareAppMessage(res) {
- return {
- title: '点餐小程序',
- path: '/pages/main/main'
- }
- }
- }
- script>
-
- <style scoped>
- .page{width:100%;min-height:100vh;orverflow:hidden;}
- .header{width:100%;background-color:#eb1625;overflow:hidden;position: fixed;left:0;top:0;z-index:90;}
- .header .search-header{width:100%;height:170rpx;margin-top:40rpx;padding-bottom:20rpx;display:flex;justify-content: center;align-items: flex-end;}
- .header .search-header.ipx{height:210rpx;}
- .header .search-wrap{width:80%;height:52rpx;background-color:rgba(255,255,255,0.9);border-radius: 5px;display: flex;align-items: center;}
- .header .icon{width:44rpx;height:44rpx;background-image:url("@/static/images/main/search_icon.png");background-size:100%;background-position: center;background-repeat: no-repeat;margin:0 20rpx;}
- .header .text{color:#999999;font-size:28rpx;}
-
- .shop-main{width:100%;margin-top:220rpx;}
- .shop-main .shop-list{width:100%;border-bottom:1px solid #EFEFEF;box-sizing: border-box;padding:20rpx 0;}
- .shop-main .shop-list .shop-wrap{width:92%;margin:0 auto;display:flex;}
- .shop-main .shop-list .shop-wrap .image{width:160rpx;height:160rpx;margin-right:20rpx;}
- .shop-main .shop-list .shop-wrap .image image{width:100%;height:100%;border-radius: 5px;}
- .shop-main .shop-list .shop-info{width:72%;clear: both;}
- .shop-main .shop-list .shop-info .shop-name{width:100%;height:44rpx;overflow:hidden;white-space: nowrap;text-overflow: ellipsis;font-size:32rpx;font-weight: bold;}
- .shop-main .shop-list .shop-info .distance{font-size:28rpx;margin-top:10rpx;color:#666666}
- .shop-main .shop-list .shop-info .address{font-size:28rpx;margin-top:10rpx;color:#666666;width:100%;height:44rpx;overflow:hidden;white-space: nowrap;text-overflow: ellipsis;}
- .shop-main .shop-list .shop-info .pack-btn{padding:10rpx 20rpx;background-color:#eb1625;font-size:28rpx;color:#FFFFFF;display: table;border-radius: 5px;float: right;margin-top:10rpx;}
- style>
注:项目教程来自《uni-app多端跨平台开发从入门到企业级实战》