微信小程序 使用picker封装省市区三级联动实例代码


Posted in Javascript onOctober 28, 2016

 微信小程序 使用picker封装省市区三级联动实例

  目前学习小程序更多的是看看能否二次封装其它组件,利于以后能快速开发各种小程序应用。目前发现picker的selector模式只有一级下拉,那么我们是否可以通过3个picker来实现三级联动模板的形式来引入其它页面中呢?答案是肯定可以的。那么我的思路是这样的:

1、使用template模板语法进行封装,数据从页面传入

2、根据picker组件的语法,range只能是一组中文地区数组,但是我们需要每个地区的唯一码来触发下一级联动数据。这样,我的做法是通过一个对象里面的两组数据分表存储中文名和唯一码的两个对象数组。格式【province:{code:['110000', '220000'...], name: ['北京市', '天津市'...]}】,这个格式是固定的,需要服务端配合返回

3、通过picker的bindchange事件来获取下一级的数据,每个方法都写入函数中在暴露出来供页面调用

然后讲下我demo的目录结构:

common

    -net.js//wx.request请求接口二次整合

    -cityTemplate.js//三级联动方法

page

    -demo

        -demo.js

        -demo.wxml

template

    -cityTemplate.wxml

app.js

app.json

app.wxss

然后,使用phpstudy搭建了简单的服务端供测试。不要问我服务端的为啥是这样的,我也不懂,刚入门我只要数据...

当然你可以省掉这一步,将数据直接固定在demo.js里面进行测试...

代码如下:【服务端的返回数据格式是遵循了下面的retArr的规范的】

<?php 
header("Content-type: text/html; charset=utf-8");  
 
$type=$_REQUEST["type"];//获取省市区的标志 
$fcode=$_GET["fcode"]; 
 
$retArr=[ 
  "status"=>true, 
  "data"=>[], 
  "msg"=>"" 
]; 
 
if($type!="province" && $type!="city" && $type!="county"){ 
  $retArr["status"]=false; 
  $retArr["msg"]="获取地区类型错误,请检查"; 
   
  echo json_encode($retArr); 
  exit; 
} 
 
function getProvince(){ 
  $province=[]; 
  $code=["110000", "350000", "710000"]; 
  $province["code"]=$code; 
  $name=["北京市", "福建省", "台湾省"]; 
  $province["name"]=$name; 
  $fcode=["0", "0", "0"]; 
  $province["fcode"]=$fcode; 
  return $province; 
} 
function getCity($P_fcode){ 
  $city=[]; 
  $code=[]; 
  $name=[]; 
  $fcode=[]; 
  if($P_fcode=="110000"){ 
    $code=["110100"]; 
    $name=["北京市"]; 
    $fcode=$P_fcode; 
  } 
  if($P_fcode=="350000"){ 
    $code=["350100", "350200", "350300", "350400", "350500", "350600", "350700", "350800", "350900"]; 
    $name=["福州市", "厦门市", "莆田市", "三明市", "泉州市", "漳州市", "南平市", "龙岩市", "宁德市"]; 
    $fcode=$P_fcode; 
  } 
  if($P_fcode=="710000"){ 
     
  } 
  $city=["code"=>$code, "name"=>$name, "fcode"=>$fcode]; 
  return $city; 
} 
function getCounty($P_fcode){ 
  $county=[]; 
  $code=[]; 
  $name=[]; 
  $fcode=[];  
  if($P_fcode=="110100"){ 
    $code=["110101", "110102", "110103", "110104", "110105", "110106", "110107"]; 
    $name=["东城区", "西城区", "崇文区", "宣武区", "朝阳区", "丰台区", "石景山区"]; 
    $fcode=$P_fcode; 
  } 
  if($P_fcode=="350100"){ 
    $code=["350102", "350103", "350104"]; 
    $name=["鼓楼区", "台江区", "苍山区"]; 
    $fcode=$P_fcode; 
  } 
  if($P_fcode=="350200"){ 
    $code=["350203", "350205", "350206"]; 
    $name=["思明区", "海沧区", "湖里区"]; 
    $fcode=$P_fcode; 
  } 
  $county=["code"=>$code, "name"=>$name, "fcode"=>$fcode]; 
  return $county; 
} 
 
//var_dump($province); 
if($type=="province"){ 
  $province=getProvince(); 
  $retArr["data"]=$province;  
}else if($type=="city"){ 
  $city=getCity($fcode); 
  $retArr["data"]=$city; 
}else if($type="county"){ 
  $county=getCounty($fcode); 
  $retArr["data"]=$county; 
} 
 
echo json_encode($retArr); 
 
 
?>

接下来是cityTemplate.wxml::

<template name="city"> 
<view class="areas"> 
 <view class="province"> 
  <picker bindchange="provincePickerChange" value="{{provinceIndex}}" range="{{province.name}}" data-city-url="{{cityUrl}}"> 
  <text class="select-item">{{province.name[provinceIndex]}}</text> 
  </picker> 
 </view> 
 
 <view class="city"> 
 <block wx:if="{{!city.name.length}}"> --二级市区-- </block> 
 <block wx:if="{{city.name.length>0}}">  
  <picker bindchange="cityPickerChange" value="{{cityIndex}}" range="{{city.name}}" data-county-url="{{countyUrl}}"> 
   <text class="select-item">{{city.name[cityIndex]}}</text> 
  </picker> 
 </block> 
 </view> 
 
 <view class="county"> 
 <block wx:if="{{!county.name.length}}"> --三级地区-- </block> 
 <block wx:if="{{county.name.length>0}}"> 
  <picker bindchange="countyPickerChange" value="{{countyIndex}}" range="{{county.name}}"> 
   <text class="select-item">{{county.name[countyIndex]}}</text> 
  </picker> 
 </block> 
 </view> 
 
</view> 
</template>

cityTemplate.js::

/** 
 * 获取三级联动的三个函数 
 * that:  注册页面的this实例 必填 
 * p_url: 一级省份url 必填 
 * p_data:一级省份参数 选填 
 */ 
var net = require( "net" );//引入request方法 
var g_url, g_datd, g_cbSuccess, g_cbSuccessErr, g_cbFail, g_cbComplete, g_header, g_method; 
 
function initCityFun( that, p_url, p_data ) { 
  //获取一级省份数据 
  g_cbSuccess = function( res ) { 
   that.setData( { 
    'city.province': res 
   }); 
  }; 
  net.r( p_url, p_data, g_cbSuccess, g_cbSuccessErr, g_cbFail, g_cbComplete, g_header, g_method ); 
 
  //点击一级picker触发事件并获取市区方法 
  var changeProvince = function( e ) { 
    that.setData( { 
      'city.provinceIndex': e.detail.value 
    }); 
    var _fcode = that.data.city.province.code[ e.detail.value ]; 
    if( !_fcode ) { 
      _fcode = 0; 
    } 
    var _cityUrl = e.target.dataset.cityUrl; 
 
    g_url = _cityUrl + _fcode; 
    g_cbSuccess = function( res ) { 
      that.setData( { 
        'city.city': res 
      }); 
    } 
    net.r( g_url, g_datd, g_cbSuccess, g_cbSuccessErr, g_cbFail, g_cbComplete, g_header, g_method ); 
  }; 
  that[ "provincePickerChange" ] = changeProvince; 
 
  //点击二级picker触发事件并获取地区方法 
  var changeCity = function( e ) { 
    that.setData( { 
      'city.cityIndex': e.detail.value 
    }); 
    var _fcode = that.data.city.city.code[ e.detail.value ]; 
    if( !_fcode ) { 
      _fcode = 0; 
    } 
    var _countyUrl = e.target.dataset.countyUrl; 
    g_url = _countyUrl + _fcode; 
 
    g_cbSuccess = function( res ) { 
      that.setData( { 
        'city.county': res 
      }); 
    }; 
    net.r( g_url, g_datd, g_cbSuccess, g_cbSuccessErr, g_cbFail, g_cbComplete, g_header, g_method ); 
  }; 
  that[ "cityPickerChange" ] = changeCity; 
 
  //点击三级picker触发事件 
  var changeCounty = function( e ) { 
    that.setData( { 
      'city.countyIndex': e.detail.value 
    }); 
  }; 
  that["countyPickerChange"]=changeCounty; 
} 
 
function getProvinceFun(that, p_url, p_data){ 
  g_cbSuccess = function( res ) { 
   that.setData( { 
    'city.province': res 
   }); 
  }; 
  net.r( p_url, p_data, g_cbSuccess, g_cbSuccessErr, g_cbFail, g_cbComplete, g_header, g_method ); 
} 
 
module.exports={ 
  initCityFun: initCityFun, 
  getProvinceFun: getProvinceFun 
}

顺道net.js方法::

/** 
 * 网络发送http请求,默认为返回类型为json 
 *  
 * url: 必须,其他参数非必须 接口地址 
 * data:请求的参数 Object或String 
 * successFun(dts):成功返回的回调函数,已自动过滤微信端添加数据,按接口约定,返回成功后的data数据,过滤掉msg和status 
 * successErrorFun(msg):成功执行请求,但是服务端认为业务错误,执行其他行为,默认弹出系统提示信息. 
 * failFun:接口调用失败的回调函数 
 * completeFun:接口调用结束的回调函数(调用成功、失败都会执行) 
 * header:object,设置请求的 header , header 中不能设置 Referer 
 * method:默认为 GET,有效值:OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT 
 *  
 */ 
function r( url, data, successFun, successErrorFun, failFun, completeFun, header, method ) { 
  var reqObj = {}; 
  reqObj.url = url; 
  reqObj.data = data; 
 
  //默认头为json 
  reqObj.header = { 'Content-Type': 'application/json' }; 
  if( header ) { 
    //覆盖header 
    reqObj.header = header; 
  } 
 
 
  if( method ) { 
    reqObj.method = method; 
  } 
  reqObj.success = function( res ) { 
    var returnData = res.data; //将微信端结果过滤,获取服务端返回的原样数据 
    var status = returnData.status; //按接口约定,返回status时,才调用成功函数 
    //console.log(res); 
    //正常执行的业务函数 
    if( status == true ) { 
      if( successFun ) { 
        var dts = returnData.data; 
        successFun( dts );//回调,相当于获取到data后直接在回调里面处理赋值数据 
      } 
    } else if( status == false ) { 
      var msg = returnData.msg; 
      if( !successErrorFun ) { 
        console.log( msg ); 
      } else { 
        successErrorFun( msg ); 
      } 
 
    } else { 
      console.log( "服务端没有按照接口约定格式返回数据" ); 
    } 
 
 
  } 
  reqObj.fail = function( res ) { 
    if( failFun ) { 
      failFun( res ); 
    } 
  } 
  reqObj.complete = function( res ) { 
    if( completeFun ) { 
      completeFun( res ); 
    } 
  } 
 
 
  wx.request( reqObj ); 
} 
 
module.exports = { 
  r: r 
}

核心代码就是上面这三个文件,接下来是demo文件做测试::

demo.wxml::

<import src="../../template/cityTemplate.wxml"/> 
<template is="city" data="{{...city}}" />

demo.js::

var city = require( '../../common/cityTemplate' ); 
Page( { 
 data: { 
 
 }, 
 onLoad: function( options ) { 
  var _that = this; 
  //创建三级联动数据对象 ---- 这个city对象是固定的,只有请求的url是根据各自的服务端地址来更改的 
  _that.setData( { 
   city: { 
    province: {},//格式province:{code: ["11000", "12000"], name: ["北京市", "上海市"]},只能固定是name和code,因为模板需要根据这俩参数显示 
    city: {}, 
    county: {}, 
    provinceIndex: 0, 
    cityIndex: 0, 
    countyIndex: 0, 
    cityUrl: "http://localhost:8282/phpserver/areas.php?type=city&fcode=",//type表示获取地区 fcode是一级code码,到时具体根据后端请求参数修改 
    countyUrl: "http://localhost:8282/phpserver/areas.php?type=county&fcode=" 
   } 
  }) 
  var _url = "http://localhost:8282/phpserver/areas.php"; 
  var _data = { 'type': 'province', 'fcode': '0' }; 
  city.initCityFun( _that, _url, _data ); 
 } 
})

以上完整代码文件,最终测试如下:

微信小程序 使用picker封装省市区三级联动实例代码

这里存在一个bug,开启下拉刷新和picker组件的下拉会重叠了,不知道是开发工具原因,还是还为修改的bug。。。只能等微信方面更新消息给反馈了

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
HTML代码中标签的全部属性 中文注释说明
Mar 26 Javascript
JS封装的自动创建表格的实现代码
Jun 15 Javascript
JavaScript实现form表单的多文件上传
Mar 27 Javascript
Angularjs之如何在跨域请求中传输Cookie的方法
Jun 01 Javascript
vue实现引入本地json的方法分析
Jul 12 Javascript
mpvue中使用flyjs全局拦截的实现代码
Sep 13 Javascript
微信小程序下拉框组件使用方法详解
Dec 28 Javascript
基于jQuery实现可编辑的表格
Dec 11 jQuery
Vue两个版本的区别和使用方法(更深层次了解)
Feb 16 Javascript
详解Vue中的Props与Data细微差别
Mar 02 Javascript
解决vue里a标签值解析变量,跳转页面,前面加默认域名端口的问题
Jul 22 Javascript
vue keep-alive实现多组件嵌套中个别组件存活不销毁的操作
Oct 30 Javascript
基于Layer+jQuery的自定义弹框
May 26 #Javascript
微信开发 js实现tabs选项卡效果
Oct 28 #Javascript
微信开发 使用picker封装省市区三级联动模板
Oct 28 #Javascript
Easyui的组合框的取值与赋值
Oct 28 #Javascript
JS制作适用于手机和电脑的通知信息效果
Oct 28 #Javascript
Jquery UI实现一次拖拽多个选中的元素操作
Dec 01 #Javascript
浅谈js继承的实现及公有、私有、静态方法的书写
Oct 28 #Javascript
You might like
Netflix将与CLAMP、乙一以及冲方丁等6名知名制作人合伙展开原创动画计划!
2020/03/06 日漫
环境会对咖啡种植有什么影响
2021/03/03 咖啡文化
php select,radio和checkbox默认选择的实现方法
2010/05/15 PHP
使用 PHPStorm 开发 Laravel
2015/03/24 PHP
php使用pclzip类实现文件压缩的方法(附pclzip类下载地址)
2016/04/30 PHP
PHP实现冒泡排序的简单实例
2016/05/26 PHP
php处理复杂xml数据示例
2016/07/11 PHP
PHP入门教程之上传文件实例详解
2016/09/11 PHP
PHP自动补全表单的两种方法
2017/03/06 PHP
thinkPHP多表查询及分页功能实现方法示例
2017/07/03 PHP
caller和callee的区别介绍及演示结果
2013/03/10 Javascript
关于JavaScript与HTML的交互事件
2013/04/12 Javascript
jQuery多项选项卡的实现思路附样式及代码
2014/06/03 Javascript
js代码实现随机颜色的小方块
2015/07/30 Javascript
初步使用bootstrap快速创建页面
2016/03/03 Javascript
jQuery实现定位滚动条位置
2016/08/05 Javascript
jQuery ajax动态生成table功能示例
2017/06/14 jQuery
layui结合form,table的全选、反选v1.0示例讲解
2018/08/15 Javascript
js实现的格式化数字和金额功能简单示例
2019/07/30 Javascript
js实现简单放大镜效果
2020/03/07 Javascript
Javascript实现单选框效果
2020/12/09 Javascript
[06:15]2016国际邀请赛中国区预选赛单车采访:我顶WINGS
2016/06/27 DOTA
[01:34]2016国际邀请赛中国区预选赛IG战队教练采访
2016/06/27 DOTA
利用Python抓取行政区划码的方法
2016/11/28 Python
Python 循环语句之 while,for语句详解
2018/04/23 Python
Python selenium抓取微博内容的示例代码
2018/05/17 Python
python opencv 批量改变图片的尺寸大小的方法
2019/06/28 Python
基于Tensorflow使用CPU而不用GPU问题的解决
2020/02/07 Python
python自动下载图片的方法示例
2020/03/25 Python
python2和python3哪个使用率高
2020/06/23 Python
高性能装备提升营地:Kammok
2019/02/27 全球购物
Python面试题:Python是如何进行内存管理的
2014/08/04 面试题
大学四年规划书范文
2013/12/27 职场文书
员工自我评价范文
2015/03/11 职场文书
2015年社区妇联工作总结
2015/04/21 职场文书
放假通知怎么写
2015/08/18 职场文书