目前學習小程序更多的是看看能否二次封裝其它組件,利於以後能快速開發各種小程序應用。目前發現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。。。只能等微信方面更新消息給反饋了。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持。