uniapp#实现自定义省市区三级联动

uniapp中实现地址选择器

    • 适用情况和效果
    • 使用的组件
    • 功能实现
      • template代码
      • data数据
      • 方法
    • 样式代码

适用情况和效果

自定义地址选择适用于:前端展示的省市区县是由后端接口返回的(业务可能需要地区id或者其他数据);如果只是要选择位置,可以使用uni的api:uni.chooseLocation
手机端效果:
uniapp#实现自定义省市区三级联动_第1张图片

PC端效果:
uniapp#实现自定义省市区三级联动_第2张图片

使用的组件

实现该功能,首先需要一个弹出层,在下方弹出,还需要一个选择器。

  1. 弹出层 - uniPopup : uniPopup 可以直接导入插件到项目中 ;
  2. 选择器 - picker-view: 官方文档中,选择器有picker和picker-view两种,picker中有一个省市区选择器,但为什么不用呢,看看官方怎么说:uniapp#实现自定义省市区三级联动_第3张图片可以看出,使用picker-view是全平台友好的;

功能实现

template代码

		
			
				
					取消
					确定
				
				
					
						{
    {item.provinceName}}
					
					
						{
    {item.name}}
					
					
						{
    {item.name}}
					
				
			
		

data数据

			indicatorStyle: `height: ${Math.round(uni.getSystemInfoSync().screenWidth/(750/100))}px;`,
			valueArr: [0, 0, 0], // 用于判断当前滑动的是哪一列
			province: [], // 数据列表

方法

初始化方法:
进入页面时调用,loadAddr()是具体的接口方法,加载省数据

		initLoadArea() {
			loadAddr().then(res => {
				if (res.status) {
					this.province = res.data;
					this.loadCity(this.province[0].id)
				}
			})
		},

加载市数据:
loadChildAddr()是具体的加载子地区的方法;

		loadCity(parentId) {
			const params = {
				parent_id: parentId
			}

			loadChildAddr(params).then(res => {
				if (res.status) {
					if (this.province[this.valueArr[0]].children === undefined) {
						this.$set(this.province[this.valueArr[0]], 'children', [])
						res.data.forEach(item => {
							this.province[this.valueArr[0]].children.push(item)
						})
						this.loadArea(this.province[this.valueArr[0]].children[this.valueArr[1]].id)
					}
				}
			})
		},

加载区(县)数据:
我这里的加载省以下的数据是同一个接口,实际不同的情况可能是不同的接口方法,方法仅供参考,实际可根据需求选择更适合自己项目的方式

		loadArea(parentId) {
			const params = {
				parent_id: parentId
			}
			loadChildAddr(params).then(res => {
				if (res.status) {
					this.area = res.data;
					if (this.province[this.valueArr[0]].children[this.valueArr[1]].children === undefined) {
						this.$set(this.province[this.valueArr[0]].children[this.valueArr[1]], 'children', [])
						res.data.forEach(item => {
							this.province[this.valueArr[0]].children[this.valueArr[1]].children.push(item)
						})
					}
				}
			})
		},

picker-view的change事件绑定的方法:
在这里插入图片描述

		bindChange(e) {
			const val = e.detail.value;
			if (this.valueArr[0] !== val[0]) {
				this.loadCity(this.province[val[0]].id)
			} else if (this.valueArr[1] !== val[1]) {
				this.loadArea(this.province[val[0]].children[val[1]].id)
			}
			this.valueArr = val
		},

显示/关闭弹出层popup的方法:
popup是使用ref来弹出的,所以在写template代码的时候,要给uni-popup加上一个ref

		toggleTab() {
			this.$refs.popup.open();
		},
		cancel() {
			this.$refs.popup.close();
		},

样式代码

最后附上css:

.popup {
	height: fit-content;
	width: 100%;
	background: #fff;
}

.picker-btn {
	display: flex;
	height: 100upx;
	width: 100%;
	line-height: 100upx;
	background: #fff;
	font-size: 34upx;
	z-index: 1;
	border-bottom: 1rpx solid #f8f8f8;

	.left {
		flex: 1;
		color: #0076FF;
		padding-left: 40upx;
		box-sizing: border-box;
	}

	.right {
		flex: 1;
		text-align: right;
		padding-right: 40upx;
		color: #FE4533;
		box-sizing: border-box;
	}
}

picker-view {
	width: 100%;
	height: 500rpx;
	display: relative;
}
.item {
	line-height: 100rpx;
	text-align: center;
}

你可能感兴趣的:(uni-app,uni-app)