微信开发 使用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 );
 }
}) 

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • BootStrap中Datepicker控件带中文的js文件

    bootstrap-datepicker 是一个非常优秀的时间选择插件,默认是英文显示日期的.本文给大家介绍bootstrap datepicker带中文的js文件. //用之前引用bootstrap的jsif ($(".datepicker").length > 0) { $(".datepicker").datepicker({ language: "zh-CN", autoclose: true,//选中之后自动隐藏日期选择框 cle

  • Java通过JsApi方式实现微信支付

    要使用JsApi进行微信支付,首先要从微信获得一个prepay_id,然后通过调用微信的jsapi完成支付,JS API的返回结果get_brand_wcpay_request:ok仅在用户成功完成支付时返回.由于前端交互复杂,get_brand_wcpay_request:cancel或者get_brand_wcpay_request:fail可以统一处理为用户遇到错误或者主动放弃,不必细化区分. 示例代码如下: function onBridgeReady(){ WeixinJSBridge

  • 微信JSSDK上传图片

    前不久微信公开了一些接口,其中有一个uploadImage接口用于上传图片,一般和chooseImage接口配合使用.先调用chooseImage接口让用户选择一张或者多张图片,用户选择完毕后微信会返回被选中图片的id,再把图片id传给uploadImage接口上传图片. 最近做的一个项目,刚好用到了JSSDK,把用到的东西整理下. 先附上微信开发者文档链接:微信开发者文档 主要用到了: 引入JS文件 在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq

  • js实现通用的微信分享组件示例

    一.可定义的信息 1.分享时显示的LOGO:2.分享LOGO的宽度:3.分享LOGO的高度:4.分享出去显示的标题(默认调用网页标题):5.分享出去显示的描述(默认调用网页标题):6.分享链接(默认为当前页面的URL).7.分享微信的APPID(一般为空). 二.使用方法1.引入微信分享组件js: 复制代码 代码如下: /******************************* * Author:Mr.Think * Description:微信分享通用代码 * 使用方法:_WXShare

  • js实现微信分享代码

    通常自己做的一个页面想通过微信像朋友分享时,展示的标题和描述都是不是自己想要的,自己查了一些资料,原来是通过js来进行控制 展示效果如下: 标题.描述.还有分享的图片都是有js来控制的. js代码如下 <script> var dataForWeixin = { appId: "", MsgImg: "Christmas/201012189457639.gif",//显示图片 TLImg: "Christmas/201012189457639.

  • js如何判断用户是否是用微信浏览器

    上周接到个需求,需求是这样的:用户扫一扫二维码会产生一个链接,该链接会向后端发送个请求,返回一个 apk 的下载地址,用户点击下载按钮可以下载此 apk.然后就发生了问题,经过测试,发现用微信扫一扫打开的页面点击下载按钮下载不了 apk,后百度之,原来是微信内置浏览器屏蔽了下载链接,后面和需求方沟通,需求改为如果用户是用微信内置浏览器打开的,则提示用户换一个浏览器打开页面,否则下载不了 apk.那么该如何判断用户是否是用微信浏览器呢? 我们知道 js 可以通过 window.navigator.

  • 微信JS接口汇总及使用详解

    基本说明 使用说明 1.引入JS文件 在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js 备注:支持使用 AMD/CMD 标准模块加载方法加载 2.注入配置config接口 所有需要使用JSSDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用). 复制代码 代码如下: wx.config({  debug:

  • angularjs封装bootstrap时间插件datetimepicker

    背景:angular与jquery类库的协作 第三方类库中,不得不提的是大名鼎鼎的jquery,现在基本上已经是国内web开发的必修工具了.它灵活的dom操作,让很多web开发人员欲罢不能.再加上已经很成熟的jquery UI 库和大量jquery 插件,几乎是一个取之不尽用之不竭的宝库.然而,它是否能与angularjs结合呢? 很多angularjs原教旨主义者对此持否定态度.他们认为,既然已经使用了angularjs做web应用框架,那就必须避免其他类库的干扰,做纯净的MvvM模式应用.任

  • HTML Color Picker(js拾色器效果)

    File Name : colorpicker.html Requirement : Internet Explorer or Mozilla Author : Jean-Luc Antoine Submitted : 26/03/2005 Category : 4K 复制代码 代码如下: <form name="recherche" method="post" action="yourpage.html"><input typ

  • javascript实现的简易的DatePicker日历

    jQ的ui有,YUI的widget里也有.而且也封装的结结实实,兼容性,通用性,都做得挺好.于是在代码完善的同时,代码量自然也不会少.即使建立在基础库之上,代码也是好几百行. 真正使用的时候可能并不需要这么完善的功能.咱们就写个简陋点的东西,够自己用就行了. 而且以前有朋友提出我发的东西都是一些娱乐货,没有什么实用性,这次就当是个开始,抛个砖,以后时不时发个带一些实用性的东东. <!-- 以下demo没有什么出彩的地方,仅供有需要的朋友看看 --> DatePicker .date-picke

随机推荐