微信开发 使用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 相关文章推荐
Jquery中删除元素的实现代码
Dec 29 Javascript
php和js对数据库图片进行等比缩放示例
Apr 28 Javascript
js图片闪动特效可以控制间隔时间如几分钟闪动一下
Aug 12 Javascript
javascript面向对象之共享成员属性与方法及prototype关键字用法
Jan 13 Javascript
JS清除字符串中重复值的实现方法
Aug 03 Javascript
详解微信小程序 wx.uploadFile 的编码坑
Jan 23 Javascript
Vue仿今日头条实例详解
Feb 06 Javascript
[原创]jQuery实现合并/追加数组并去除重复项的方法
Apr 11 jQuery
jQuery实现的网站banner图片无缝轮播效果完整实例
Jan 28 jQuery
axios如何利用promise无痛刷新token的实现方法
Aug 27 Javascript
js消除图片小游戏代码
Dec 11 Javascript
js实现弹幕墙效果
Dec 10 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
php程序效率优化的一些策略小结
2010/07/17 PHP
PHP可逆加密/解密函数分享
2012/09/25 PHP
PHP If Else(elsefi) 语句
2013/04/07 PHP
浅谈php中mysql与mysqli的区别分析
2013/06/10 PHP
yii通过小物件生成view的方法
2016/10/08 PHP
PHP实现微信小程序用户授权的工具类示例
2019/03/05 PHP
Laravel 前端资源配置教程
2019/10/18 PHP
用php实现分页效果的示例代码
2020/12/10 PHP
js过滤特殊字符输入适合输入、粘贴、拖拽多种情况
2014/03/22 Javascript
JQuery中的事件及动画用法实例
2015/01/26 Javascript
javascript实现图像循环明暗变化的方法
2015/02/25 Javascript
jquery+css实现的红色线条横向二级菜单效果
2015/08/22 Javascript
jQuery动态修改字体大小的方法【测试可用】
2016/09/09 Javascript
JS+HTML5实现图片在线预览功能
2017/07/22 Javascript
Angular5集成eventbus的示例代码
2018/07/19 Javascript
Nginx设置为Node.js的前端服务器方法总结
2019/03/27 Javascript
前端面试知识点目录一览
2019/04/15 Javascript
react 组件传值的三种方法
2019/06/03 Javascript
浅谈Layui的eleTree树式选择器使用方法
2019/09/25 Javascript
vue计算属性+vue中class与style绑定(推荐)
2020/03/30 Javascript
uniapp 仿微信的右边下拉选择弹出框的实现代码
2020/07/12 Javascript
Django查找网站项目根目录和对正则表达式的支持
2015/07/15 Python
Ruby使用eventmachine为HTTP服务器添加文件下载功能
2016/04/20 Python
Python检测数据类型的方法总结
2019/05/20 Python
PyQt5固定窗口大小的方法
2019/06/18 Python
Python enumerate函数遍历数据对象组合过程解析
2019/12/11 Python
python+django+selenium搭建简易自动化测试
2020/08/19 Python
Selenium结合BeautifulSoup4编写简单的python爬虫
2020/11/06 Python
德国网上宠物店:Zoobio
2018/05/23 全球购物
Probikekit欧盟:在线公路自行车专家
2019/07/12 全球购物
自荐信写法介绍
2014/01/25 职场文书
考试没考好检讨书
2014/01/31 职场文书
《数星星的孩子》教学反思
2014/04/11 职场文书
协议书与合同的区别
2014/04/18 职场文书
python 如何用map()函数创建多线程任务
2021/04/07 Python
为什么MySQL8新特性会修改自增主键属性
2022/04/18 MySQL