uniapp:省市选择 自定义组件

news/2024/7/19 16:24:41 标签: js, uni-app, vue, javascript

源码

https://gitee.com/river-winter/unappCity

效果图

湾流

两个数据文件

热门城市
common/hotData.js

javascript">export default [{ name: "上海市", },{ name: "广州市", },
{ name: "北京市", },{ name: "天津市", },{ name: "重庆市", },
{ name: "深圳市", },{name: "佛山市", },{ name: "东莞市", },
{ name: "杭州市", },{ name: "宁波市", },{ name: "南京市", },
{ name: "苏州市", },{ name: "福州市", },{name: "厦门市", },
{ name: "泉州市", },{ name: "济南市", },{ name: "青岛市", },
{ name: "武汉市", },{ name: "成都市", },{ name: "郑州市", },
{name: "长沙市", },{ name: "其他城市",},
]

省市数据
common/cityData.js

javascript">export default {
	"a": ["北京市", "天津市", "河北省", "山西省", "内蒙古自治区", "辽宁省", "吉林省", "黑龙江省", "上海市", "江苏省", "浙江省", "安徽省", "福建省", "江西省", "山东省",
		"河南省", "湖北省", "湖南省", "广东省", "广西壮族自治区", "海南省", "重庆市", "四川省", "贵州省", "云南省", "西藏自治区", "陕西省", "甘肃省", "青海省",
		"宁夏回族自治区", "新疆维吾尔自治区", "台湾省", "香港特别行政区", "澳门特别行政区"
	],
	"o": {
		"0": ["北京市"],
		"1": ["天津市"],
		"2": ["石家庄市", "唐山市", "秦皇岛市", "邯郸市", "邢台市", "保定市", "张家口市", "承德市", "沧州市", "廊坊市", "衡水市", "省直辖县级行政区划"],
		"3": ["太原市", "大同市", "阳泉市", "长治市", "晋城市", "朔州市", "晋中市", "运城市", "忻州市", "临汾市", "吕梁市"],
		"4": ["呼和浩特市", "包头市", "乌海市", "赤峰市", "通辽市", "鄂尔多斯市", "呼伦贝尔市", "巴彦淖尔市", "乌兰察布市", "兴安盟", "锡林郭勒盟", "阿拉善盟"],
		"5": ["沈阳市", "大连市", "鞍山市", "抚顺市", "本溪市", "丹东市", "锦州市", "营口市", "阜新市", "辽阳市", "盘锦市", "铁岭市", "朝阳市", "葫芦岛市"],
		"6": ["长春市", "吉林市", "四平市", "辽源市", "通化市", "白山市", "松原市", "白城市", "延边朝鲜族自治州"],
		"7": ["哈尔滨市", "齐齐哈尔市", "鸡西市", "鹤岗市", "双鸭山市", "大庆市", "伊春市", "佳木斯市", "七台河市", "牡丹江市", "黑河市", "绥化市", "大兴安岭地区"],
		"8": ["上海市"],
		"9": ["南京市", "无锡市", "徐州市", "常州市", "苏州市", "南通市", "连云港市", "淮安市", "盐城市", "扬州市", "镇江市", "泰州市", "宿迁市"],
		"10": ["杭州市", "宁波市", "温州市", "嘉兴市", "湖州市", "绍兴市", "金华市", "衢州市", "舟山市", "台州市", "丽水市"],
		"11": ["合肥市", "芜湖市", "蚌埠市", "淮南市", "马鞍山市", "淮北市", "铜陵市", "安庆市", "黄山市", "滁州市", "阜阳市", "宿州市", "六安市", "亳州市", "池州市",
			"宣城市"
		],
		"12": ["福州市", "厦门市", "莆田市", "三明市", "泉州市", "漳州市", "南平市", "龙岩市", "宁德市"],
		"13": ["南昌市", "景德镇市", "萍乡市", "九江市", "新余市", "鹰潭市", "赣州市", "吉安市", "宜春市", "抚州市", "上饶市"],
		"14": ["济南市", "青岛市", "淄博市", "枣庄市", "东营市", "烟台市", "潍坊市", "济宁市", "泰安市", "威海市", "日照市", "莱芜市", "临沂市", "德州市", "聊城市",
			"滨州市", "菏泽市"
		],
		"15": ["郑州市", "开封市", "洛阳市", "平顶山市", "安阳市", "鹤壁市", "新乡市", "焦作市", "濮阳市", "许昌市", "漯河市", "三门峡市", "南阳市", "商丘市",
			"信阳市", "周口市", "驻马店市", "省直辖县级行政区划"
		],
		"16": ["武汉市", "黄石市", "十堰市", "宜昌市", "襄阳市", "鄂州市", "荆门市", "孝感市", "荆州市", "黄冈市", "咸宁市", "随州市", "恩施土家族苗族自治州",
			"省直辖县级行政区划"
		],
		"17": ["长沙市", "株洲市", "湘潭市", "衡阳市", "邵阳市", "岳阳市", "常德市", "张家界市", "益阳市", "郴州市", "永州市", "怀化市", "娄底市",
			"湘西土家族苗族自治州"],
		"18": ["广州市", "韶关市", "深圳市", "珠海市", "汕头市", "佛山市", "江门市", "湛江市", "茂名市", "肇庆市", "惠州市", "梅州市", "汕尾市", "河源市", "阳江市",
			"清远市", "东莞市", "中山市", "潮州市", "揭阳市", "云浮市"
		],
		"19": ["南宁市", "柳州市", "桂林市", "梧州市", "北海市", "防城港市", "钦州市", "贵港市", "玉林市", "百色市", "贺州市", "河池市", "来宾市", "崇左市"],
		"20": ["海口市", "三亚市", "三沙市", "儋州市", "省直辖县级行政区划"],
		"21": ["重庆市"],
		"22": ["成都市", "自贡市", "攀枝花市", "泸州市", "德阳市", "绵阳市", "广元市", "遂宁市", "内江市", "乐山市", "南充市", "眉山市", "宜宾市", "广安市", "达州市",
			"雅安市", "巴中市", "资阳市", "阿坝藏族羌族自治州", "甘孜藏族自治州", "凉山彝族自治州"
		],
		"23": ["贵阳市", "六盘水市", "遵义市", "安顺市", "毕节市", "铜仁市", "黔西南布依族苗族自治州", "黔东南苗族侗族自治州", "黔南布依族苗族自治州"],
		"24": ["昆明市", "曲靖市", "玉溪市", "保山市", "昭通市", "丽江市", "普洱市", "临沧市", "楚雄彝族自治州", "红河哈尼族彝族自治州", "文山壮族苗族自治州",
			"西双版纳傣族自治州", "大理白族自治州", "德宏傣族景颇族自治州", "怒江傈僳族自治州", "迪庆藏族自治州"
		],
		"25": ["拉萨市", "日喀则市", "昌都市", "林芝市", "山南市", "那曲地区", "阿里地区"],
		"26": ["西安市", "铜川市", "宝鸡市", "咸阳市", "渭南市", "延安市", "汉中市", "榆林市", "安康市", "商洛市"],
		"27": ["兰州市", "嘉峪关市", "金昌市", "白银市", "天水市", "武威市", "张掖市", "平凉市", "酒泉市", "庆阳市", "定西市", "陇南市", "临夏回族自治州",
			"甘南藏族自治州"],
		"28": ["西宁市", "海东市", "海北藏族自治州", "黄南藏族自治州", "海南藏族自治州", "果洛藏族自治州", "玉树藏族自治州", "海西蒙古族藏族自治州"],
		"29": ["银川市", "石嘴山市", "吴忠市", "固原市", "中卫市"],
		"30": ["乌鲁木齐市", "克拉玛依市", "吐鲁番市", "哈密市", "昌吉回族自治州", "博尔塔拉蒙古自治州", "巴音郭楞蒙古自治州", "阿克苏地区", "克孜勒苏柯尔克孜自治州", "喀什地区",
			"和田地区", "伊犁哈萨克自治州", "塔城地区", "阿勒泰地区", "自治区直辖县级行政区划"
		],
		"31": ["台北市", "高雄市", "台南市", "台中市", "金门县", "南投县", "基隆市", "新竹市", "嘉义市", "新北市", "宜兰县", "新竹县", "桃园县", "苗栗县", "彰化县",
			"嘉义县", "云林县", "屏东县", "台东县", "花莲县", "澎湖县"
		],
		"32": ["香港岛", "九龙", "新界"],
		"33": ["澳门半岛", "氹仔岛", "路环岛"]
	}
}

组件页

pages/index/city.vue

javascript"><template>
	<view class="city">
		<view class="city_item flex1">
			<!-- 左侧滑动导航栏 -->
			<view class="city_item_left color81">
				<scroll-view :scroll-y="true" style="height:calc(100vh - 88rpx);">
					<view :class="indexsp == 'hot' ? 'active' : ''" @tap="setProvince" data-index="hot">
						常见&热门
					</view>
					<view :class="indexsp == index ? 'active' : ''" v-for="(item,index) in province.a"
						@tap="setProvince" :data-index="index">{{item}}</view>
				</scroll-view>
			</view>
			<!-- 右侧选择导航栏 -->
			<view class="city_item_right">
				<!-- 选中城市展示 -->
				<view class="current">
					<text class="hot_title">当前选择城市:</text>
					<view class="flex1">
						<!-- <imgParts url="../../static/icon/address.png" class="icon" width="25" height="30" /> -->
						<view>
							<text v-for="(item,index) in current" @click="setCity(item)">{{item}}{{index != (current.length-1) ? '、' : ''}}</text>
						</view>
					</view>
				</view>
				<!-- 城市选项展示 -->
				<view>
					<!-- 热门城市选项 -->
					<view class="hot" v-if="indexsp == 'hot'">
						<button v-for="(item,index) in hotlist" v-if="item.name != '其他城市'"
							:class="indexOfs(current,item.name) ? 'active' : ''"
							@tap="setCity(item.name)">{{item.name}}</button>
					</view>
					<!-- 城市选项 -->
					<view class="hot" v-else>
						<!-- 根据侧边导航选项索引决定右侧渲染的城市数据 -->
						<button v-for="(item,index) in province.o[indexsp]" @tap="setCity(item)"
							:class="indexOfs(current,item) ? 'active' : ''">{{item}}</button>
					</view>
					<!-- 确认按钮 -->
					<button class="submit f08btn" @tap="back">确定</button>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	// 导入省市数据
	import cityData from '@/common/cityData.js';
	// 导入热门城市数据
	import hotData from '@/common/hotData.js'
	export default {
		data() {
			return {
				// 省市数据
				province: cityData,
				// 侧边导航选项索引
				indexsp: 'hot',
				// 选中城市数组
				current: [],
				// 热门城市数据
				hotlist: hotData
			};
		},
		onLoad(options) {
			let that = this;
			// 将页面传递过来的数据使用"|"符号分割开,存储到变量current中
			that.current = options.city ? options.city.split('|') : [];
		},
		methods: {
			indexOfs(list, name) {
				return list.indexOf(name) != -1;
			},
			setCity(city) {// city 当前点击的城市
				
				let that = this;
				// 选中的城市数组
				let current = that.current;
				// 将当前点击城市在选中城市数组中检索,将结果赋值给变量index
				let index = current.indexOf(city);
				
				if (index != -1) {//index不等于-1代表选中数组中已有当前点击城市
					//从返回的城市数组位置进行删除一个元素
					that.current.splice(index, 1)
					
				} else if (current.length < 4) {// 当选中的城市数少于4个时
					// 将当前点击城市push进选中城市数组
					that.current.push(city);
				} else {//弹窗提示,选中城市不能超过4个
					uni.showToast({
						title: '城市不能超过4个',
						icon: 'none'
					})
				}
			},
			// 确定按钮触发函数
			back() {
				// 将数据通过|符号切割开
				let city = this.current.join('|');
				// 组件传值
				uni.$emit('setCity', city);
				// 返回上一个页面
				uni.navigateBack({
					delta:1
				})
			},
			// 侧边导航点击处理函数
			setProvince(e) {
				// 将点击元素的索引赋值到变量indexsp中
				this.indexsp = e.currentTarget.dataset.index;
			}
		}
	}
</script>

<style lang="scss" scoped>
	.submit {
		position: fixed;
		bottom: 10rpx;
		width: 500rpx
	}

	.f08btn {
		background-color: #f08300 !important;
		color: #fff;
		font-size: 28rpx;
	}

	.city {
		width: 100%;

		&_title {
			margin-bottom: 60rpx;
		}

		&_item {
			padding-bottom: 20rpx;
			align-items: flex-start;

			&_left {
				width: 210rpx;
				display: inline-block;
				background: #fafafa;

				view {
					text-align: center;
					padding: 20rpx;
				}

				.active {
					color: #f08300;
					background: #fff;
				}
			}

			&_right {
				width: 500rpx;
				display: inline-block;
				padding-left: 20rpx;
				position: fixed;

				button {
					border: 1rpx solid #f6f6f6;
				}

				.current {
					padding: 20rpx 30rpx 0 0;
					// 当前城市样式
					.hot_title {
						width: 100%;
						display: inline-block;
						color: #bfbfbf;
						line-height: 1;
						vertical-align: middle;
						margin-bottom: 22rpx;
					}
					.flex1{
						color: orange;
						.data-v-57280228{
						}
						text{
							font-size: 14px;
						}
					}

					.icon {
						width: 30rpx;
						height: 35rpx;
						display: inline-block;
						vertical-align: middle;
					}

					view {
						
						justify-content: space-between;

						view {
							width: calc(100% - 40rpx);

							text {
								display: inline-block;
							}
						}
					}
				}

				.hot {
					button {
						color: #484848;
						min-width: calc(50% - 20rpx);
						height: 65rpx;
						background: #fff;
						padding: 0 12rpx;
						display: inline-block;
						font-size: 24rpx;
						margin: 18rpx 20rpx 0 0;
					}

					button:after {
						border-color: #eee;
					}

					.active {
						color: #f08300;
						border: 1rpx solid #f08300;
					}

					.active:after {
						border-color: #f08300;
					}

				}
			}
		}

	}
</style>

引入页

pages/index/index.vue

javascript"><template>
	<!-- 带着已选城市为参数跳转到城市选择页 -->
	<navigator :url="`./city?city=${form.city}`" class="nav">
		<text>{{form.city ? form.city : '未选择城市'}}</text>
	</navigator>
</template>

<script>
	export default{
		data(){
			return{
				// 选中的城市
				form:{
					city:''
				}
			}
		},
		// 从跳转页面返回时触发的周期函数
		onShow(){
			let that=this
			// 使用$on接收组件传过来的值
			uni.$on('setCity',function(name){
				// 将选择的城市数据保存到form.city中
				that.form.city=name
			})
		}
	}
</script>

<style lang="scss"  scoped>
	.nav{
		height: 60rpx;
		text{
			color: orange;
		}
	}
</style>


http://www.niftyadmin.cn/n/874949.html

相关文章

vue自定义指令在实际开发中的使用

创建一个文件来管理所有的自定义指令 src/directives/index.js 在src/directives/index.js文件中定义几个指令 //改变文字颜色指令 export const fontColor{//dom元素节点 options包含传入的属性对象inserted(dom,options){dom.style.backgroundoptions.value} } // 改变文字大…

阿里云oss_配置阿里云OSS图床

配置阿里云OSS图床 博客说明 文章所涉及的资料来自互联网整理和个人总结&#xff0c;意在于个人学习和经验汇总&#xff0c;如有什么地方侵权&#xff0c;请联系本人删除&#xff0c;谢谢&#xff01; 开通阿里云OSS 开通阿里云 OSS https://www.aliyun.com/product/oss/ 首先我…

pythonsocket编程步骤_Python 学习笔记 - socket(基本原理和流程)

在学Python之前&#xff0c;先复习一下网络的基本概念。比如TCP/IP 4层模型&#xff0c;最上面的应用软件发送数据包&#xff0c;数据包在运输层加上TCP或者UDP的报头&#xff0c;然后在网络层加上IP的报头&#xff0c;然后在数据链路层根据ethernet协议分割成帧&#xff0c;每…

js 递归算法将扁平数据处理成树状数据

示例 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, initia…

不关注公众号可以获取openid吗_微信公众平台开发获取 UnionID

微信公众平台更新&#xff0c;为开发者提供UnionID机制经开发者反馈&#xff0c;由于同一公司下多个公众号之间需要用户帐号互通&#xff0c;微信开放平台提供了UnionID机制&#xff0c;来解决此问题。通过获取用户基本信息接口&#xff0c;开发者可通过OpenID来获取用户基本信…

垃圾邮件分类数据集_处理同时含有定量和分类变量的数据集的PCA方法

R包ade4处理包含定量和分类变量数据集的PCA方法常规的主成分分析(PCA)中&#xff0c;数据集所涉及的变量通常全部为定量变量。对于定性变量而言&#xff0c;通常将它们转化为0-1类型的二元数据后&#xff0c;作为PCA的输入(尽管效果可能不是很好)。如果是变量全部为分类变量&am…

vue 父组件使用sync修饰符直接获取子组件传来的值

子组件触发事件 <div class"btns" click"sure"><div class"confirm">确定</div></div> //事件名前加update sure() {this.$emit(update:showDialog,false) },父组件 sync修饰符 <child :showDialog.sync"succ…

互联网+大赛作品_“颂中国力量 绘美好梦想”全市中小学生互联网+书画大赛作品展示(一)...

由平顶山市教育体育局主办&#xff0c;平顶山市教育体育局关心下一代工作委员会、平顶山教育电视台、教育部中国书画等级考试平顶山市招生管理办公室承办&#xff0c;平顶山市书法家协会、平顶山市美术家协会协办的“颂中国力量 绘美好梦想”——平顶山市中小学生互联网书画大赛…