uni-app+uView实现定位功能,通过组建方式渲染和传递值的实现

Uni-app 实现定位功能

我做这个定位功能的实现使用的技术是:uni-app+uView, 定位的功能是使用腾讯地图小程序定位。通过获取经纬度的方式进行获取地理信息,我们可以直接调用腾讯定位的API,然后获取地理信息。通过uView的UI可现成技术进行实现。具体代码实现在每一个模块中有对应的代码

使用到的文档地址

腾讯地图SDK官方文档使用地址
uView官方文档使用地址
qqmap-wx-jssdk.min.js下载地址

需求和实现功能截图:

实现功能样式

首页定位信息采集

在这里插入图片描述
代码实现:

将这个头部定位的信息栏目进行封装一个组件,因为这个页面在多个地方使用到了;通过传递city,area,city_code 进行数据响应。(search-bar.vue 在下面有这组件)

<template>
	<view>
	<!-- 该部分多个地方使用,封装了一个组件 -->
		<search-bar v-on:pinitJob="Ssearch" :swiperlist="swiperlist" :placeholder="'搜索企业、职位'" :city="city" :area="area" :city_code="city_code"></search-bar>
	</view>
</template>
<script>
// 引入定位系统的sdk ,可以通过我上述提供的资源下载地址进行下载
 let QQMapWX = require('../../static/js/qqmap-wx-jssdk.min.js');
 // 在最外层创建一个全局变量
 let qqmapsdk;
export default {
	data(){
		return {
			city:'', // 城市
			area:'', // 区/县
			city_code: '', // 城市id
		}
	},
	onLoad(options) {
     qqmapsdk = new QQMapWX({
          // key: 'G5KBZ-xxxx-xxx-3KPRK-STFSA'
          // 自己的定位APK秘钥
          key: 'MRJBZ-xxxx-xxxx-xxxx-2DJHZ-xxxxx'
      });
      this.getCurrentLocation();
},
methods:{
		// 获取当前位置
        getCurrentLocation() {
            var that = this;
            uni.getLocation({
                type: 'wgs84',
                geocode: true,
                success: (res) => {
                    console.log("获取经纬度成功");
                    this.latitude = res.latitude;
                    this.longitude = res.longitude;
                    // 解析地址
                    qqmapsdk.reverseGeocoder({
                        location: {
                            latitude: that.latitude,
                            longitude: that.longitude
                        },
                        success: function(res) {
                            that.$nextTick(function() {
                            	// 可以根据自己的需要进行添加
                                this.city_code = res.result.ad_info.city_code; // 市区
                                this.city = res.result.address_component.city; // 市
                                this.area = res.result.address_component.district; // 区
                                this.address = [this.city, this.area]
                                that.getJobList()
                            })
                            // console.log(province, city, area)
                        },
                        fail: function(res) {
                            this.$refs.uToast.show({
                                title: '定位失败',
                                type: 'error',
                                icon: 'none'
                            })
                            console.log(res);
                        },
                        complete: function(res) {
                            console.log(res)
                        }
                    })
                },
                fail: (err) => {
                    uni.showToast({
                        title: '获取经纬度失败',
                        icon: 'none'
                    })
                    console.log("获取经纬度失败");
                    console.log(err);
                },
                complete: () => {}
            })
        },
}
 
}
</script>

search-bar 组件 => search-bar.vue

<template>
    <view class="page">
        <view class="title">
            <!-- <view style="display: flex; align-items: flex-end;" data-url="/subPackage/pages/switch_city/switch_city" @tap.stop="navTo"> -->
            <view style="display: flex; align-items: flex-end;">
                <view style="white-space: nowrap;" @click="goLocaltion(city,area,city_code)">{{city}}-{{area==''? '暂未选择区/县': area}}</view>  
                <view class="rbtriangle"></view>
            </view>
            <view class="search_ipt" :class="{hasresume:isresume == false}">
                <text class="iconfont iconsearch" style="margin-right: 10rpx;"></text>
                <input type="text" :placeholder="placeholder" v-model="keywords" confirm-type="搜索"
                    @confirm="initJob(keywords)" />
            </view>
            <image src="../../static/images/intro.png" :data-url="'/pages/historyCompany/historyCompany?type=1'"
                @tap.stop="navTo" v-show="isresume"></image>
        </view>
        <xunlan_swiper :data="swiperlist" :height="'280'" v-if="isshow"></xunlan_swiper>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                keywords: '',
            }
        },
        props: {
            isshow: {
                default: true,
                type: Boolean
            },
            swiperlist: {
                default: ()=>[],
                type: Array
            },
            isresume: {
                default: true,
                type: Boolean
            },
            placeholder: {
                default: 0,
                type: String
            },
            city:{
                default: '',
                type:String
            },
            area:{
                default: '',
                type:String
            },
            city_code:{
                default:'',
                type:String
            }
        },
        methods: {
        	// 直接进行跳转
            navTo(e) {
                let url = e.currentTarget.dataset.url;
                uni.navigateTo({
                    url: url
                })
            },
            initJob() {
                this.$emit("pinitJob", this.keywords)
            },
            // 页面跳转进行修改数据
            goLocaltion(city,area,city_code) {
                uni.navigateTo({
                // 传递需要的值,通过ES6进行拼接
                    url: `../../pages/index/xxxx?city=${city}&area=${area}&city_code=${city_code}`
                })
            }
        }
    }
</script>

<style lang="scss" scoped>
// 样式
    .page {
        position: relative;
        background-color: #FFFFFF;
    }

    .title {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 20rpx;
        font-size: 26rpx;
        color: #474754;

        image {
            width: 80rpx;
            height: 80rpx;
        }
    }

    .rbtriangle {
        width: 0;
        height: 0;
        border-bottom: 10rpx solid black;
        border-left: 10rpx solid transparent;
        margin: 0 20rpx;
    }

    .search_ipt {
        display: flex;
        align-items: center;
        width: 396rpx;
        height: 80rpx;
        padding: 10rpx;
        border-radius: 14rpx;
        background-color: #F5F6FA;
    }

    .hasresume {
        width: 500rpx;
    }
</style>

进入定位页面更改位置信息(切换城市),更改该程序的地理信息,关键字搜索

切换城市和获取区域的信息地理位置,关键字搜索

我们使用uView自带的样式进行布局使用,通过点击按钮进入到这个页面(可携带参数),以我这个为例的话,我是传递city,city_code,area三个值通过onLoad(options) 获取到这三个值,然后拿到选择区/县需要获取到city_code 的值请求到对应的区域。在搜索当中,可以通过用户提供的关键字在失去焦点时候进行模糊搜索,并且返回!

<template>
    <view class="page">
        <view class="title">
            <u-search placeholder="请输入城市名称" v-model="searchVal" :show-action="false" @focus="focusChange()" @blur="clearChange()" @change="searchChange(searchVal)"
                :dataCity="dataCity">
            </u-search>
        </view>
        <!-- 查询出来的列表 -->
        <view class="content bg-white" v-if="contentFlag == true">
            <view v-for="(searchItem,index) in seachCityList" :key="index">
                <view class="search-city-name" @click="searchChangeArea(searchItem.id,searchItem.fullname)">
                    {{searchItem.fullname}}
                </view>
            </view>
        </view>
        <!-- 所有城市列表 -->
        <view class="content" v-if="contentFlag == false">
            <view class="header">
                <view class="w45 color2F308A">
                    <image src="../../../static/images/location1_f.png" mode=""></image> <text>{{city}} {{area}}</text>
                </view>|
                <view class="w45" @click="changeArea(city_code)">
                    <image src="../../../static/images/select.png" mode=""></image><text
                        @click="show = true">选择区/县</text>
                </view>
                <view class="selectArea">
                    <u-select v-model="show" mode="single-column" :list="list" @confirm="confirm" @cancel="cancel">
                    </u-select>
                </view>
                <view class="text-content">根据城市选择地点</view>
            </view>
            <view class="index-list" :scrollTop="scrollTop">
                <view class="city-list">
                    <view class="current-city-box">
                        <text class="current-city-name">{{city}}</text>
                        <text class="current-city-btn">当前城市</text>
                    </view>
                </view>
                <u-index-list>
                    <view v-for="(item, index) in indexList" :key="index">
                    <!-- 这里的key需要绑定item.keywods或者唯一id,不然会出现点击城市获取的city_code有差异 -->
                        <u-index-anchor :use-slot="true" :index="item.keywords">
                            <view class="anchor-text city-fullname" v-for="(cityItem,i) in  item.list" :key="cityItem.id"
                                @click="changeCityById(cityItem.id,cityItem.fullname)">
                                {{cityItem.fullname}}
                            </view>
                        </u-index-anchor>
                    </view>
                </u-index-list>
            </view>
        </view>
    </view>
</template>

<script>
    let Config = require('../../common/config.js')
    let QQMapWX = require('../../../static/js/qqmap-wx-jssdk.min.js');
    let qqmapsdk = Config.map_global_key
    let setTime = null;
    export default {
        data() {
            return {
                keywords: '',
                searchVal: '', // 搜索内容
                indexList: [],
                city: '', // 市
                area: '', // 区
                scrollTop: 0,
                show: false, // 模态框控制
                list: [],
                city_code: '',
                seachCityList:[], // 模糊查询的数组
                contentFlag: false
            }
        },
        onLoad(options) {
            console.log('onLoad--options', options)
            // 获取传递的值
            this.city = options.city
            this.area = options.area
            // 截取并且赋值city_code
            this.city_code = this.subStringCode(options.city_code)
        },
        onUnload() {
            let pages = getCurrentPages();
            console.log(pages[0]);
            pages[0].$vm.area = this.area
            pages[0].$vm.city = this.city
            pages[0].$vm.city_code = this.city_code
        },
        onShow() {
        	// 与首页一致
            qqmapsdk = new QQMapWX({
                key: 'MRJBZ-xxxx-xxxx-GBN4H-2DJHZ-xxxxx'
            });
            // 获取市的列表
            this.getCityList().then(res => {
                this.indexList = res
            })
            // 进入页面获取对应市的区
            this.changeArea(this.city_code)
        },
        methods: {
            // 获取城市列表
            getCityList() {
                let fir = []
                let that = this
                let municipality = []
                return new Promise((resolve, reject) => {
                    qqmapsdk.getCityList({
                        success(res) {
                            if (res.status == 0) {
                                // resolve(res.result)
                                this.indexList = res.result
                                let myCityList = res.result
                                res.result.map((item, index) => {
                                    // console.log(item);
                                    let cityfirdtNumber = ['a', 'b', 'c', 'd', 'e', 'f', 'g',
                                        'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
                                        'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
                                    ]
                                    if (index == 0) {
                                        item.map(e => {
                                            // if (!e.fullname.includes('省')) {
                                            //     fir.push(e)
                                            // }
                                            if (e.fullname.includes('市')) {
                                                municipality.push(e.cidx)
                                            }
                                        })
                                    }
                                    // console.log(fir, "fir", municipality);
                                    if (index == 1) {
                                        Array.prototype.push.apply(item, fir)
                                        // console.log(item, cityfirdtNumber);
                                        let cityGropp = {}
                                        for (let i = 0; i < cityfirdtNumber.length; i++) {
                                            let city = []
                                            item.map((e, myIndex) => {
                                                let str = e.pinyin.join('')[0]
                                                // console.log(str);
                                                //直辖市过滤其中的区
                                                for (let j = 0; j < municipality
                                                    .length; j++) {
                                                    let muvity = municipality[j]
                                                    if (myIndex <= muvity[muvity
                                                            .length - 1] && myIndex >=
                                                        muvity[0]) {
                                                        return
                                                    }

                                                }
                                                if (str == cityfirdtNumber[i]) {
                                                    // if (e.fullname.includes('自治') || e.fullname.includes('地区') || e.fullname.includes('市') || e.fullname.includes('行政')) {
                                                    let objs = {
                                                        fullname: e.fullname,
                                                        name: e.name,
                                                        pinyin: e.pinyin,
                                                        id: e.id,
                                                        longPin: e.pinyin.join('')
                                                    }
                                                    city.push(objs)
                                                    // }
                                                }
                                            })
                                            cityGropp[cityfirdtNumber[i]] = city
                                        }
                                        // console.log(cityGropp, "cityGropp");
                                        let cityText = []
                                        let indexList = []
                                        let num = 0
                                        for (const key in cityGropp) {
                                            let obj = {}

                                            if (cityGropp[key].length > 0) {
                                                indexList.push(key.toUpperCase())
                                                obj.keywords = key.toUpperCase()
                                                obj.list = cityGropp[key]
                                                num += cityGropp[key].length
                                                cityGropp[key].sort((a, b) => a.longPin
                                                    .charCodeAt(0) - b.longPin.charCodeAt(0)
                                                ); //a~z 排序  
                                            }
                                            if (obj.keywords) {
                                                cityText.push(obj)
                                            }

                                        }
                                        resolve(cityText)
                                    }

                                })
                            }

                        },
                        fail(err) {
                            reject(err)
                        }
                    })
                })
            },



            //选择城市下的区县
            getDistrictByCityId(id) {
                console.log('id', id)
                return new Promise((resolve, reject) => {
                    qqmapsdk.getDistrictByCityId({
                        id,
                        success(res) {
                            if (res.status == 0) {
                                // console.log(res, 1);
                                resolve(res.result)
                            }
                        },
                        fail(err) {
                            reject(err)
                        }
                    })
                })
            },

            // 截取cityCode后六位
            subStringCode(str) {
                let res = str.substring(str.length - 6, str.length)
                return res
            },

            // 选择地区
            async changeArea(cityCode) {
                await this.getDistrictByCityId(cityCode).then(res => {
                    let newArr = []
                    res.map(item => {
                        item.map(e => {
                            e.label = e.fullname
                            e.value = e.id
                            let obj = {
                                label: e.fullname,
                                value: e.id
                            }
                            newArr.push(obj)
                        })
                    })
                    console.log(newArr)
                    this.list = newArr;
                })
            },

            // 选择确定按钮
            confirm(e) {
                e.map(item => {
                    this.area = item.label
                })
                // 返回上一页
                uni.navigateBack()
            },

            // 点击获取城市信息
            changeCityById(id,value) {
                console.log('查看value',value)
                console.log('查看id,',id,)
                this.city_code = id
                this.city = value
                this.area = ''
                this.list = []
                this.changeArea(id)
                // 防止用户过度点击
                uni.showLoading({
                    title: "加载中"
                })
                setTimeout(() => {
                    uni.hideLoading()
                }, 200)
            },

            // 关闭
            cancel(e) {
                e.map(item => {
                    console.log('关闭e', e)
                    // this.city_code = item.value
                })
            },

            // 帮助用户快速查询
            getSuggestion(params) {
                console.log('关键字搜索内容', params)
                return new Promise((resolve, reject) => {
                    qqmapsdk.getSuggestion({
                        keyword: params,
                        success(res) {
                            if (res.status == 0) {
                                // console.log(res, 1);
                                resolve(res.data)
                            }
                        },
                        fail(err) {
                            reject(err)
                        }
                    })
                })
            },

            // 获取焦点
            focusChange() {
               this.contentFlag = true 
            },
            
            // 没有数据时候
            clearChange() {
                this.contentFlag = false
            },
            
            // 模糊查询选择函数
            searchChangeArea(id,value) {
                this.city = value
                this.changeArea(id)
                this.area = ''
               this.getDistrictByCityId(id).then(res => {
                  let newArr = []
                      res.map(item => {
                          item.map(e => {
                              e.label = e.fullname
                              e.value = e.id
                              let obj = {
                                  label: e.fullname,
                                  value: e.id
                              }
                              newArr.push(obj)
                          })
                      })
                      console.log(newArr)
                      this.seachCityList = newArr;
                  })
            },
            

            // 市区焦点模糊查询
            searchChange(value) {
                this.contentFlag = true
                let that = this
                console.log("value", value)
                setTime&&clearTimeout(setTime)
               setTime = setTimeout(() =>{
                   let arr = []
                   that.indexList.map(item => {
                       // console.log(item.list);
                       item.list.map(e => {
                           if ((value && e.fullname.indexOf(value) != -1) || e.longPin.indexOf(value) != -
                               1) {
                               console.log(e);
                               // that.selectArea(e.id)
                              arr.push(e)
                           }
                   
                       })
                   })
                   this.seachCityList = arr
                   console.log('arr==>',JSON.parse(JSON.stringify(arr)))
                   uni.showLoading({
                       title:'加载数据中',
                       icon:'none'
                   })
               },500)
            }
        }
    }
</script>

<style lang="scss" scoped>
    .page {
        width: 100%;
        height: 100%;
        margin: 0 auto;
        background-color: whitesmoke !important;

        .title {
            width: 100%;
            padding: 20rpx 0;
            margin: 0 auto;
            background-color: #fff;
            position: relative;
        }

        .content {
            width: 90%;
            margin: 0 auto;

            .header {
                width: 100%;
                background-color: #FFFFFF;
                border-radius: 10px;
                margin-top: 10px;
                padding: 10px 0;

                .w45 {
                    width: 45%;
                    display: inline-block;
                    text-align: center;
                    height: 60rpx;
                    line-height: 60rpx;

                    image {
                        width: 25rpx;
                        height: 25rpx;
                        margin-right: 10rpx;
                    }

                    text {
                        height: 30rpx;
                        line-height: 30rpx;
                    }
                }

                .color2F308A {
                    color: #2F308A;
                    font-weight: bold;
                }
            }

            .text-content {
                font-weight: bold;
                font-size: 28rpx;
                color: #111111;
                text-align: left;
                padding: 24rpx 0;
                background-color: #F7F9FC;
            }
        }

        .index-list {
            width: 90%;
            height: 100%;
            margin: 0 auto;
            background-color: #FFF !important;
            border-radius: 10px;

            .city-list {
                width: 80%;
                position: relative;
                margin-left: 10px;

                .current-city-box {
                    padding: 30rpx 0;

                    .current-city-name {
                        color: #111111;
                        font-size: 30rpx;
                        font-weight: 500;
                    }

                    .current-city-btn {
                        margin-left: 10rpx;
                        font-size: 20rpx;
                        background-color: rgba(77, 185, 213, .2);
                        color: #4DB9D5;
                        padding: 4rpx 12rpx;
                        border-radius: 8rpx;
                    }
                }
            }

            .city-keywords {
                width: 100%;
                height: 50rpx;
                line-height: 50rpx;
                font-weight: bold;
                font-size: 32rpx;
                background-color: whitesmoke;
            }

            .city-fullname {
                width: 100%;
                height: 80rpx;
                line-height: 80rpx;
                font-size: 28rpx;
                font-weight: bold;
                background-color: #FFFFFF;
                border-bottom: solid 0.4px #ECECEC;
            }
        }
    }

    // 样式穿透,修改u-view组件的背景色
    .page /deep/ .u-index-anchor-wrapper .u-index-anchor {
        background-color: #fff;
    }

    .page /deep/ .u-search {
        width: 90%;
        margin: 0 auto !important;
    }
    
    .bg-white {
        background-color: #FFF;
        width: 100%;
        height: 100vh;
        .search-city-name {
            width: 100%;
            height: 60rpx;
            line-height: 60rpx;
            text-indent: 1em;
            font-size: 28rpx;
            font-weight: 600;
            border-bottom: 1px solid #C0C0C0;
        }
    }
</style>

切换城市页面
在这里插入图片描述

切换该城市的区域
在这里插入图片描述

关键字搜索功能实现
在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值