项目地址:https://github.com/leesonp/littleAPP.gitphp
2017.07.21 17:30 更新
html
以前版本是从头写到尾没有封装的,有的同窗可能看的一脸懵逼,昨天我用微信官方提供的WXML模板(template)对代码进行了封装,在模板中定义代码片断,经过封装之后咱们就能够在不一样的地方调用了。 Demo已上传到github。前端
文件组成: 1.模板类(model) 2.旧版未封装类 (index) 3.新版调用类 (modelTest) 4.数据源 (area.js)
怎么使用呢? 只需在要用到的类中导入模板模板,引入对应后缀的文件,作一些简单必要操做便可。 以上传的Demo为例:git
// modelTest.js var model = require('../../model/model.js') var show = false; var item = {}; Page({ data: { item: { show: show } }, //生命周期函数--监听页面初次渲染完成 onReady: function (e) { var that = this; //请求数据 model.updateAreaData(that, 0, e); }, //点击选择城市按钮显示picker-view translate: function (e) { model.animationEvents(this, 0, true,400); }, //隐藏picker-view hiddenFloatView: function (e) { model.animationEvents(this, 200, false,400); }, //滑动事件 bindChange: function (e) { model.updateAreaData(this, 1, e); item = this.data.item; this.setData({ province: item.provinces[item.value[0]].name, city: item.citys[item.value[1]].name, county: item.countys[item.value[2]].name }); }, onReachBottom: function (){ }, nono: function (){} })
<!--modelTest.wxml--> <import src="../../model/model.wxml"/> <view class="infoText">{{province}} {{city}} {{county}}</view> <button class="animation-button" bindtap="translate">选择城市</button> <template is="areaData" data="{{...item}}"/>
/* modelTest.wxss */ @import '../../model/model.wxss'
在model.js文件中我就暴露了两个接口,引入模板后,所有代码就这些。是否是感受舒服不少? 代码简洁、逻辑清晰,是封装给咱们带来的好处,但愿没试过封装的同窗能够尝试下。github
-- END --json
------------------------------ 分割线 ------------------------------小程序
2017.07.17 更新
微信小程序
本人以前一直从事iOS开发,最近无项目闲来无事研究了下微信小程序。 我没有像重新学一门语言同样从头至尾看一遍文档,我我的感受小程序相似前端开发,正好以前对前端也略有涉猎,因此直接就拿我以前iOS的项目的某个模块练手,不懂的再去查阅官方文档。 由于有个建立红包的界面,UITableView的某个cell点击会弹出选择区域和时间选择器,下面就给你们讲一下小程序版是怎样的一种操做。数组
在iOS中我用的是UIPickView,体验还OK。那在小程序中选什么控件呢?查阅官方文档,有两种滑动选择器。 微信
picker:从底部弹起的滚动选择器,现支持三种选择器,经过mode来区分,分别是普通选择器,时间选择器,日期选择器,默认是普通选择器。由于是固定的,直接pass掉了。可是最开始我觉得只有这一种,而后想去百度找找有没有自定义的。结果发现几乎网上没有很好的区域选择器的方案。我就再回过头来查阅官方文档发现还有个picker-view。 picker-view:嵌入页面的滚动选择器。官方的示例咋一看仍是时间选择器,觉得也是定死的呢。可是看代码就能够发现,其实跟iOS的写法逻辑类似。 既然类似咱们就能够着手写代码了。可是开始写以前首先咱们要拿到省市区县的数据。网上搜索下中国行政区域能够找到不少,我选了这个。下载下来是txt文件的Json数据。那怎么导入工程呢? 有两种方法: 1.在utils文件夹下新建一个js文件,写一个函数把txt里的json数据复制粘贴进去,而后在须要的类目下调用这个函数接收返回值就好了。
//area.js function getAreaInfo(callBack){ var str =["此处粘贴json数据":... ];//因数据量太大就不在此处所有展现,知道是个数组就好了。 callBack(str); } module.exports.getAreaInfo = getAreaInfo; ------------------------------ 分割线 ------------------------------ //index.js var area = require('../../utils/area.js') ... Page({ data: { }, onLoad: function (options) { var that = this; //获取省市区县数据 area.getAreaInfo(function (arr) { }); } }) ...
2.写一个接口调用,我本身就是写的一个PHP接口。
//php代码 $filename = "ChinaArea.txt";//网络上下载的文件(PHP或Java须要配置环境才能请求到数据)。 $json_string = file_get_contents($filename); echo print_r($json_string,true);
我的建议仍是不要把数据源直接写在项目,由于小程序包是有大小限制的如若超过是没法提交的因此建议写接口,或者拿别人现成的接口。
话很少说直接贴代码吧。(代码已作必要注释)
<!--index.wxml--> <view class="infoText">{{province}} {{city}} {{county}}</view> <view class="aaaa" > <button class="animation-button" bindtap="translate">选择城市</button> </view> <view class="animation-element-wrapper" animation="{{animation}}" style="visibility:{{show ? 'visible':'hidden'}}" bindtap="hiddenFloatView" data-id="444"> <view class="animation-element" catchtap="nono"> <text class="left-bt" catchtap="hiddenFloatView" data-id="555">取消</text> <text class="right-bt" catchtap="hiddenFloatView" data-id="666">肯定</text> <view class="line"></view> <picker-view indicator-style = "height: 50rpx;" value="{{value}}" bindchange="bindChange" catchtap="nono"> <!--省--> <picker-view-column> <view wx:for="{{provinces}}" wx:key="" > {{item.name}} </view> </picker-view-column> <!--地级市--> <picker-view-column> <view wx:for="{{citys}}" wx:key="" > {{item.name}} </view> </picker-view-column> <!--区县--> <picker-view-column> <view wx:for="{{countys}}" wx:key="" > {{item.name}} </view> </picker-view-column> </picker-view> </view> </view>
/**index.wxss**/ page{ background-color: rgba(255, 255, 255, 1); } .infoText{ margin-top: 20rpx; text-align: center; width: 100%; justify-content: center; } picker-view{ background-color: white; padding: 0; width: 100%; height: 380rpx; bottom: 0; position: fixed; } picker-view-column view{ vertical-align:middle; font-size: 28rpx; line-height: 28rpx; height: 100%; display: flex; align-items: center; justify-content: center; } /* ----------------------------------------- */ .animation-element-wrapper { display: flex; position: fixed; left: 0; top:0; height: 100%; width: 100%; background-color: rgba(0, 0, 0, 0.6); } .animation-element { display: flex; position: fixed; width: 100%; height: 470rpx; bottom: 0; background-color: rgba(255, 255, 255, 1); } .animation-button { top:20rpx; width: 290rpx; height: 100rpx; align-items:center; } text{ color: #999999; display: inline-flex; position: fixed; margin-top: 20rpx; height: 50rpx; text-align: center; line-height: 50rpx; font-size: 34rpx; font-family: Arial, Helvetica, sans-serif; } .left-bt{ left: 30rpx; } .right-bt { right: 30rpx; } .line{ display: block; position: fixed; height: 1rpx; width: 100%; margin-top: 89rpx; background-color: #eeeeee; }
//index.js //获取应用实例 var area = require('../../utils/area.js') var areaInfo = [];//全部省市区县数据 var provinces = [];//省 var citys = [];//城市 var countys = [];//区县 var index = [0, 0, 0]; var cellId; var t = 0; var show = false; var moveY = 200; Page({ data: { show: show, provinces: provinces, citys: citys, countys: countys, value: [0, 0, 0] }, //滑动事件 bindChange: function (e) { var val = e.detail.value //判断滑动的是第几个column //若省份column作了滑动则定位到地级市和区县第一位 if (index[0] != val[0]) { val[1] = 0; val[2] = 0; getCityArr(val[0], this);//获取地级市数据 getCountyInfo(val[0], val[1], this);//获取区县数据 } else { //若省份column未作滑动,地级市作了滑动则定位区县第一位 if (index[1] != val[1]) { val[2] = 0; getCountyInfo(val[0], val[1], this);//获取区县数据 } } index = val; console.log(index + " => " + val); //更新数据 this.setData({ value: [val[0], val[1], val[2]], province: provinces[val[0]].name, city: citys[val[1]].name, county: countys[val[2]].name }) }, onLoad: function (options) { cellId = options.cellId; var that = this; var date = new Date() console.log(date.getFullYear() + "年" + (date.getMonth() + 1) + "月" + date.getDate() + "日"); //获取省市区县数据 area.getAreaInfo(function (arr) { areaInfo = arr; //获取省份数据 getProvinceData(that); }); }, // ------------------- 分割线 -------------------- onReady: function () { this.animation = wx.createAnimation({ transformOrigin: "50% 50%", duration: 0, timingFunction: "ease", delay: 0 } ) this.animation.translateY(200 + 'vh').step(); this.setData({ animation: this.animation.export(), show: show }) }, //移动按钮点击事件 translate: function (e) { if (t == 0) { moveY = 0; show = false; t = 1; } else { moveY = 200; show = true; t = 0; } // this.animation.translate(arr[0], arr[1]).step(); animationEvents(this,moveY, show); }, //隐藏弹窗浮层 hiddenFloatView(e){ console.log(e); moveY = 200; show = true; t = 0; animationEvents(this,moveY, show); }, //页面滑至底部事件 onReachBottom: function () { // Do something when page reach bottom. } }) //动画事件 function animationEvents(that,moveY,show){ console.log("moveY:" + moveY + "\nshow:" + show); that.animation = wx.createAnimation({ transformOrigin: "50% 50%", duration: 400, timingFunction: "ease", delay: 0 } ) that.animation.translateY(moveY + 'vh').step() that.setData({ animation: that.animation.export(), show: show }) } // ---------------- 分割线 ---------------- //获取省份数据 function getProvinceData(that) { var s; provinces = []; var num = 0; for (var i = 0; i < areaInfo.length; i++) { s = areaInfo[i]; if (s.di == "00" && s.xian == "00") { provinces[num] = s; num++; } } that.setData({ provinces: provinces }) //初始化调一次 getCityArr(0, that); getCountyInfo(0, 0, that); that.setData({ province: "北京市", city: "市辖区", county: "东城区", }) } // 获取地级市数据 function getCityArr(count, that) { var c; citys = []; var num = 0; for (var i = 0; i < areaInfo.length; i++) { c = areaInfo[i]; if (c.xian == "00" && c.sheng == provinces[count].sheng && c.di != "00") { citys[num] = c; num++; } } if (citys.length == 0) { citys[0] = { name: '' }; } that.setData({ city: "", citys: citys, value: [count, 0, 0] }) } // 获取区县数据 function getCountyInfo(column0, column1, that) { var c; countys = []; var num = 0; for (var i = 0; i < areaInfo.length; i++) { c = areaInfo[i]; if (c.xian != "00" && c.sheng == provinces[column0].sheng && c.di == citys[column1].di) { countys[num] = c; num++; } } if(countys.length == 0){ countys[0] = {name:''}; } that.setData({ county: "", countys: countys, value: [column0, column1, 0] }) }
最终效果:
本文的难点主要集中在滑动的是哪一列、数据的处理、每次滑动每一列数据的更新数组的定位: 1.滑动第一列: 第二列和第三列位置都置零;更新数组citys和countys。 2.滑动第二列: 第一列不动,第三列置零;更新数组countys。 3.滑动第三列: 第一列和第二列都不动;数据不用更新,改变val[2]便可。 。 处理很差的话体验会很很差,会有闪跳的感受。
项目地址:https://github.com/leesonp/littleAPP.git
这是我第一次写文章,写的很差或者有纰漏的地方,但愿你们多多包容、指正,谢谢。