微信开发 使用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 相关文章推荐
Node.js实战 建立简单的Web服务器
Mar 08 Javascript
jquery单击事件和双击事件冲突解决方案
Mar 02 Javascript
基于JS实现textarea中获取动态剩余字数的方法
May 25 Javascript
全面解析Angular中$Apply()及$Digest()的区别
Aug 04 Javascript
JavaScript自定义分页样式
Jan 17 Javascript
jQuery实现Table表格隔行变色及高亮显示当前选择行效果示例
Feb 14 Javascript
js仿新浪微博消息发布功能
Feb 17 Javascript
JavaScript之Date_动力节点Java学院整理
Jun 28 Javascript
es6+angular1.X+webpack 实现按路由功能打包项目的示例
Aug 16 Javascript
vue2.x+webpack快速搭建前端项目框架详解
Nov 30 Javascript
JavaScript实现学生在线做题计时器功能
Dec 05 Javascript
Vee-validate 父组件获取子组件表单校验结果的实例代码
May 20 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
Ajax实时验证用户名/邮箱等是否已经存在的代码打包
2011/12/01 PHP
PHP判断文件是否被引入的方法get_included_files用法示例
2016/11/29 PHP
BOOM vs RR BO3 第二场2.13
2021/03/10 DOTA
使用Raygun来自动追踪AngularJS中的异常
2015/06/23 Javascript
全面解析JavaScript中的valueOf与toString方法(推荐)
2016/06/14 Javascript
AngularJS深入探讨scope,继承结构,事件系统和生命周期
2016/11/02 Javascript
JS常见简单正则表达式验证功能小结【手机,地址,企业税号,金额,身份证等】
2017/01/22 Javascript
js中小数向上取整数,向下取整数,四舍五入取整数的实现(必看篇)
2017/02/13 Javascript
js中document.referrer实现移动端返回上一页
2017/02/22 Javascript
Vue.js实战之组件的进阶
2017/04/04 Javascript
Webpack常见静态资源处理-模块加载器(Loaders)+ExtractTextPlugin插件
2017/06/29 Javascript
vue组件初学_弹射小球(实例讲解)
2017/09/06 Javascript
微信小程序使用image组件显示图片的方法【附源码下载】
2017/12/08 Javascript
Angular利用内容投射向组件输入ngForOf模板的方法
2018/03/05 Javascript
vue js秒转天数小时分钟秒的实例代码
2018/08/08 Javascript
ES6入门教程之Array.from()方法
2019/03/23 Javascript
使用jQuery mobile NuGet让你的网站在移动设备上同样精彩
2019/06/18 jQuery
JS前端知识点总结之页面加载事件,数组操作,DOM节点操作,循环和分支
2019/07/04 Javascript
Weex开发之地图篇的具体使用
2019/10/16 Javascript
解决Echarts2竖直datazoom滑动后显示数据不全的问题
2020/07/20 Javascript
Python实现根据IP地址和子网掩码算出网段的方法
2015/07/30 Python
Python 模块EasyGui详细介绍
2017/02/19 Python
对tensorflow中cifar-10文档的Read操作详解
2020/02/10 Python
Python中的整除和取模实例
2020/06/03 Python
matplotlib.pyplot.matshow 矩阵可视化实例
2020/06/16 Python
Subside Sports德国:足球球衣和球迷商品
2019/06/08 全球购物
爱尔兰最大的体育零售商:Life Style Sports
2019/06/12 全球购物
请写出 float x 与"零值"比较的 if 语句
2016/01/04 面试题
护理实习自我鉴定
2013/12/14 职场文书
追悼会上的答谢词
2014/01/10 职场文书
我的大学生活演讲稿
2014/04/25 职场文书
清洁工岗位职责
2015/02/13 职场文书
费用申请报告范文
2015/05/15 职场文书
大学生军训感言
2015/08/01 职场文书
创业项目大全(适合在家创业的项目)
2019/08/15 职场文书
深入解析Apache Hudi内核文件标记机制
2022/03/31 Servers