微信小程序 使用picker封装省市区三级联动实例代码

微信小程序 使用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)

相关推荐

  • 微信小程序 wx.request(接口调用方式)详解及实例

    微信小程序 wx.request----接口调用方式 最近开发了一个微信小程序版的任务管理系统,在向Java后台发送接口时遇到了一些问题,在这里做一个简单的总结. 官方接口 官方给出的接口叫做wx.request,请求方式比较简单,下面是官网给出的请求实例. wx.request({ url: 'test.php', //仅为示例,并非真实的接口地址 data: { x: '' , y: '' }, header: { 'content-type': 'application/json' },

  • 微信小程序 获取微信OpenId详解及实例代码

    获取微信OpenId 先获取code 再通过code获取authtoken,从authtoken中取出openid给前台 微信端一定不要忘记设定网页账号中的授权回调页面域名 流程图如下 主要代码 页面js代码 /* 写cookie */ function setCookie(name, value) { var Days = 30; var exp = new Date(); exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000); doc

  • 微信小程序 input输入框控件详解及实例(多种示例)

    微信小程序 input输入框控件 今天主要详写一下微信小程序中的Input输入框控件,输入框在程序中是最常见的,登录,注册,获取搜索框中的内容等等都需要,同时,还需要设置不同样式的输入框,今天的代码中都要相应的使用. 首先主页面中将登录的样式进行了简单展示和使用, 代码如下: <!--index.wxml--> <!--如果在同一个form表单中创建了多个input输入框,可以给给每个输入框,创建自己的 name="userName"属性,可以区别哪个输入框,并通过添

  • 微信小程序 实战小程序实例

    微信小程序基本组件和API已撸完,总归要回到正题的,花了大半天时间做了个精简版的百思不得姐,包括段子,图片,音频,视频,四个模块.这篇就带着大家简述下这个小的APP,源码会放到GitHub上欢迎start. 项目中我能学到什么? tabbar使用方式 网络调用真实接口 loading使用 scroll-view实现下拉刷新上拉加载 image组件对图片的处理, 音乐和视频组件的使用 跳转传值使用 等等等.... app.json全局配置文件 { "pages":[ "page

  • 微信小程序 数据访问实例详解

    先简单说一下,小程序的结构 如图所示 1.每个视图(.wxml)只需要添加对应名字的脚本(.js)和样式(.wxss)就可以了,不需要引用,page下面的脚本以及样式都是继承至最外面的app.js , app.wxcss 2.脚本也就是.js文件,他有固定格式:page,是用于获取数据的 3.utils是用来放置数据接口的 数据访问,如果懂点ajax,都不是问题,没啥好讲的 微信小程序,因为IDE太烂了,如果代码再写得难以阅读,整个项目就很难维护了. 因为没有写过app,不知道在app中数据访问

  • 微信小程序-消息提示框实例

    做Android的时候对toast是很熟悉的.微信小程序开发中toast也是重要的消息提示方式. 提示框: wx.showToast(OBJECT) 显示消息提示框 OBJECT参数说明: 示例代码: wx.showToast({ title: '成功', icon: 'success', duration: 2000 }) wx.hideToast() 隐藏消息提示框 wx.showToast({ title: '加载中', icon: 'loading', duration: 10000 }

  • 微信小程序 实现列表刷新的实例详解

    微信小程序 列表刷新: 微信小程序,最近自己学习微信小程序的知识,就想实现现在APP 那种列表刷新,下拉刷新,上拉加载等功能. 先开看一下界面 1.wx.request (获取远程服务器的数据,可以理解成$.ajax) 2. scroll-view的两个事件 2.1 bindscrolltolower(滑到页面底部时) 2.2 bindscroll (页面滑动时) 2.3 bindscrolltoupper (滑倒页面顶部时) 然后我们看代码,详细描述. index.js var url = "

  • 微信小程序(应用号)简单实例应用及实例详解

    Demo 预览 演示视频(流量预警 2.64MB) GitHub Repo 地址 仓库地址:https://github.com/zce/weapp-demo 使用步骤 将仓库克隆到本地: bash $ git clone https://github.com/zce/weapp-demo.git weapp-douban --depth 1 $ cd weapp-douban 打开微信Web开放者工具(注意:必须是0.9.092300版本) 必须是0.9.092300版本,之前的版本不能保证正

  • 微信小程序 地图定位简单实例

    微信小程序开发地图定位. 微信小程序 刚刚公布没多久,自己学习一下内容,以便以后的开发,想落后别人,这里做了一个简单的小程序示例,大家可以参考下 要求要完成的功能: 1.要完成的要点是城市定位. 2.就是切换城市. 首页我们先参照微信小程序开放的官方文档找到: 在这里我们可以找到"当前位置经纬度" getLocation: function () { var that = this wx.getLocation( { success: function (res) { console.

  • 微信小程序开发之入门实例教程篇

    前言 近日,在工作闲暇之余,阅读了一些关于微信小程序的文章,忍不住,想动手试他一试.本文就以"我的第一个微信小程序"为例,简单的介绍下,微信小程序的入门级用法. 一.注册小程序账号 1.进入微信公众平台(https://mp.weixin.qq.com/),注册小程序账号,根据提示填写对应的信息即可. 2.注册成功后进入首页,在 小程序发布流程->小程序开发与管理->配置服务器中,点击"开发者设置". 3.会获得一个AppID,记录AppID,后面创建项

随机推荐