此组件原作链接为:https://blog.csdn.net/NAMECZ/article/details/80254178#comments_12281606
优化内容:
1:组件数据加载空白
2:组件报错:Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors.
3:组件样式调整
4:在组件的调用页面使用this.setData({"组件数据":[]})给组件赋值后组件的值不能随之动态改变
5:点击返回再次打开组件时上次勾选的数据不能重置
6:取消勾选点击返回后组件相关选项框有问题
主要优化后的组件代码如下
- js:新增clear()、loadAgin()方法,修改back()方法
Component({ properties: { list: { type: Array, value: [], }, select:{ type: Array, value: [], } }, data: { childlist: [], n: 0, checked: [], allNum: [], }, ready(){ var that=this; var list = that.data.list;//传递过来的数据 var select = that.data.select; var checked = new Array; var allNum = []; var aaa = []; // 检查默认选中状态 for (let i = 0; i < list.length; i++) { for (let k = 0; k < list[i].childlist.length; k++) { for (let j = 0; j < select.length; j++) { if (list[i].childlist[k].value == select[j]) { aaa = []; // 若某条二级数组中存在多个选中的项要做判断筛选 if (checked[i]) { // check中第i项如果存过值,那么将在此项中继续加入值 checked[i].forEach(function (item) { aaa.push(item); }) aaa.push(list[i].childlist[k]); checked[i] = aaa; } else { // check中第i项没有存过值,那么将值存入第i项 if (list[i].childlist[k].istitle == "全部") { for (let s = 0; s < list[i].childlist.length; s++) { list[i].childlist[s].checked = true allNum[i] = list[i].childlist.length - 1; checked[i] = [list[i]]; } } else { checked[i] = [list[i].childlist[k]]; } } list[i].childlist[k].checked = true; } } } } that.setData({ 'childlist[0]': list[0].childlist, list: list, checked: checked, allNum: allNum, }) }, methods: { ontap(e) { console.log(e) var that = this; var n = e.currentTarget.dataset.index; var childlist = "childlist[" + n + "]"; that.setData({ [childlist]: that.data.list[n].childlist, n: n }) }, // 清空已经选择的选项 clear(){ var afterClearList = this.data.list; for (var i = 0; i < afterClearList.length; i++) { var citylist=afterClearList[i].childlist; for(var j=0;j<citylist.length;j++){ delete citylist[j].checked; } } this.setData({ 'childlist[0]':[], checked: [], allNum: [], list:afterClearList, }) }, // 在被调用的页面的select属性重新赋值后调用这个方法刷新所选项 loadAgin(){ var a={currentTarget:{dataset:{index:0}}}; this.ontap(a); var that=this; var list = that.data.list;//传递过来的数据 var select = that.data.select; var checked = new Array; var allNum = []; var aaa = []; // 检查默认选中状态 for (let i = 0; i < list.length; i++) { for (let k = 0; k < list[i].childlist.length; k++) { for (let j = 0; j < select.length; j++) { if (list[i].childlist[k].value == select[j]) { aaa = []; // 若某条二级数组中存在多个选中的项要做判断筛选 if (checked[i]) { // check中第i项如果存过值,那么将在此项中继续加入值 checked[i].forEach(function (item) { aaa.push(item); }) aaa.push(list[i].childlist[k]); checked[i] = aaa; } else { // check中第i项没有存过值,那么将值存入第i项 if (list[i].childlist[k].istitle == "全部") { for (let s = 0; s < list[i].childlist.length; s++) { list[i].childlist[s].checked = true allNum[i] = list[i].childlist.length - 1; checked[i] = [list[i]]; } } else { checked[i] = [list[i].childlist[k]]; } } list[i].childlist[k].checked = true; } } } } that.setData({ 'childlist[0]': list[0].childlist, list: list, checked: checked, allNum: allNum, }) }, all() { var that = this; var n = that.data.n; var childlist = "childlist[" + n + "]"; var checked = "checked[" + n + "]"; var allNum = "allNum[" + n + "]"; var all = ""; var checkArr = []; var checkboxItems = that.data.childlist[n]; if (checkboxItems[0].checked) { checkboxItems[0].checked = true; checkArr = []; } else { checkboxItems[0].checked = false; // checkArr.push(checkboxItems[0]) checkArr.push(that.data.list[n]) all = checkboxItems.length - 1; } checkboxItems[0].checked = !checkboxItems[0].checked for (let k = 1; k < checkboxItems.length; k++) { checkboxItems[k].checked = checkboxItems[0].checked; } that.setData({ [childlist]: checkboxItems, [checked]: checkArr, [allNum]: all ? all : 0, }, function () { console.log(that.data.checked); }) }, checkboxChange(e) { var that = this; var n = that.data.n; var checkboxItems = that.data.childlist[n]; var values = e.detail.value; console.log("checkboxChange"); console.log(values); var flag = ""; var childlist = "childlist[" + n + "]"; var checked = "checked[" + n + "]"; var allNum = "allNum[" + n + "]"; var checkedArr = []; var all = ""; for (var i = 0, lenI = checkboxItems.length; i < lenI; ++i) { checkboxItems[i].checked = false; for (var j = 0, lenJ = values.length; j < lenJ; ++j) { if (checkboxItems[i].value == values[j]) { checkboxItems[i].checked = true; checkedArr.push(checkboxItems[i]); break; } } } if (values.length == checkboxItems.length - 1) { checkboxItems[0].checked = true; // checkedArr = [checkboxItems[0]]; checkedArr = [that.data.list[n]]; all = checkboxItems.length - 1; } this.setData({ [childlist]: checkboxItems, [checked]: checkedArr, [allNum]: all }); }, formSubmit: function (e) { var that = this; var values = that.data.checked; var arr = []; var arr1 = []; for (let i = 0; i < values.length; i++) { if (values[i] != undefined) { arr.push(values[i]); } } for (let i = 0; i < arr.length; i++) { for (let j = 0; j < arr[i].length; j++) { arr1.push(arr[i][j]) } } var detail = arr1;//选中的值 this.clear(); this.triggerEvent("formSubmit", {citys:detail}); }, back() { this.clear(); this.triggerEvent("back"); } } })
-
wxml:
<cu-custom bgColor="bg-gradual-blue"> <view slot="content">订单管理</view> </cu-custom> <form bindsubmit="formSubmit"> <view class='content'> <!-- 一级菜单 --> <scroll-view class='scrollLeft' scroll-y> <block wx:for="{ {list}}" wx:key="item"> <view class="leftBox" catchtap='ontap' data-index='{ {index}}' style='{ {n==index?"border-left:8rpx solid #1aad16;color:#1aad16":""}}'> { {item.istitle}} <view class='num' hidden="{ {checked[index].length>0?false:true}}"> <text>{ {allNum[index]?allNum[index]:(checked[index].length>0?checked[index].length:0)}}</text> </view> </view> </block> </scroll-view> <!-- 二级菜单 --> <scroll-view class='scrollRight' scroll-y> <view class="weui-cells weui-cells_after-title"> <!-- 二级菜单中的全部选项 --> <label class="weui-cell weui-check__label" catchtap='all'> <checkbox class="weui-check" value="{ {childlist[n][0].value}}" checked="{ {childlist[n][0].checked}}" /> <view class="weui-cell__hd weui-check__hd_in-checkbox"> <icon class="weui-icon-checkbox_circle" type="circle" size="23" wx:if="{ {!childlist[n][0].checked}}"></icon> <icon class="weui-icon-checkbox_success" type="success" size="23" wx:if="{ {childlist[n][0].checked}}"></icon> </view> <view class="weui-cell__bd">{ {childlist[n][0].istitle}}</view> </label> <checkbox-group bindchange="checkboxChange"> <!-- 二级菜单中的剩余选项 --> <block wx:for="{ {childlist[n]}}" wx:key="value"> <label class="weui-cell weui-check__label" wx:if='{ {item.istitle!="全部"}}'> <checkbox class="weui-check" value="{ {item.value}}" checked="{ {item.checked}}" /> <view class="weui-cell__hd weui-check__hd_in-checkbox"> <icon class="weui-icon-checkbox_circle" type="circle" size="23" wx:if="{ {!item.checked}}"></icon> <icon class="weui-icon-checkbox_success" type="success" size="23" wx:if="{ {item.checked}}"></icon> </view> <view class="weui-cell__bd">{ {item.istitle}}</view> </label> </block> </checkbox-group> </view> </scroll-view> </view> <view class="btn-area"> <button catchtap='back' class="back">返回</button> <button formType="submit" class="submit">确定</button> </view> </form>
-
wxss:
/* page{ background: #f8f8f8; } */ .content{ position: absolute; top:0; bottom:100rpx; width: 100%; } .scrollLeft{ box-sizing: border-box; float: left; width: 25%; height: 100%; border-right: 1rpx solid #ddd; font-size: 35rpx; } .scrollRight{ float: left; width: 75%; height: 100%; } .leftBox{ position: relative; box-sizing: border-box; width: 100%; height: 100rpx; display: flex; justify-content: center; align-items:center; border-bottom: 1rpx solid #ddd; } .num{ position: absolute; top:10rpx; right: 10rpx; width: 30rpx; height: 30rpx; display: flex; justify-content: center; align-items: center; background-color: #f10215; border-radius: 50%; color: white; font-size: 22rpx; } .rightBox{ box-sizing: border-box; width: 100%; } .weui-cells { position: relative; margin-top: 1.17647059em; background-color: #FFFFFF; line-height: 1.41176471; font-size: 17px; } .weui-cells_after-title { margin-top: 0; } .weui-cell { padding: 10px 15px; position: relative; display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-align: center; -webkit-align-items: center; align-items: center; } .weui-check__label:active { background-color: #ECECEC; } .weui-check { position: absolute; left: -9999px; } .weui-check__hd_in-checkbox { padding-right: 0.35em; } .weui-icon-checkbox_circle, .weui-icon-checkbox_success { margin-left: 4.6px; margin-right: 4.6px; } .weui-cell__bd { -webkit-box-flex: 1; -webkit-flex: 1; flex: 1; } .btn-area{ position: absolute; bottom: 0; width: 100%; height: 100rpx; display: flex; justify-content: space-between; align-items: center; margin-top: 20rpx; } .btn-area .back{ width: 30%; height: 80%; color: white; background-color: orange; display: flex; justify-content: center; align-items: center; } .btn-area .submit{ width: 50%; height: 80%; color: white; background-color: #1aad16; display: flex; justify-content: center; align-items: center; margin-right: 10%; }
以上是该组件的优化,以下是调用的地方的逻辑
-
新建cityjson.js中遍历全国城市,这个js太大,所以不方便放在文中,可以到我的下载中去下载,链接如下:
-
https://download.csdn.net/download/nienianzhi1744/12447981
json调用,先在页面的.json文件中调用分组组件
"usingComponents": { "check": "../components/checkGrop/checkGrop" }
-
js调用,再在页面的.js文件中调用城市数据并拼出适合组件使用的json数据的格式
const cityJson = require('../../assets/json/city.js').cityjson; Page({ data: { StatusBar: app.globalData.StatusBar, CustomBar: app.globalData.CustomBar, gridCol: 3, skin: false, cityArray: [], allCitys: [], checkedCityName: [], cityListStr: null }, // 加载城市数据 loadCityGroup: function () { var provinceList = []; var allCityList = []; for (var i = 0; i < cityJson.length; i++) { var province = cityJson[i]; var citys = province.city; var cityList = [{ istitle: "全部", value: "全部" }]; for (var j = 0; j < citys.length; j++) { var cityMap = { istitle: citys[j].city_name, value: citys[j].city_name } allCityList.push(citys[j].city_name); cityList.push(cityMap) }; var firstMap = { id: i, istitle: province.province, childlist: cityList } provinceList.push(firstMap); } this.setData({ cityArray: provinceList, allCitys: allCityList }); }, })
- wxml调用:其中cityArray是所有的城市数据,checkedCityName是加载时默认带出的选中的城市,id是属性必不可少,submmitCityConfigModal是点击提交时的方法,hideCityConfigModal是返回时的方法
<view class="padding-xl"> <check list="{ {cityArray}}" select="{ {checkedCityName}}" id="cityCheck" bind:formSubmit="submmitCityConfigModal" bindback="hideCityConfigModal"></check> </view>
以上调用完成后,开始具体的方法。
- 打开组件时:如果需要默认带出值,则需要给data中checkedCityName这个数组通过this.setData赋值,数组格式是['北京','石家庄']这种类型的。
- 赋值完成后必须写 this.selectComponent('#cityCheck').loadAgin(),才可以加载默认带出数据。cityCheck是刚才组件定义的id
- 提交时可以通过e.detail.citys来获取到本次选中了哪些城市
- 返回时清理并重置选择了但未保存的数据,这个操作已经在组件的clear()方法和back()方法中完成,无需再手动调用。
over