|
@@ -0,0 +1,442 @@
|
|
|
|
+<template>
|
|
|
|
+ <view class="simple-address" v-if="showPopup">
|
|
|
|
+ <!-- 遮罩层 -->
|
|
|
|
+ <view
|
|
|
|
+ class="simple-address-mask"
|
|
|
|
+ v-if="maskClick"
|
|
|
|
+ :class="[ani + '-mask', animation ? 'mask-ani' : '']"
|
|
|
|
+ :style="{
|
|
|
|
+ 'background-color': maskBgColor
|
|
|
|
+ }"
|
|
|
|
+ @tap="hideMask(true)"
|
|
|
|
+ ></view>
|
|
|
|
+
|
|
|
|
+ <!-- 省市区 -->
|
|
|
|
+ <view class="simple-address-content simple-address--fixed" :class="[type, ani + '-content', animation ? 'content-ani' : '']">
|
|
|
|
+ <view class="simple-address__header">
|
|
|
|
+ <view class="simple-address__header-btn-box" @click="pickerCancel">
|
|
|
|
+ <text class="simple-address__header-text" :style="{ color: cancelColor, fontSize: btnFontSize }">取消</text>
|
|
|
|
+ </view>
|
|
|
|
+ <view class="simple-address__header-btn-box" @click="pickerConfirm">
|
|
|
|
+ <text class="simple-address__header-text" :style="{ color: confirmColor, fontSize: btnFontSize }">确定</text>
|
|
|
|
+ </view>
|
|
|
|
+ </view>
|
|
|
|
+ <view class="simple-address__box">
|
|
|
|
+ <picker-view indicator-style="height: 70rpx;" class="simple-address-view" :value="pickerValue" @change="pickerChange">
|
|
|
|
+ <picker-view-column>
|
|
|
|
+ <!-- #ifndef APP-NVUE -->
|
|
|
|
+ <view class="picker-item" :style="{ fontSize: fontSize }" v-for="(item, index) in provinceDataList" :key="index">{{ item.name }}</view>
|
|
|
|
+ <!-- #endif -->
|
|
|
|
+ <!-- #ifdef APP-NVUE -->
|
|
|
|
+ <text class="picker-item" :style="{ fontSize: fontSize }" v-for="(item, index) in provinceDataList" :key="index">{{ item.name }}</text>
|
|
|
|
+ <!-- #endif -->
|
|
|
|
+ </picker-view-column>
|
|
|
|
+ <picker-view-column>
|
|
|
|
+ <!-- #ifndef APP-NVUE -->
|
|
|
|
+ <view class="picker-item" :style="{ fontSize: fontSize }" v-for="(item, index) in cityDataList" :key="index">{{ item.name }}</view>
|
|
|
|
+ <!-- #endif -->
|
|
|
|
+ <!-- #ifdef APP-NVUE -->
|
|
|
|
+ <text class="picker-item" :style="{ fontSize: fontSize }" v-for="(item, index) in cityDataList" :key="index">{{ item.name }}</text>
|
|
|
|
+ <!-- #endif -->
|
|
|
|
+ </picker-view-column>
|
|
|
|
+ <picker-view-column>
|
|
|
|
+ <!-- #ifndef APP-NVUE -->
|
|
|
|
+ <view class="picker-item" :style="{ fontSize: fontSize }" v-for="(item, index) in areaDataList" :key="index">{{ item.name }}</view>
|
|
|
|
+ <!-- #endif -->
|
|
|
|
+ <!-- #ifdef APP-NVUE -->
|
|
|
|
+ <text class="picker-item" :style="{ fontSize: fontSize }" v-for="(item, index) in areaDataList" :key="index">{{ item.name }}</text>
|
|
|
|
+ <!-- #endif -->
|
|
|
|
+ </picker-view-column>
|
|
|
|
+ </picker-view>
|
|
|
|
+ </view>
|
|
|
|
+ </view>
|
|
|
|
+
|
|
|
|
+ </view>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script>
|
|
|
|
+ import { getProvince, getCityByPro, getDistrictByCity } from '@/api/data.js'
|
|
|
|
+ export default{
|
|
|
|
+ name: 'Address',
|
|
|
|
+ props: {
|
|
|
|
+ // 是否允许点击遮罩层关闭
|
|
|
|
+ maskClick: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: true
|
|
|
|
+ },
|
|
|
|
+ // 是否开启动画
|
|
|
|
+ animation: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: true
|
|
|
|
+ },
|
|
|
|
+ // 遮罩层背景颜色
|
|
|
|
+ maskBgColor: {
|
|
|
|
+ type: String,
|
|
|
|
+ default: 'rgba(0, 0, 0, 0.4)' //背景颜色 rgba(0, 0, 0, 0.4) 为空则调用 uni.scss
|
|
|
|
+ },
|
|
|
|
+ /* 弹出层类型,可选值; 暂时只支持底部弹出
|
|
|
|
+ bottom:底部弹出层
|
|
|
|
+ */
|
|
|
|
+ type: {
|
|
|
|
+ type: String,
|
|
|
|
+ default: 'bottom'
|
|
|
|
+ },
|
|
|
|
+ cancelColor: {
|
|
|
|
+ type: String,
|
|
|
|
+ default: '' // 取消按钮颜色
|
|
|
|
+ },
|
|
|
|
+ confirmColor: {
|
|
|
|
+ type: String,
|
|
|
|
+ default: '' // 确认按钮颜色
|
|
|
|
+ },
|
|
|
|
+ fontSize: {
|
|
|
|
+ type: String,
|
|
|
|
+ default: '28rpx' // picker-item字体大小
|
|
|
|
+ },
|
|
|
|
+ btnFontSize: {
|
|
|
|
+ type: String,
|
|
|
|
+ default: '' // 按钮的字体大小
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ data(){
|
|
|
|
+ return{
|
|
|
|
+ showPopup: false, // 是否显示省市区选择
|
|
|
|
+ ani: '',
|
|
|
|
+ pickerValue: [0, 0, 0], // 默认值下标
|
|
|
|
+ pickerId: [], // 省市区默认值id
|
|
|
|
+ provinceDataList: [], // 省数据列表
|
|
|
|
+ cityDataList: [], // 市数据列表
|
|
|
|
+ areaDataList: [], // 区数据列表
|
|
|
|
+ isFirst: false, // 是否首次进入组件
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ // 初始化
|
|
|
|
+ init(){
|
|
|
|
+ this.provinceDataList = []
|
|
|
|
+ this.cityDataList = []
|
|
|
|
+ this.areaDataList = []
|
|
|
|
+ this.isFirst = false
|
|
|
|
+ },
|
|
|
|
+ // 点击遮罩层关闭选择省市区
|
|
|
|
+ hideMask() {
|
|
|
|
+ this._$emit('onCancel')
|
|
|
|
+ this.close()
|
|
|
|
+ },
|
|
|
|
+ // 打开省市区picker
|
|
|
|
+ open(idArr) {
|
|
|
|
+ // 初始化数据
|
|
|
|
+ this.init()
|
|
|
|
+ this.pickerId = idArr
|
|
|
|
+ // idArr 省市区默认id
|
|
|
|
+ if(this.pickerId && this.pickerId.length > 0){
|
|
|
|
+ // 获取省下拉
|
|
|
|
+ this.getProvinceList(idArr)
|
|
|
|
+ }else{
|
|
|
|
+ // 获取省下拉
|
|
|
|
+ this.getProvinceList()
|
|
|
|
+ }
|
|
|
|
+ this.showPopup = true
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.ani = 'simple-' + this.type
|
|
|
|
+ }, 100)
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ // 关闭省市区picker
|
|
|
|
+ close(type) {
|
|
|
|
+ if (!this.maskClick && type) return
|
|
|
|
+ this.ani = ''
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.showPopup = false
|
|
|
|
+ }, 300)
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ // 取消按钮
|
|
|
|
+ pickerCancel() {
|
|
|
|
+ this._$emit('onCancel')
|
|
|
|
+ this.close()
|
|
|
|
+ },
|
|
|
|
+ // 确定按钮
|
|
|
|
+ pickerConfirm() {
|
|
|
|
+ this._$emit('onConfirm')
|
|
|
|
+ if(!this.isFirst){
|
|
|
|
+ // 首次
|
|
|
|
+ this.isFirst = true
|
|
|
|
+ }
|
|
|
|
+ this.close()
|
|
|
|
+ },
|
|
|
|
+ // 省市区 change
|
|
|
|
+ pickerChange(e) {
|
|
|
|
+ const _this = this
|
|
|
|
+ let changePickerValue = e.detail.value
|
|
|
|
+
|
|
|
|
+ if (this.pickerValue[0] !== changePickerValue[0]) {
|
|
|
|
+ if(this.pickerId && this.pickerId.length > 0 && this.isFirst){
|
|
|
|
+ // 获取市下拉
|
|
|
|
+ this.getCityList(this.pickerId[0], this.pickerId)
|
|
|
|
+ }else{
|
|
|
|
+ // 第一级发生滚动,省 change重置市区下拉数据
|
|
|
|
+ this.getCityList(this.provinceDataList[changePickerValue[0]].id)
|
|
|
|
+ changePickerValue[1] = 0
|
|
|
|
+ changePickerValue[2] = 0
|
|
|
|
+ }
|
|
|
|
+ } else if (this.pickerValue[1] !== changePickerValue[1]) {
|
|
|
|
+ if(this.pickerId && this.pickerId.length > 0 && this.isFirst){
|
|
|
|
+ // 获取市下拉
|
|
|
|
+ this.getAreaList(this.pickerId[1], this.pickerId)
|
|
|
|
+ }else{
|
|
|
|
+ // 第二级滚动,市 change重置区县下拉数据
|
|
|
|
+ this.getAreaList(this.cityDataList[changePickerValue[1]].id)
|
|
|
|
+ changePickerValue[2] = 0
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ this.pickerValue = changePickerValue
|
|
|
|
+ // setTimeout解决由于省市区接口请求数据有延缓导致获值报错
|
|
|
|
+ setTimeout(()=>{
|
|
|
|
+ _this._$emit('onChange')
|
|
|
|
+ },1000)
|
|
|
|
+ },
|
|
|
|
+ _$emit(emitName) {
|
|
|
|
+ let pickObj = {
|
|
|
|
+ label: this._getLabel(),
|
|
|
|
+ value: this.pickerValue,
|
|
|
|
+ cityCode: this._getCityCode(),
|
|
|
|
+ areaCode: this._getAreaCode(),
|
|
|
|
+ provinceCode: this._getProvinceCode(),
|
|
|
|
+ labelArr: this._getLabel().split('-')
|
|
|
|
+ }
|
|
|
|
+ this.$emit(emitName, pickObj)
|
|
|
|
+ },
|
|
|
|
+ _getLabel() {
|
|
|
|
+ // name报错未发现页面影响(由于省市区接口请求数据延缓)
|
|
|
|
+ let pcikerLabel =
|
|
|
|
+ this.provinceDataList[this.pickerValue[0]].name + '-' + this.cityDataList[this.pickerValue[1]].name + '-' + this.areaDataList[this.pickerValue[2]].name
|
|
|
|
+ return pcikerLabel
|
|
|
|
+ },
|
|
|
|
+ _getCityCode() {
|
|
|
|
+ return this.cityDataList[this.pickerValue[1]].id
|
|
|
|
+ },
|
|
|
|
+ _getProvinceCode() {
|
|
|
|
+ return this.provinceDataList[this.pickerValue[0]].id
|
|
|
|
+ },
|
|
|
|
+ _getAreaCode() {
|
|
|
|
+ return this.areaDataList[this.pickerValue[2]].id
|
|
|
|
+ },
|
|
|
|
+ // 获取省下拉数据
|
|
|
|
+ getProvinceList(idArr){
|
|
|
|
+ const _this = this
|
|
|
|
+ getProvince().then(res => {
|
|
|
|
+ if (res.code == 200 || res.status == 204 || res.status == 200) {
|
|
|
|
+ _this.provinceDataList = res.data || [] // 省下拉数据
|
|
|
|
+ // 判断是否有默认值
|
|
|
|
+ if(idArr){
|
|
|
|
+ _this.getCityList(idArr[0], idArr)
|
|
|
|
+ _this.getAreaIndArr(idArr)
|
|
|
|
+ }else{
|
|
|
|
+ // 默认省数据第一条下的市下拉数据
|
|
|
|
+ _this.getCityList(_this.provinceDataList[0].id)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+ _this.provinceDataList = []
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ // 获取城市列表
|
|
|
|
+ getCityList (val, idArr) {
|
|
|
|
+ const _this = this
|
|
|
|
+ _this.cityDataList = []
|
|
|
|
+ _this.areaDataList = []
|
|
|
|
+ if (val != null && val != '') {
|
|
|
|
+ getCityByPro({id: val}).then(res => {
|
|
|
|
+ if (res.code == 200 || res.status == 204 || res.status == 200) {
|
|
|
|
+ _this.cityDataList = res.data || [] // 市下拉数据
|
|
|
|
+ // 判断是否有默认值
|
|
|
|
+ if(idArr){
|
|
|
|
+ _this.getAreaList(idArr[1], idArr)
|
|
|
|
+ _this.getAreaIndArr(idArr)
|
|
|
|
+ }else{
|
|
|
|
+ // 默认市数据第一条下的区县下拉数据
|
|
|
|
+ _this.getAreaList(_this.cityDataList[0].id)
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ _this.cityDataList = []
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 获取区县列表
|
|
|
|
+ getAreaList (val, idArr) {
|
|
|
|
+ const _this = this
|
|
|
|
+ this.areaDataList = []
|
|
|
|
+ if (val != null && val != '') {
|
|
|
|
+ getDistrictByCity({id: val}).then(res => {
|
|
|
|
+ if (res.code == 200 || res.status == 204 || res.status == 200) {
|
|
|
|
+ _this.areaDataList = res.data || []
|
|
|
|
+ // 判断是否有默认值
|
|
|
|
+ if(idArr){ _this.getAreaIndArr(idArr) }
|
|
|
|
+ } else {
|
|
|
|
+ _this.areaDataList = []
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 根据id 获取省市区 下标值
|
|
|
|
+ getAreaIndArr(idArr){
|
|
|
|
+ const _this = this
|
|
|
|
+ const provinceInd = _this.provinceDataList.findIndex(res => res['id'] == idArr[0])
|
|
|
|
+ const cityInd = _this.cityDataList.findIndex(res => res['id'] == idArr[1])
|
|
|
|
+ const districtInd = _this.areaDataList.findIndex(res => res['id'] == idArr[2])
|
|
|
|
+ setTimeout(()=>{
|
|
|
|
+ _this.pickerValue = [provinceInd, cityInd, districtInd]
|
|
|
|
+ },100)
|
|
|
|
+ // console.log(_this.pickerValue,'_this.pickerValue')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
+.simple-address {
|
|
|
|
+ /* #ifndef APP-NVUE */
|
|
|
|
+ display: flex;
|
|
|
|
+ /* #endif */
|
|
|
|
+ flex-direction: column;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.simple-address-mask {
|
|
|
|
+ position: fixed;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ top: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ right: 0;
|
|
|
|
+
|
|
|
|
+ transition-property: opacity;
|
|
|
|
+ transition-duration: 0.3s;
|
|
|
|
+ opacity: 0;
|
|
|
|
+ /* #ifndef APP-NVUE */
|
|
|
|
+ z-index: 99;
|
|
|
|
+ /* #endif */
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.mask-ani {
|
|
|
|
+ transition-property: opacity;
|
|
|
|
+ transition-duration: 0.2s;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.simple-bottom-mask {
|
|
|
|
+ opacity: 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.simple-center-mask {
|
|
|
|
+ opacity: 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.simple-address--fixed {
|
|
|
|
+ position: fixed;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ right: 0;
|
|
|
|
+ transition-property: transform;
|
|
|
|
+ transition-duration: 0.3s;
|
|
|
|
+ transform: translateY(460rpx);
|
|
|
|
+ /* #ifndef APP-NVUE */
|
|
|
|
+ z-index: 99;
|
|
|
|
+ /* #endif */
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.simple-address-content {
|
|
|
|
+ background-color: #ffffff;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.simple-content-bottom {
|
|
|
|
+ bottom: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ right: 0;
|
|
|
|
+ transform: translateY(500rpx);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.content-ani {
|
|
|
|
+ transition-property: transform, opacity;
|
|
|
|
+ transition-duration: 0.2s;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.simple-bottom-content {
|
|
|
|
+ transform: translateY(0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.simple-center-content {
|
|
|
|
+ transform: scale(1);
|
|
|
|
+ opacity: 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.simple-address__header {
|
|
|
|
+ position: relative;
|
|
|
|
+ /* #ifndef APP-NVUE */
|
|
|
|
+ display: flex;
|
|
|
|
+ /* #endif */
|
|
|
|
+ flex-direction: row;
|
|
|
|
+ flex-wrap: nowrap;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ border-bottom-color: #f2f2f2;
|
|
|
|
+ border-bottom-style: solid;
|
|
|
|
+ border-bottom-width: 1rpx;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.simple-address--fixed-top {
|
|
|
|
+ /* #ifndef APP-NVUE */
|
|
|
|
+ display: flex;
|
|
|
|
+ /* #endif */
|
|
|
|
+ flex-direction: row;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ border-top-color: $uni-border-color;
|
|
|
|
+ border-top-style: solid;
|
|
|
|
+ border-top-width: 1rpx;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.simple-address__header-btn-box {
|
|
|
|
+ /* #ifndef APP-NVUE */
|
|
|
|
+ display: flex;
|
|
|
|
+ /* #endif */
|
|
|
|
+ flex-direction: row;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ height: 70rpx;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.simple-address__header-text {
|
|
|
|
+ text-align: center;
|
|
|
|
+ font-size: $uni-font-size-base;
|
|
|
|
+ color: #1aad19;
|
|
|
|
+ line-height: 70rpx;
|
|
|
|
+ padding-left: 40rpx;
|
|
|
|
+ padding-right: 40rpx;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.simple-address__box {
|
|
|
|
+ position: relative;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.simple-address-view {
|
|
|
|
+ position: relative;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ /* #ifndef APP-NVUE */
|
|
|
|
+ width: 100%;
|
|
|
|
+ /* #endif */
|
|
|
|
+ /* #ifdef APP-NVUE */
|
|
|
|
+ width: 750rpx;
|
|
|
|
+ /* #endif */
|
|
|
|
+ height: 408rpx;
|
|
|
|
+ background-color: rgba(255, 255, 255, 1);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.picker-item {
|
|
|
|
+ text-align: center;
|
|
|
|
+ line-height: 70rpx;
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
+}
|
|
|
|
+</style>
|