APICloud AVM框架 封装省市区级联选择弹框

AVM(Application-View-Model)前端组件化开发模式基于标准Web Components组件化思想,提供包含虚拟DOM和Runtime的编程框架avm.js以及多端统一编译工具,完全兼容Web Components标准,同时兼容Vue和React语法糖编写代码,编译工具将Vue和React相关语法糖编译转换为avm.js代码。

基于标准 Web Components 组件化思想,兼容 Vue / React 语法特性,通过一次编码,分别编译为 App、小程序代码,实现多端开发。
 

组件功能介绍

省市区级联选择框,也可用于其他多层级数据的选择,典型场景为省市区选择。

目前场景设定的是3级,可根据自己的实际需求改成2级或者4级或者更多级。

数据源就是典型的树形结构的JSON数组数据。实际代码中我封装了一个关于省市区三级数据的js插件,具体使用方法省市区三级行政区划数据JS插件 

示例展示 

  

 

组件开发

组件文件

area-cascader.stml

<template>
	<view class="area-cascader_container">
		<view class="area-cascader_box">
			<view class="area-cascader_box-header">
				<text class="area-cascader_box-header-label">请选择所在地区</text>
				<text class="area-cascader_box-header-button" @click="closeCascader">×</text>
			</view>
			<view class="area-cascader_box-nav">
				<view class="area-cascader_box-nav-item" v-for="(item,index) in result" data-index={index} @click="setSelect">
					<text class='area-cascader_box-nav-item--selected' v-if="this.data.selectIndex==index && item.value">{item.text}</text>
					<text class='area-cascader_box-nav-item--unselected' v-else-if="this.data.selectIndex==index && !item.value">请选择</text>
					<text class='area-cascader_box-nav-item--result' v-else-if="this.data.selectIndex!=index && item.value">{{item.text}}</text>
				</view>
			</view>
			<scroll-view class="area-cascader_pane" scroll-y="">
				<view class="area-cascader_pane-option" v-for="(item,index) in selectArea" data-value={item.value} data-text={item.text} @click="setSelectItem">
					<text>{item.text}</text>
				</view>
			</scroll-view>
		</view>
	</view>
</template>
<script>
	export default {
		name: 'area-cascader',
		props:{
			options:Array
		},
		install(){
			this.data.result[0]={value:null,text:''};
		},
		installed(){
			this.data.selectArea = this.props.options;
		},
		data() {
			return{
				result:[],
				selectIndex:0,
				selectArea:[]
			}
		},
		methods: {
			setSelectItem(e){
				if(this.data.selectIndex<3){
					this.data.result[this.data.selectIndex].value=e.currentTarget.dataset.value;
					this.data.result[this.data.selectIndex].text=e.currentTarget.dataset.text;
					//追加下一级
					this.data.selectIndex+=1;				
					if(this.data.selectIndex<3){
						this.data.result[this.data.selectIndex]={value:null,text:''};
						var parentOption=this.data.selectArea.filter(item=>item.value==e.currentTarget.dataset.value);
						this.data.selectArea = parentOption[0].children;
					}				
					if(this.data.selectIndex==3){
						this.fire('finish',this.data.result);
					}
				}				
			},
			closeCascader(){
				this.fire('close','');
			},
			setSelect(e){
				this.data.selectIndex=e.currentTarget.dataset.index;
				if(this.data.selectIndex==0){
					this.data.selectArea = this.props.options;
				}
				else if(this.data.selectIndex==1){
					var parentOption=this.props.options.filter(item=>item.value==this.data.result[0].value);
					this.data.selectArea = parentOption[0].children;
				}
			}
		}
	}
</script>
<style>
	.area-cascader_container {
		position: absolute;
		height: 100%;
		width: 100%;
		background-color: rgba(0,0,0,0.1);
	}
	.area-cascader_box{
		align-items: center;
		position: absolute;
		bottom: 0;
		width: 100%;
		height: 70%;
		background-color: #ffffff;
		border-top-left-radius: 30px;
		border-top-right-radius: 30px;
	}
	.area-cascader_box-header{
		width: 100%;
		flex-flow: row nowrap;
		justify-content: space-between;
		align-items: center;
		padding: 10px 15px 0 15px;
	}
	.area-cascader_box-header-label{
		font-size: 18px;
	}
	.area-cascader_box-header-button{
		font-size: 40px;
		color: #ccc;
	}
	.area-cascader_box-nav{
		width: 100%;
		flex-flow: row nowrap;
		justify-content: flex-start;
		align-items: center;
		padding: 15px;
	}
	.area-cascader_box-nav-item{
		box-sizing: border-box;
		align-items: center;
		/* background-color: #452334; */
		margin-right: 20px;
		justify-content: center;
	}
	.area-cascader_box-nav-item--selected{
		font-size: 16px;
		padding-bottom: 10px;	
		border-bottom: 3px solid #49c916;
	}
	.area-cascader_box-nav-item--unselected{
		font-size: 16px;
		padding-bottom: 10px;
		border-bottom: 3px solid #49c916;
	}
	.area-cascader_box-nav-item--result{
		font-size: 16px;
		padding-bottom: 13px;
		border-bottom: 0;
	}
	.area-cascader_pane{
		padding-left: 15px;
		padding-right: 10px;
		width: 100%;
		height: 80%;
	}
	.area-cascader_pane-option{	
		flex-flow: row nowrap;
		align-items: flex-start;
		justify-content: space-between;
		padding: 5px 0;
	}
</style>

组件使用说明

本组件是基于AVM.js开发的多端组件,通常同时适配Android、iOS、小程序、H5 , 具体支持情况还要看每个组件的说明文档。

首先需要登录开发平台,http://www.apicloud.com。 通过控制平台右上方的模块Store进入,然后选择AVM组件。

 

找到对应模块进入

 

也可通过搜索栏,通过组件名称关键字进行检索。

 进入模块详情,点击立即下载下载完整的组件安装包。  

组件压缩包的文件目录如下

 

也可通过查看模块文档 来了解模块的具体参数,引用的原生模块,注意事项等。 

具体在项目中的使用步骤是,第一步将压缩文件中的easy-area-cascader.stml文件拷贝到项目的components目录,通过阅读readme.md 文档和查看demo示例文件 demo-easy-area-cascader.stml在需要开发的stml文件中,引入组件文件,完成页面的开发。

areaList.js文件,可根据实际项目放到对应的文件夹中,我放在了utils这个文件夹中。本插件基于ES6语法封装的,封装了areaList,getTree,getArea,getCity,getProvince四个方法,本组件中用到的事getTree,返回的是树形结构的JSON格式数据。

demo-area-cascader.stml

<template>
	<view class="page">
		<safe-area></safe-area>
		<text style="padding:10px;font-size:20px;">地区级联选择</text>
		<view class="box" @click="openCascader">
			<text>地区</text>
			<text>{selectArea}</text>
			<image class="more" src={ico} mode="widthFix"></image>
		</view>
		<area-cascader
			:options="areaValue"
			onfinish="getArea"
			onclose="closeCascader"
			v-if="isShowCascader"
		>
		</area-cascader>
	</view>
</template>
<script>
	import '../../components/area-cascader.stml'
	import {areaList,getTree,getArea,getProvince,getCity} from '../../utils/areaList.js'
	export default {
		name: 'demo-area-cascader',
		apiready(){
			this.data.areaValue = getTree();
			// getCity('130000');
			// getProvince();
			// getArea('130200');
		},
		data() {
			return{
				selectArea:'',
				areaValue:[],
				isShowCascader:false,
				ico:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAZRJREFUeF7t2z1KxEAYgOF3D2Old7AVsdlirS3sBEE9gB5gYQtLC3utxZPYeRgZ2CKEXSGT+X4nqUIgkPfJzBQZsqLzY9V5PwvAMgLsBDbAGjgHPoAHi0exnALvwM0g+hO41kawBNgCT6NgdQRLgAvg+8AbV0WwBCjtZR0o8398qCFYA5gjeAAwRfACYIbgCcAEwRuAOoJHAFUErwBqCJ4BVBC8A4gjRAAQRYgCIIYQCUAEIRpAc4SIAE0RogI0Q4gM0AQhOsBshAwAsxCyAFQjZAKoQsgGMBkhI8B/CK/A/fATdFaAYwi/wEnPAD/AWQ8AxzZcdsBjdoBJu03Z1oBJ8WUkZAKYHJ8JoCo+C0B1fAaAWfHRAWbHRwZoEh8VoFl8RICm8dEAmsdHAhCJjwIgFh8BQDTeO4B4vGcAlXivAGrxHgFU470BqMd7AjCJ9wJgFu8BwDTeGuAS+Bp+ot6fq/0rYA3wBtyOAFTjrQFegOcBgHq8NcDV/qepU6DE3x2YDuKXMu0LVGEtAFVsiW7qfgT8AYVYcEHJaD3BAAAAAElFTkSuQmCC',
				
			}
		},
		methods: {
			getArea(e){
				// console.log(JSON.stringify(e));
				this.data.selectArea = e.detail[0].text+'/'+e.detail[1].text+'/'+e.detail[2].text;
				this.data.isShowCascader = false;
			},
			openCascader(e){
				this.data.isShowCascader = true;
			},
			closeCascader(e){
				this.data.isShowCascader = false;
			}
		}
	}
</script>
<style>
	.page {
		height: 100%;
		background-color: #ffffff;
	}
	.box{
		flex-flow: row nowrap;
		justify-content: space-between;
		align-items: center;
		margin: 10px;
		border-radius: 5px;
		background-color: #f0f0f0;
		padding: 10px;
	}
	.more{
		width: 20px;
	}
</style>

如果在AVM组件库中,没有找到实际项目中需要的组件,可以自己尝试封装组件。

这是组件化开发的在线文档地址

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白鱼赤乌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值