微信开发 使用picker封装省市区三级联动模板


Posted in Javascript onOctober 28, 2016

目前学习小程序更多的是看看能否二次封装其它组件,利于以后能快速开发各种小程序应用。目前发现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 相关文章推荐
使用prototype.js进行异步操作
Feb 07 Javascript
JQuery 学习笔记 选择器之六
Jul 23 Javascript
jquery 删除cookie失效的解决方法
Nov 12 Javascript
jQuery中.live()方法的用法深入解析
Dec 30 Javascript
jQuery中each()方法用法实例
Dec 27 Javascript
jquery实现像栅栏一样左右滑出式二级菜单效果代码
Aug 24 Javascript
jquery实现的3D旋转木马特效代码分享
Aug 25 Javascript
Vue自定义指令详解
Jul 28 Javascript
详解Angularjs 自定义指令中的数据绑定
Jul 19 Javascript
解决vue-cli项目webpack打包后iconfont文件路径的问题
Sep 01 Javascript
vuex直接赋值的三种方法总结
Sep 16 Javascript
Node.js中package.json中库的版本号(~和^)
Apr 02 Javascript
Easyui的组合框的取值与赋值
Oct 28 #Javascript
JS制作适用于手机和电脑的通知信息效果
Oct 28 #Javascript
Jquery UI实现一次拖拽多个选中的元素操作
Dec 01 #Javascript
浅谈js继承的实现及公有、私有、静态方法的书写
Oct 28 #Javascript
jQuery.datatables.js插件用法及api实例详解
Oct 28 #Javascript
扩展jquery easyui tree的搜索树节点方法(推荐)
Oct 28 #Javascript
浅谈jQuery中的eq()与DOM中element.[]的区别
Oct 28 #Javascript
You might like
上海永华YH-R296(华普R-96)12波段立体声收音机的分析和打理
2021/03/02 无线电
亲密接触PHP之PHP语法学习笔记1
2006/12/17 PHP
一些php项目中比较通用的php自建函数的详解
2013/06/06 PHP
Zend Studio 实用快捷键一览表(精心整理)
2013/08/10 PHP
基于PHP技术开发客服工单系统
2016/01/06 PHP
php 判断过去离现在几年的函数(实例代码)
2016/11/15 PHP
Yii框架的路由配置方法分析
2019/09/09 PHP
tp5.1框架数据库子查询操作实例分析
2020/05/26 PHP
js检测客户端不是firefox则提示下载
2007/04/07 Javascript
另一个javascript小测验(代码集合)
2011/07/27 Javascript
Jquery validation remote 验证的缓存问题解决方法
2014/03/25 Javascript
随鼠标移动的时钟非常漂亮遗憾的是只支持IE
2014/08/12 Javascript
js实现键盘控制DIV移动的方法
2015/01/10 Javascript
js实现格式化金额,字符,时间的方法
2015/02/26 Javascript
jQuery实现网站添加高亮突出显示效果的方法
2015/06/26 Javascript
javascript 分号总结及详细介绍
2016/09/24 Javascript
javaScript实现滚动条事件详解
2020/03/24 Javascript
简单了解小程序+node梳理登陆流程
2019/06/24 Javascript
原生JavaScript实现幻灯片效果
2021/02/19 Javascript
在Python中操作列表之List.pop()方法的使用
2015/05/21 Python
尝试使用Python多线程抓取代理服务器IP地址的示例
2015/11/09 Python
python使用itchat实现手机控制电脑
2018/02/22 Python
python Celery定时任务的示例
2018/03/13 Python
python监控进程脚本
2018/04/12 Python
python将类似json的数据存储到MySQL中的实例
2019/07/12 Python
Python模块相关知识点小结
2020/03/09 Python
欧洲顶级的童装奢侈品购物网站:Bambini Fashion(面向全球)
2018/04/24 全球购物
adidas马来西亚官网:adidas MY
2020/09/12 全球购物
商务日语毕业生自荐信
2013/11/23 职场文书
公司接待方案
2014/03/08 职场文书
区域销售经理岗位职责
2015/04/02 职场文书
追悼会家属答谢词
2015/09/29 职场文书
2016年区委书记抓基层党建工作公开承诺书
2016/03/25 职场文书
创新创业项目计划书该怎样写?
2019/08/13 职场文书
MySQL Router的安装部署
2021/04/24 MySQL
一篇文章弄懂Python中的内建函数
2021/08/07 Python