帖子
帖子
用户
博客
课程

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

YonBuilder移动开发 2023-1-13 17:24 205人浏览 0人回复
原作者: wuliyuye 收藏 邀请
摘要

​省市区级联选择框,也可用于其他多层级数据的选择,典型场景为省市区选择。 目前场景设定的是3级,可根据自己的实际需求改成2级或者4级或者更多级。 数据源就是典型的树形结构的JSON数组数据。实际代码中我封装了 ...

​省市区级联选择框,也可用于其他多层级数据的选择,典型场景为省市区选择。
目前场景设定的是3级,可根据自己的实际需求改成2级或者4级或者更多级。
数据源就是典型的树形结构的JSON数组数据。实际代码中我封装了一个关于省市区三级数据的js插件,具体使用方法省市区三级行政区划数据JS插件
组件文件area-cascader.stml
  1. <template>
  2.         <view class="area-cascader_container">
  3.                 <view class="area-cascader_box">
  4.                         <view class="area-cascader_box-header">
  5.                                 <text class="area-cascader_box-header-label">请选择所在地区</text>
  6.                                 <text class="area-cascader_box-header-button" @click="closeCascader">×</text>
  7.                         </view>
  8.                         <view class="area-cascader_box-nav">
  9.                                 <view class="area-cascader_box-nav-item" v-for="(item,index) in result" data-index={index} @click="setSelect">
  10.                                         <text class='area-cascader_box-nav-item--selected' v-if="this.data.selectIndex==index && item.value">{item.text}</text>
  11.                                         <text class='area-cascader_box-nav-item--unselected' v-else-if="this.data.selectIndex==index && !item.value">请选择</text>
  12.                                         <text class='area-cascader_box-nav-item--result' v-else-if="this.data.selectIndex!=index && item.value">{{item.text}}</text>
  13.                                 </view>
  14.                         </view>
  15.                         <scroll-view class="area-cascader_pane" scroll-y="">
  16.                                 <view class="area-cascader_pane-option" v-for="(item,index) in selectArea" data-value={item.value} data-text={item.text} @click="setSelectItem">
  17.                                         <text>{item.text}</text>
  18.                                 </view>
  19.                         </scroll-view>
  20.                 </view>
  21.         </view>
  22. </template>
  23. <script>
  24.         export default {
  25.                 name: 'area-cascader',
  26.                 props:{
  27.                         options:Array
  28.                 },
  29.                 install(){
  30.                         this.data.result[0]={value:null,text:''};
  31.                 },
  32.                 installed(){
  33.                         this.data.selectArea = this.props.options;
  34.                 },
  35.                 data() {
  36.                         return{
  37.                                 result:[],
  38.                                 selectIndex:0,
  39.                                 selectArea:[]
  40.                         }
  41.                 },
  42.                 methods: {
  43.                         setSelectItem(e){
  44.                                 if(this.data.selectIndex<3){
  45.                                         this.data.result[this.data.selectIndex].value=e.currentTarget.dataset.value;
  46.                                         this.data.result[this.data.selectIndex].text=e.currentTarget.dataset.text;
  47.                                         //追加下一级
  48.                                         this.data.selectIndex+=1;                               
  49.                                         if(this.data.selectIndex<3){
  50.                                                 this.data.result[this.data.selectIndex]={value:null,text:''};
  51.                                                 var parentOption=this.data.selectArea.filter(item=>item.value==e.currentTarget.dataset.value);
  52.                                                 this.data.selectArea = parentOption[0].children;
  53.                                         }                               
  54.                                         if(this.data.selectIndex==3){
  55.                                                 this.fire('finish',this.data.result);
  56.                                         }
  57.                                 }                               
  58.                         },
  59.                         closeCascader(){
  60.                                 this.fire('close','');
  61.                         },
  62.                         setSelect(e){
  63.                                 this.data.selectIndex=e.currentTarget.dataset.index;
  64.                                 if(this.data.selectIndex==0){
  65.                                         this.data.selectArea = this.props.options;
  66.                                 }
  67.                                 else if(this.data.selectIndex==1){
  68.                                         var parentOption=this.props.options.filter(item=>item.value==this.data.result[0].value);
  69.                                         this.data.selectArea = parentOption[0].children;
  70.                                 }
  71.                         }
  72.                 }
  73.         }
  74. </script>
  75. <style>
  76.         .area-cascader_container {
  77.                 position: absolute;
  78.                 height: 100%;
  79.                 width: 100%;
  80.                 background-color: rgba(0,0,0,0.1);
  81.         }
  82.         .area-cascader_box{
  83.                 align-items: center;
  84.                 position: absolute;
  85.                 bottom: 0;
  86.                 width: 100%;
  87.                 height: 70%;
  88.                 background-color: #ffffff;
  89.                 border-top-left-radius: 30px;
  90.                 border-top-right-radius: 30px;
  91.         }
  92.         .area-cascader_box-header{
  93.                 width: 100%;
  94.                 flex-flow: row nowrap;
  95.                 justify-content: space-between;
  96.                 align-items: center;
  97.                 padding: 10px 15px 0 15px;
  98.         }
  99.         .area-cascader_box-header-label{
  100.                 font-size: 18px;
  101.         }
  102.         .area-cascader_box-header-button{
  103.                 font-size: 40px;
  104.                 color: #ccc;
  105.         }
  106.         .area-cascader_box-nav{
  107.                 width: 100%;
  108.                 flex-flow: row nowrap;
  109.                 justify-content: flex-start;
  110.                 align-items: center;
  111.                 padding: 15px;
  112.         }
  113.         .area-cascader_box-nav-item{
  114.                 box-sizing: border-box;
  115.                 align-items: center;
  116.                 /* background-color: #452334; */
  117.                 margin-right: 20px;
  118.                 justify-content: center;
  119.         }
  120.         .area-cascader_box-nav-item--selected{
  121.                 font-size: 16px;
  122.                 padding-bottom: 10px;       
  123.                 border-bottom: 3px solid #49c916;
  124.         }
  125.         .area-cascader_box-nav-item--unselected{
  126.                 font-size: 16px;
  127.                 padding-bottom: 10px;
  128.                 border-bottom: 3px solid #49c916;
  129.         }
  130.         .area-cascader_box-nav-item--result{
  131.                 font-size: 16px;
  132.                 padding-bottom: 13px;
  133.                 border-bottom: 0;
  134.         }
  135.         .area-cascader_pane{
  136.                 padding-left: 15px;
  137.                 padding-right: 10px;
  138.                 width: 100%;
  139.                 height: 80%;
  140.         }
  141.         .area-cascader_pane-option{       
  142.                 flex-flow: row nowrap;
  143.                 align-items: flex-start;
  144.                 justify-content: space-between;
  145.                 padding: 5px 0;
  146.         }
  147. </style>
复制代码
组件使用
demo-area-cascader.stml
  1. <template>
  2.         <view class="page">
  3.                 <safe-area></safe-area>
  4.                 <text style="padding:10px;font-size:20px;">地区级联选择</text>
  5.                 <view class="box" @click="openCascader">
  6.                         <text>地区</text>
  7.                         <text>{selectArea}</text>
  8.                         <image class="more" src={ico} mode="widthFix"></image>
  9.                 </view>
  10.                 <area-cascader
  11.                         :options="areaValue"
  12.                         onfinish="getArea"
  13.                         onclose="closeCascader"
  14.                         v-if="isShowCascader"
  15.                 >
  16.                 </area-cascader>
  17.         </view>
  18. </template>
  19. <script>
  20.         import '../../components/area-cascader.stml'
  21.         import {areaList,getTree,getArea,getProvince,getCity} from '../../utils/areaList.js'
  22.         export default {
  23.                 name: 'demo-area-cascader',
  24.                 apiready(){
  25.                         this.data.areaValue = getTree();
  26.                         // getCity('130000');
  27.                         // getProvince();
  28.                         // getArea('130200');
  29.                 },
  30.                 data() {
  31.                         return{
  32.                                 selectArea:'',
  33.                                 areaValue:[],
  34.                                 isShowCascader:false,
  35.                                 ico:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAZRJREFUeF7t2z1KxEAYgOF3D2Old7AVsdlirS3sBEE9gB5gYQtLC3utxZPYeRgZ2CKEXSGT+X4nqUIgkPfJzBQZsqLzY9V5PwvAMgLsBDbAGjgHPoAHi0exnALvwM0g+hO41kawBNgCT6NgdQRLgAvg+8AbV0WwBCjtZR0o8398qCFYA5gjeAAwRfACYIbgCcAEwRuAOoJHAFUErwBqCJ4BVBC8A4gjRAAQRYgCIIYQCUAEIRpAc4SIAE0RogI0Q4gM0AQhOsBshAwAsxCyAFQjZAKoQsgGMBkhI8B/CK/A/fATdFaAYwi/wEnPAD/AWQ8AxzZcdsBjdoBJu03Z1oBJ8WUkZAKYHJ8JoCo+C0B1fAaAWfHRAWbHRwZoEh8VoFl8RICm8dEAmsdHAhCJjwIgFh8BQDTeO4B4vGcAlXivAGrxHgFU470BqMd7AjCJ9wJgFu8BwDTeGuAS+Bp+ot6fq/0rYA3wBtyOAFTjrQFegOcBgHq8NcDV/qepU6DE3x2YDuKXMu0LVGEtAFVsiW7qfgT8AYVYcEHJaD3BAAAAAElFTkSuQmCC',
  36.                                
  37.                         }
  38.                 },
  39.                 methods: {
  40.                         getArea(e){
  41.                                 // console.log(JSON.stringify(e));
  42.                                 this.data.selectArea = e.detail[0].text+'/'+e.detail[1].text+'/'+e.detail[2].text;
  43.                                 this.data.isShowCascader = false;
  44.                         },
  45.                         openCascader(e){
  46.                                 this.data.isShowCascader = true;
  47.                         },
  48.                         closeCascader(e){
  49.                                 this.data.isShowCascader = false;
  50.                         }
  51.                 }
  52.         }
  53. </script>
  54. <style>
  55.         .page {
  56.                 height: 100%;
  57.                 background-color: #ffffff;
  58.         }
  59.         .box{
  60.                 flex-flow: row nowrap;
  61.                 justify-content: space-between;
  62.                 align-items: center;
  63.                 margin: 10px;
  64.                 border-radius: 5px;
  65.                 background-color: #f0f0f0;
  66.                 padding: 10px;
  67.         }
  68.         .more{
  69.                 width: 20px;
  70.         }
  71. </style>
复制代码
使用示例
微信图片_20220606171518.jpg微信图片_20220606171533.jpg

本文暂无评论,快来抢沙发!