uniApp picker-view自定义选择省市区

新建组件pick-adress

pick-adress

通过uniapp提供的组件picker-view和picker-view-column做一个滚动的时间选择弹框

// An highlighted block
<template>
	<view class="">
		<!-- 支付按钮 -->
		<view class="pay_popup" :class="isOpen ? 'on' : ''">
			<view class="pay-title flex-sb-cent">
				<button class="btn" @click="onClose">取消</button>
				<button class="btn" @click="onSubmit">完成</button>
			</view>
			<view class="">
				<picker-view :value="idxArr" @change="bindChange" class="picker-view"
				 indicator-class="picker-box">
					<picker-view-column >
						<view class="item" v-for="(item,index) in provinceArray" :key="index">{{item.label}}</view>
					</picker-view-column>
					<picker-view-column>
						<view class="item" v-for="(item,index) in cityArray" :key="index">{{item.label}}</view>
					</picker-view-column>
					<picker-view-column v-if="isDistrictY">
						<view class="item" v-for="(item,index) in districtArray" :key="index">{{item.label}}</view>
					</picker-view-column>
				</picker-view>

			</view>			
		</view>
		<view class="mask" v-if="isOpen" @click="onClose"></view>
	</view>
</template>

<script>
	import { mapGetters } from "vuex";
	import addressData from '@/config/address.js'
	export default {
		props: {
			isOpen: {
				default: false,
				type: Boolean
			},
			
			isDistrictY: {// 判断是否选择区域数据true表示选择false表示不显示
				default: true,
				type: Boolean
			}
		},
		data () {
			return {
				title: 'picker-view',
				area1_name: '',
				area2_name: '',
				area3_name: '',
				area1_code: '',
				area2_code: '',
				area3_code: '',
				idxArr: [0,0,0],
				oldpProvinceDataList: addressData,
				provinceArray: [],
				cityArray: [],
				districtArray: [],
				column1: 0,
				column2: 0,
				column3: 0,
				// indicatorStyle: `height: 50px;`
			}
		},
		created() {
			for(let i=0; i<this.oldpProvinceDataList.length; i++){
				this.provinceArray.push(this.oldpProvinceDataList[i]);
			}
			for(let i=0; i<this.oldpProvinceDataList[0].children.length; i++){
				this.cityArray.push(this.oldpProvinceDataList[0].children[i]);
			}
			this.area1_name = this.provinceArray[0].label
			this.area2_name = this.cityArray[0].label
			this.area1_code = this.provinceArray[0].value
			this.area2_code = this.cityArray[0].value
			if (!this.isDistrictY) return
			for(let i=0; i<this.oldpProvinceDataList[0].children[0].children.length; i++){
				this.districtArray.push(this.oldpProvinceDataList[0].children[0].children[i]);
			}
			this.area3_name = this.districtArray[0].label
			this.area3_code = this.districtArray[0].value
		},
		
		methods: {
			pickerColumnchange(){
				let idxArr = this.idxArr
				if (this.oldpProvinceDataList[idxArr[0]].children&& this.oldpProvinceDataList[idxArr[0]].children.length>0) {
					this.cityArray = this.oldpProvinceDataList[idxArr[0]].children.map((item,index)=>{
						return item
					})
				}
				if (!this.isDistrictY) return
				if(this.oldpProvinceDataList[idxArr[0]].children && this.oldpProvinceDataList[idxArr[0]].children.length>0 &&
				this.oldpProvinceDataList[idxArr[0]].children[idxArr[1]].children && idxArr.length == 3){
					this.districtArray = this.oldpProvinceDataList[idxArr[0]].children[idxArr[1]].children.map((item,index)=>{
						return item
					})
				} else{
					this.idxArr[2] = 0
					this.districtArray = []
				}
			},
			bindChange: function (e) {
				const val = e.detail.value
				if (this.column1 !== val[0]) {
					this.column1 = val[0]
					this.column2 = 0
					this.column3 = 0
				} else if (this.column2 !== val[1]){
					this.column1 = val[0]
					this.column2 = val[1]
					this.column3 = 0
				} else {
					this.column1 = val[0]
					this.column2 = val[1]
					this.column3 = val[2]
				}
				
				this.idxArr = [this.column1,this.column2,this.column3]
				this.pickerColumnchange()
				if (this.provinceArray.length>0) {
					this.area1_name = this.provinceArray[this.column1].label
					this.area1_code = this.provinceArray[this.column1].value
				}
				if (this.cityArray.length>0) {
					this.area2_name = this.cityArray[this.column2].label
					this.area2_code = this.cityArray[this.column2].value
				} else {
					this.area2_name = ''
					this.area2_code = ''
				}
				if (!this.isDistrictY) return
				if (this.districtArray.length>0) {
					this.area3_name = this.districtArray[this.column3].label
					this.area3_code = this.districtArray[this.column3].value
				} else {
					this.area3_name = ''
					this.area3_code = ''
				}
			},
			onClose() {
				this.$emit('close',1)
			},
			onSubmit() {
				let data = {
					area1_name: this.area1_name,
					area2_name: this.area2_name,
					area3_name: this.area3_name,
					area1_code: this.area1_code,
					area2_code: this.area2_code,
					area3_code: this.area3_code,
				}
				this.$emit('bindChage',data)
			},
		}
	}
</script>

<style lang="less" scoped>
.pay_popup {
	.body-title {
		font-size: 36rpx;
		color: #666;
		text-align: center;
		padding-bottom: 12rpx;
		
	}
	.pay-title {
		border-bottom: none;
		padding: 0 32rpx;
		.btn {
			font-size: 32rpx;
			font-family: PingFang SC;
			font-weight: 400;
			color: #C90F07;
			line-height: 32rpx;
		}
	}
}
.picker-view {
	width: 100%;
	height: 432rpx;
	padding: 0 32rpx;
	.picker-box {
		// width: 686px;
		height: 80rpx;
		background: #C90F07;
		font-weight: 500;
		color: #45454C;
		line-height: 80rpx;
		opacity: 0.12;
	}
	uni-picker-view-column {
		&:first-child {
			.picker-box {
				border-top-left-radius: 16rpx;
				border-bottom-left-radius: 16rpx;
			}
		}
		&:last-child {
			.picker-box {
				border-top-right-radius: 16rpx;
				border-bottom-right-radius: 16rpx;
			}
		}
	}
}
.item {
	height: 80rpx;
	line-height: 80rpx;
	align-items: center;
	justify-content: center;
	text-align: center;
	color: #45454C !important;
	font-size: 36rpx;
	font-family: PingFang SC;
}


</style>

</template>

<script>
	import { mapGetters } from "vuex";
	export default {
		props: {
			isOpen: {
				default: false,
				type: Boolean
			},
			modelValue: {// 选择时间格式 yyyy-MM-dd
				default: '',
				type: String
			},
			isGreaterY: { // 是否选择年月日,y 表示选择年月日,n 表示选择年月
				default: 'n',
				type: String
			}
		},
		data () {
			
			return {
				title: 'picker-view',
				years: [],
				year: '',
				months: [],
				month: '',
				days: [],
				day: '',
				value: [],
				// indicatorStyle: `height: 50px;`
			}
		},
		created() {
			const date = new Date()
			const years = []
			const year = date.getFullYear()
			const months = []
			const month = date.getMonth() + 1
			const days = []
			const day = date.getDate()
			if (this.isGreaterY=='n') {
				for (let i = 1990; i <= date.getFullYear(); i++) {
					years.push(i)
				}
				this.value = [9999,month-1,day-1]
			} else {
				for (let i = date.getFullYear()+100; i >= date.getFullYear(); i--) {
					years.unshift(i)
				}
				this.value = [0,month-1,day-1]
			}
			
			for (let i = 1; i <= 12; i++) {
				months.push(i)
			}
			for (let i = 1; i <= 31; i++) {
				days.push(i)
			}
			// 设置默认选择时间
			this.years = years
			this.months = months
			this.days = days
			this.year = year
			
			this.day = day
			if (month<10) {
				this.month = '0'+month
			} else {
				this.month = month
			}
		},
		methods: {
			bindChange: function (e) {
				const val = e.detail.value
				this.year = this.years[val[0]]
				let month = this.months[val[1]]
				if (month<10) {
					this.month = '0'+month
				} else {
					this.month = month
				}
				this.day = this.days[val[2]]
			},
			onClose() {
				this.$emit('onClose',1)
			},
			onSubmit() {
				let data = ''
				if (this.modelValue=='yyyy-MM') {
					data = this.year+'.'+this.month
				} else {
					data = this.year+'.'+this.month+'.'+this.day
				}
				this.$emit('bindChage',data,{year:this.year,month:this.month,day:this.day})
			},
		}
	}
</script>

<style lang="less" scoped>
.pay_popup {
	.body-title {
		font-size: 36rpx;
		color: #666;
		text-align: center;
		padding-bottom: 12rpx;
		
	}
	.pay-title {
		border-bottom: none;
		padding: 0 32rpx;
		.btn {
			font-size: 32rpx;
			font-family: PingFang SC;
			font-weight: 400;
			color: #C90F07;
			line-height: 32rpx;
		}
	}
}
.picker-view {
	width: 100%;
	height: 432rpx;
	padding: 0 32rpx;
	.picker-box {
		// width: 686px;
		height: 80rpx;
		background: #C90F07;
		font-weight: 500;
		color: #45454C;
		line-height: 80rpx;
		opacity: 0.12;
	}
	uni-picker-view-column {
		&:first-child {
			.picker-box {
				border-top-left-radius: 16rpx;
				border-bottom-left-radius: 16rpx;
			}
		}
		&:last-child {
			.picker-box {
				border-top-right-radius: 16rpx;
				border-bottom-right-radius: 16rpx;
			}
		}
	}
}
.item {
	height: 80rpx;
	line-height: 80rpx;
	align-items: center;
	justify-content: center;
	text-align: center;
	color: #45454C !important;
	font-size: 36rpx;
	font-family: PingFang SC;
}

/* 弹出样式 */

.pay_popup {
	width: 100%;
	background-color: #fff;
	position: fixed;
	left: 0;
	bottom: 0;
	z-index: 997;
	transform: translate3d(0, 100%, 0);
	transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
	border-top-left-radius: 32rpx;
	border-top-right-radius: 32rpx;
	overflow: hidden;
}
.pay_popup.on {
	transform: translate3d(0, 0, 0);
}
.pay_popup .pay-title {
	width: 100%;
	font-size: 36rpx;
	font-family: PingFang SC;
	font-weight: 500;
	color: #1C1C1F;
	text-align: center;
	position: relative;
	height: 112rpx;
	line-height: 112rpx;
	background: #FFFFFF;
	border-bottom: 1rpx solid #E5E5E5;
	
}
.pay_popup .right-close {
	position: absolute;
	left: 24rpx;
	font-size: 36rpx;
	color: #1C1C1F;
}

</style>

在项目中新建config文件夹 创建address.js文件

将省市区编码放到address.js中,讲address.js引入到组件中,数据太多放不下,如果找不到省市区地址数据,可以用element-ui中的三级联动地址数据打印出来使用
address.js文件在这个地方下载

在父组件中使用

引入父组件中

<template>
	<view>
		<view class="xss-info-item flex-fs-left">
			<view class="xss-left-name">用户地址</view>
				<view class="xss-input line1" @click="onPickAddress">
					<view class="xss-input-bar " v-if="address">{{address}}</view>
					<view class="xss-input-bar" style="color:#999;font-size:32rpx" v-else>省、市、区</view>
				</view>
				<text class="iconfont icon-xiangyou"></text>
			</view>
		
		<pickAdress :isOpen="isPickAddressShow" @close="onCloseAddress" @bindChage="onBindChageAddress"></pickAdress>
	</view>
</template>
<script>
	import pickAdress from '@/components/pick-adress.vue'
	export default {
		components: {
			pickAdress,
		},
		data() {
			return: {
				isPickAddressShow: false,
				selectAddress: {},
				address: '',
			}
		},
		methods: {
			onPickAddress() {
				if (this.authState) return
				this.isPickAddressShow = true
			},
			onCloseAddress(type,data) {
				this.isPickAddressShow = false
			},
			onBindChageAddress(data) {
				this.selectAddress = data
				this.address = data.area1_name+data.area2_name+data.area3_name
				this.isPickAddressShow = false
			},
		}
	}
</script>
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值