微信小程序 使用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 相关文章推荐
JS 分号引起的一段调试问题
Jun 18 Javascript
juqery 学习之三 选择器 层级 基本
Nov 25 Javascript
服务器端的JavaScript脚本 Node.js 使用入门
Mar 07 Javascript
javascript阻止浏览器后退事件防止误操作清空表单
Nov 22 Javascript
深入学习JavaScript中的原型prototype
Aug 13 Javascript
JavaScript实现跑马灯抽奖活动实例代码解析与优化(二)
Feb 16 Javascript
jQuery禁用快捷键例如禁用F5刷新 禁用右键菜单等的简单实现
Aug 31 Javascript
jQuery中clone()函数实现表单中增加和减少输入项
May 13 jQuery
详解React native全局变量的使用(跨组件的通信)
Sep 07 Javascript
vue-cli项目优化方法- 缩短首屏加载时间
Apr 01 Javascript
Javascript 类型转换、封闭函数及常见内置对象操作示例
Nov 15 Javascript
Node.js创建一个Express服务的方法详解
Jan 06 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
德生1994机评
2021/03/02 无线电
一个简单的PHP投票程序源码
2007/03/11 PHP
php empty,isset,is_null判断比较(差异与异同)
2010/10/19 PHP
PHP实现自动发送邮件功能代码(qq 邮箱)
2017/08/18 PHP
Laravel 5.5基于内置的Auth模块实现前后台登陆详解
2017/12/21 PHP
js调用activeX获取u盘序列号的代码
2011/11/21 Javascript
基于jquery自定义的漂亮单选按钮RadioButton
2013/11/19 Javascript
javascript event在FF和IE的兼容传参心得(绝对好用)
2014/07/10 Javascript
一个很有趣3D球状标签云兼容IE8
2014/08/22 Javascript
jQuery中click事件的定义和用法
2014/12/20 Javascript
javascript模拟评分控件实现方法
2015/05/13 Javascript
利用JavaScript的AngularJS库制作电子名片的方法
2015/06/18 Javascript
jQuery焦点图切换特效代码分享
2015/09/15 Javascript
JavaScript编写简单的计算器
2015/11/25 Javascript
Angular2学习笔记——详解NgModule模块
2016/12/02 Javascript
vuejs简单验证码功能完整示例
2019/01/08 Javascript
vue轻量级框架无法获取到vue对象解决方法
2019/05/12 Javascript
Vue.use()在new Vue() 之前使用的原因浅析
2019/08/26 Javascript
layui table 多行删除(id获取)的方法
2019/09/12 Javascript
使用httplib模块来制作Python下HTTP客户端的方法
2015/06/19 Python
Python 爬虫学习笔记之正则表达式
2016/09/21 Python
Python编程实现两个文件夹里文件的对比功能示例【包含内容的对比】
2017/06/20 Python
Python 通配符删除文件的实例
2018/04/24 Python
详解windows python3.7安装numpy问题的解决方法
2018/08/13 Python
Python3的介绍、安装和命令行的认识(推荐)
2018/10/20 Python
pycharm在调试python时执行其他语句的方法
2018/11/29 Python
对python实现模板生成脚本的方法详解
2019/01/30 Python
Series和DataFrame使用简单入门
2019/11/13 Python
Python实现定时监测网站运行状态的示例代码
2020/09/30 Python
解决pytorch 的state_dict()拷贝问题
2021/03/03 Python
蒙蒂塞罗商店:Monticello Shop
2018/11/25 全球购物
师范生自荐信范文
2013/10/06 职场文书
酒店员工培训方案
2014/06/02 职场文书
护士优质服务演讲稿
2014/08/26 职场文书
大国崛起观后感
2015/06/02 职场文书
单位收入证明范本
2015/06/18 职场文书