uni-app开发备忘录1(持续更新)
果然找到了以上配置,但是通过真机调试发现,这个配置只有在苹果手机上才能生效,安卓手机不生效,并且需要在APP.vue中将page的背景色设为透明。看来,通过配置文件实现这条路已经走不通了,那就只能通过代码实现了。但是遗憾的是,全局背景色只有在小程序中才生效。全端设置pages.json里pages页面的背景色。全端设置pages.json里pages页面的背景色。
·
全端设置pages.json里pages页面的背景色
第一时间想到的肯定是全局设置:
但是遗憾的是,全局背景色只有在小程序中才生效。接下来,看看能不能在页面中单独配置:
果然找到了以上配置,但是通过真机调试发现,这个配置只有在苹果手机上才能生效,安卓手机不生效,并且需要在APP.vue中将page的背景色设为透明。看来,通过配置文件实现这条路已经走不通了,那就只能通过代码实现了。以下是两种实现方式:
1.全局样式
// APP.vue
page {
background: #fff; // 窗体自定义背景色
}
2.页面窗体
// my-page.vue
<template>
<view class="my-page"></view>
</template>
<style lang="scss">
page {
background-color: #eff3f7; // 窗体自定义背景色
}
.my-page {}
</style>
内置表单组件picker
1.使用picker实现省市区级联选择
<view class="vertical-center info-item">
<text class="info-label">所在地</text>
<picker
class="flex-auto"
mode="multiSelector"
:range="regionList"
:value="regionIndexs"
range-key="name"
@change="regionChange"
@columnchange="regionColumnchange"
>
<view class="uni-flex">
<view class="flex-auto" :class="{'holder-text': !userInfo.region}">
{{ userInfo.region || '请选择' }}
</view>
<uni-icons type="forward" size="18" color="#506f8c"></uni-icons>
</view>
</picker>
</view>
import { reactive } from 'vue'
import { useStore } from 'vuex'
import provinceData from '@/static/js/area.js'
/**
* 所在地业务
*/
const store = useStore() // 该方法用于返回store实例
const userInfo = computed(() => store.state.userInfo)
const regionIndexs = reactive([0, 0, 0])
const regionList = reactive([provinceData, provinceData[0].city, provinceData[0].city[0].area]) // 当前省市区级联选项列表
// 省市区三级级联选择
const regionColumnchange = e => {
const { column, value } = e.detail
switch (column) {
case 0: // 选中省
regionList[1] = provinceData[value].city
regionList[2] = provinceData[value].city[0].area
regionIndexs[0] = value
break
case 1: // 选中市
regionList[2] = provinceData[regionIndexs[0]].city[value].area
regionIndexs[1] = value
break
case 2: // 选中区县
regionIndexs[2] = value
break
default:
break
}
}
// 选中所在地
const regionChange = e => {
const [provinceIndex, cityIndex, districtIndex] = e.detail.value
const province = provinceData[provinceIndex]
const place = province.name + (provice.city[cityIndex].name === provice.name ? '' : provice.city[cityIndex].name) + province.city[cityIndex].area[districtIndex]
request({
url: '',
method: 'POST',
data: {
place
}
}).then(({body}) => {
toast('所在地修改成功')
userInfo.value.region = place
}).catch(() => {
toast('所在地修改失败')
})
}
.vertical-center {
display: flex;
align-items: center;
}
.uni-flex {
display: flex;
}
.flex-auto {
flex: auto;
}
.info-item {
padding: 40rpx 0;
font-size: 32rpx;
box-shadow: inset 0 -1px 0 0 #ebf2fb;
.info-label {
width: 160rpx;
color: #506f8c;
}
}
.holder-text {
color: #b6c5d3;
}
// area.js
export default [{"name": "北京","city": [{"name": "北京","area": ["东城区", "西城区", "崇文区", "宣武区", "朝阳区", "丰台区", "石景山区", "海淀区", "门头沟区", "房山区", "通州区", "顺义区", "昌平区", "大兴区","平谷区","怀柔区", "密云县", "延庆县"]}]},{"name": "天津","city": [{"name": "天津","area": ["和平区", "河东区", "河西区", "南开区", "河北区", "红桥区", "塘沽区", "汉沽区", "大港区", "东丽区", "西青区", "津南区", "北辰区", "武清区","宝坻区","宁河县", "静海县", "蓟 县"]}]},{"name": "河北","city": [{"name": "石家庄","area": ["长安区", "桥东区", "桥西区", "新华区", "郊 区", "井陉矿区", "井陉县", "正定县", "栾城县", "行唐县", "灵寿县", "高邑县", "深泽县", "赞皇县","无极县","平山县", "元氏县", "赵 县", "辛集市", "藁城区", "晋州市", "新乐市", "鹿泉市"]},{"name": "唐山","area": ["路南区", "路北区", "古冶区", "开平区", "新 区", "丰润县", "滦 县", "滦南县", "乐亭县", "迁西县", "玉田县", "唐海县", "遵化市", "丰南市","迁安市"]},{"name": "秦皇岛","area": ["海港区", "山海关区", "北戴河区", "青龙满族自治县", "昌黎县", "抚宁县", "卢龙县"]},{"name": "邯郸","area": ["邯山区", "丛台区", "复兴区", "峰峰矿区", "邯郸县", "临漳县", "成安县", "大名县", "涉 县", "磁 县", "肥乡县", "永年县", "邱 县","鸡泽县","广平县", "馆陶县", "魏 县", "曲周县", "武安市"]},{"name": "邢台","area": ["桥东区", "桥西区", "邢台县", "临城县", "内丘县", "柏乡县", "隆尧县", "任 县", "南和县", "宁晋县", "巨鹿县", "新河县", "广宗县", "平乡县","威 县","清河县", "临西县", "南宫市", "沙河市"]},{"name": "保定","area": ["新市区", "北市区", "南市区", "满城县", "清苑县", "涞水县", "阜平县", "徐水县", "定兴县", "唐 县", "高阳县", "容城县", "涞源县", "望都县","安新县","易 县", "曲阳县", "蠡 县", "顺平县", "博野", "雄县", "涿州市", "定州市", "安国市", "高碑店市"]},{"name": "张家口","area": ["桥东区", "桥西区", "宣化区", "下花园区", "宣化县", "张北县", "康保县", "沽源县", "尚义县", "蔚 县", "阳原县", "怀安县", "万全县", "怀来县","涿鹿县","赤城县", "崇礼县"]},{"name": "承德","area": ["双桥区", "双滦区", "鹰手营子矿区", "承德县", "兴隆县", "平泉县", "滦平县", "隆化县", "丰宁满族自治县", "宽城满族自治县", "围场满族蒙古族自治县"]},{"name": "沧州","area": ["新华区", "运河区", "沧 县", "青 县", "东光县", "海兴县", "盐山县", "肃宁县", "南皮县", "吴桥县", "献 县", "孟村回族自治县", "泊头市","任丘市","黄骅市", "河间市"]},{"name": "廊坊","area": ["安次区", "固安县", "永清县", "香河县", "大城县", "文安县", "大厂回族自治县", "霸州市", "三河市"]},{"name": "衡水","area": ["桃城区", "枣强县", "武邑县", "武强县", "饶阳县", "安平县", "故城县", "景 县", "阜城县", "冀州市", "深州市"]}]},{"name": "山西","city": [{"name": "太原","area": ["小店区", "迎泽区", "杏花岭区", "尖草坪区", "万柏林区", "晋源区", "清徐县", "阳曲县", "娄烦县", "古交市"]},{"name": "大同","area": ["城 区", "矿 区", "南郊区", "新荣区", "阳高县", "天镇县", "广灵县", "灵丘县", "浑源县", "左云县", "大同县"]},{"name": "阳泉","area": ["城 区", "矿 区", "郊 区", "平定县", "盂 县"]},{"name": "长治","area": ["城 区", "郊 区", "长治县", "襄垣县", "屯留县", "平顺县", "黎城县", "壶关县", "长子县", "武乡县", "沁 县", "沁源县", "潞城市"]},{"name": "晋城","area": ["城 区", "沁水县", "阳城县", "陵川县", "泽州县", "高平市"]},{"name": "朔州","area": ["朔城区", "平鲁区", "山阴县", "应 县", "右玉县", "怀仁县"]},{"name": "忻州","area": ["忻府区", "原平市", "定襄县", "五台县", "代 县", "繁峙县", "宁武县", "静乐县", "神池县", "五寨县", "岢岚县", "河曲县", "保德县", "偏关县"]},{"name": "吕梁","area": ["离石区", "孝义市", "汾阳市", "文水县", "交城县", "兴 县", "临 县", "柳林县", "石楼县", "岚 县", "方山县", "中阳县", "交口县"]},{"name": "晋中","area": ["榆次市", "介休市", "榆社县", "左权县", "和顺县", "昔阳县", "寿阳县", "太谷县", "祁 县", "平遥县", "灵石县"]},{"name": "临汾","area": ["临汾市", "侯马市", "霍州市", "曲沃县", "翼城县", "襄汾县", "洪洞县", "古 县", "安泽县", "浮山县", "吉 县", "乡宁县", "蒲 县","大宁县","永和县", "隰 县", "汾西县"]},{"name": "运城","area": ["运城市", "永济市", "河津市", "芮城县", "临猗县", "万荣县", "新绛县", "稷山县", "闻喜县", "夏 县", "绛 县", "平陆县", "垣曲县"]}]},{"name": "内蒙古","city": [{"name": "呼和浩特","area": ["新城区", "回民区", "玉泉区", "郊 区", "土默特左旗", "托克托县", "和林格尔县", "清水河县", "武川县"]},{"name": "包头","area": ["东河区", "昆都伦区", "青山区", "石拐矿区", "白云矿区", "郊 区", "土默特右旗", "固阳县", "达尔罕茂明安联合旗"]},{"name": "乌海","area": ["海勃湾区", "海南区", "乌达区"]},{"name": "赤峰","area": ["红山区", "元宝山区", "松山区", "阿鲁科尔沁旗", "巴林左旗", "巴林右旗", "林西县", "克什克腾旗", "翁牛特旗", "喀喇沁旗", "宁城县", "敖汉旗"]},{"name": "呼伦贝尔","area": ["海拉尔市", "满洲里市", "扎兰屯市", "牙克石市", "根河市", "额尔古纳市", "阿荣旗", "莫力达瓦达斡尔族自治旗", "鄂伦春自治旗", "鄂温克族自治旗","新巴尔虎右旗","新巴尔虎左旗", "陈巴尔虎旗"]},{"name": "兴安盟","area": ["乌兰浩特市", "阿尔山市", "科尔沁右翼前旗", "科尔沁右翼中旗", "扎赉特旗", "突泉县"]},{"name": "通辽","area": ["科尔沁区", "霍林郭勒市", "科尔沁左翼中旗", "科尔沁左翼后旗", "开鲁县", "库伦旗", "奈曼旗", "扎鲁特旗"]},{"name": "锡林郭勒盟","area": ["二连浩特市", "锡林浩特市", "阿巴嘎旗", "苏尼特左旗", "苏尼特右旗", "东乌珠穆沁旗", "西乌珠穆沁旗", "太仆寺旗", "镶黄旗", "正镶白旗", "正蓝旗","多伦县"]},{"name": "乌兰察布盟","area": ["集宁市", "丰镇市", "卓资县", "化德县", "商都县", "兴和县", "凉城县", "察哈尔右翼前旗", "察哈尔右翼中旗", "察哈尔右翼后旗", "四子王旗"]},{"name": "伊克昭盟","area": ["东胜市", "达拉特旗", "准格尔旗", "鄂托克前旗", "鄂托克旗", "杭锦旗", "乌审旗", "伊金霍洛旗"]},{"name": "巴彦淖尔盟","area": ["临河市", "五原县", "磴口县", "乌拉特前旗", "乌拉特中旗", "乌拉特后旗", "杭锦后旗"]},{"name": "阿拉善盟","area": ["阿拉善左旗", "阿拉善右旗", "额济纳旗"]}]},{"name": "辽宁","city": [{"name": "沈阳","area": ["沈河区", "皇姑区", "和平区", "大东区", "铁西区", "苏家屯区", "东陵区", "于洪区", "新民市", "法库县", "辽中县", "康平县", "新城子区", "其他"]},{"name": "大连","area": ["西岗区", "中山区", "沙河口区", "甘井子区", "旅顺口区", "金州区", "瓦房店市", "普兰店市", "庄河市", "长海县", "其他"]},{"name": "鞍山","area": ["铁东区", "铁西区", "立山区", "千山区", "海城市", "台安县", "岫岩满族自治县", "其他"]},{"name": "抚顺","area": ["顺城区", "新抚区", "东洲区", "望花区", "抚顺县", "清原满族自治县", "新宾满族自治县", "其他"]},{"name": "本溪","area": ["平山区", "明山区", "溪湖区", "南芬区", "本溪满族自治县", "桓仁满族自治县", "其他"]},{"name": "丹东","area": ["振兴区", "元宝区", "振安区", "东港市", "凤城市", "宽甸满族自治县", "其他"]},{"name": "锦州","area": ["太和区", "古塔区", "凌河区", "凌海市", "黑山县", "义县", "北宁市", "其他"]},{"name": "营口","area": ["站前区", "西市区", "鲅鱼圈区", "老边区", "大石桥市", "盖州市", "其他"]},{"name": "阜新","area": ["海州区", "新邱区", "太平区", "清河门区", "细河区", "彰武县", "阜新蒙古族自治县", "其他"]},{"name": "辽阳","area": ["白塔区", "文圣区", "宏伟区", "太子河区", "弓长岭区", "灯塔市", "辽阳县", "其他"]},{"name": "盘锦","area": ["双台子区", "兴隆台区", "盘山县", "大洼县", "其他"]},{"name": "铁岭","area": ["银州区", "清河区", "调兵山市", "开原市", "铁岭县", "昌图县", "西丰县", "其他"]},{"name": "朝阳","area": ["双塔区", "龙城区", "凌源市", "北票市", "朝阳县", "建平县", "喀喇沁左翼蒙古族自治县", "其他"]},{"name": "葫芦岛","area": ["龙港区", "南票区", "连山区", "兴城市", "绥中县", "建昌县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "吉林","city": [{"name": "长春","area": ["朝阳区", "宽城区", "二道区", "南关区", "绿园区", "双阳区", "九台市", "榆树市", "德惠市", "农安县", "其他"]},{"name": "吉林","area": ["船营区", "昌邑区", "龙潭区", "丰满区", "舒兰市", "桦甸市", "蛟河市", "磐石市", "永吉县", "其他"]},{"name": "四平","area": ["铁西区", "铁东区", "公主岭市", "双辽市", "梨树县", "伊通满族自治县", "其他"]},{"name": "辽源","area": ["龙山区", "西安区", "东辽县", "东丰县", "其他"]},{"name": "通化","area": ["东昌区", "二道江区", "梅河口市", "集安市", "通化县", "辉南县", "柳河县", "其他"]},{"name": "白山","area": ["八道江区", "江源区", "临江市", "靖宇县", "抚松县", "长白朝鲜族自治县", "其他"]},{"name": "松原","area": ["宁江区", "乾安县", "长岭县", "扶余县", "前郭尔罗斯蒙古族自治县", "其他"]},{"name": "白城","area": ["洮北区", "大安市", "洮南市", "镇赉县", "通榆县", "其他"]},{"name": "延边朝鲜族自治州","area": ["延吉市", "图们市", "敦化市", "龙井市", "珲春市", "和龙市", "安图县", "汪清县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "黑龙江","city": [{"name": "哈尔滨","area": ["松北区", "道里区", "南岗区", "平房区", "香坊区", "道外区", "呼兰区", "阿城区", "双城市", "尚志市", "五常市", "宾县", "方正县", "通河县","巴彦县","延寿县", "木兰县", "依兰县", "其他"]},{"name": "齐齐哈尔","area": ["龙沙区", "昂昂溪区", "铁锋区", "建华区", "富拉尔基区", "碾子山区", "梅里斯达斡尔族区", "讷河市", "富裕县", "拜泉县", "甘南县", "依安县", "克山县","泰来县","克东县", "龙江县", "其他"]},{"name": "鹤岗","area": ["兴山区", "工农区", "南山区", "兴安区", "向阳区", "东山区", "萝北县", "绥滨县", "其他"]},{"name": "双鸭山","area": ["尖山区", "岭东区", "四方台区", "宝山区", "集贤县", "宝清县", "友谊县", "饶河县", "其他"]},{"name": "鸡西","area": ["鸡冠区", "恒山区", "城子河区", "滴道区", "梨树区", "麻山区", "密山市", "虎林市", "鸡东县", "其他"]},{"name": "大庆","area": ["萨尔图区", "红岗区", "龙凤区", "让胡路区", "大同区", "林甸县", "肇州县", "肇源县", "杜尔伯特蒙古族自治县", "其他"]},{"name": "伊春","area": ["伊春区", "带岭区", "南岔区", "金山屯区", "西林区", "美溪区", "乌马河区", "翠峦区", "友好区", "上甘岭区", "五营区", "红星区", "新青区","汤旺河区","乌伊岭区", "铁力市", "嘉荫县", "其他"]},{"name": "牡丹江","area": ["爱民区", "东安区", "阳明区", "西安区", "绥芬河市", "宁安市", "海林市", "穆棱市", "林口县", "东宁县", "其他"]},{"name": "佳木斯","area": ["向阳区", "前进区", "东风区", "郊区", "同江市", "富锦市", "桦川县", "抚远县", "桦南县", "汤原县", "其他"]},{"name": "七台河","area": ["桃山区", "新兴区", "茄子河区", "勃利县", "其他"]},{"name": "黑河","area": ["爱辉区", "北安市", "五大连池市", "逊克县", "嫩江县", "孙吴县", "其他"]},{"name": "绥化","area": ["北林区", "安达市", "肇东市", "海伦市", "绥棱县", "兰西县", "明水县", "青冈县", "庆安县", "望奎县", "其他"]},{"name": "大兴安岭地区","area": ["呼玛县", "塔河县", "漠河县", "大兴安岭辖区", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "上海","city": [{"name": "上海","area": ["黄浦区", "卢湾区", "徐汇区", "长宁区", "静安区", "普陀区", "闸北区", "虹口区", "杨浦区", "宝山区", "闵行区", "嘉定区", "松江区", "金山区","青浦区","南汇区", "奉贤区", "浦东新区", "崇明县", "其他"]}]},{"name": "江苏","city": [{"name": "南京","area": ["玄武区", "白下区", "秦淮区", "建邺区", "鼓楼区", "下关区", "栖霞区", "雨花台区", "浦口区", "江宁区", "六合区", "溧水县", "高淳县", "其他"]},{"name": "苏州","area": ["金阊区", "平江区", "沧浪区", "虎丘区", "吴中区", "相城区", "常熟市", "张家港市", "昆山市", "吴江市", "太仓市", "其他"]},{"name": "无锡","area": ["崇安区", "南长区", "北塘区", "滨湖区", "锡山区", "惠山区", "江阴市", "宜兴市", "其他"]},{"name": "常州","area": ["钟楼区", "天宁区", "戚墅堰区", "新北区", "武进区", "金坛市", "溧阳市", "其他"]},{"name": "镇江","area": ["京口区", "润州区", "丹徒区", "丹阳市", "扬中市", "句容市", "其他"]},{"name": "南通","area": ["崇川区", "港闸区", "通州市", "如皋市", "海门市", "启东市", "海安县", "如东县", "其他"]},{"name": "泰州","area": ["海陵区", "高港区", "姜堰市", "泰兴市", "靖江市", "兴化市", "其他"]},{"name": "扬州","area": ["广陵区", "维扬区", "邗江区", "江都市", "仪征市", "高邮市", "宝应县", "其他"]},{"name": "盐城","area": ["亭湖区", "盐都区", "大丰市", "东台市", "建湖县", "射阳县", "阜宁县", "滨海县", "响水县", "其他"]},{"name": "连云港","area": ["新浦区", "海州区", "连云区", "东海县", "灌云县", "赣榆县", "灌南县", "其他"]},{"name": "徐州","area": ["云龙区", "鼓楼区", "九里区", "泉山区", "贾汪区", "邳州市", "新沂市", "铜山县", "睢宁县", "沛县", "丰县", "其他"]},{"name": "淮安","area": ["清河区", "清浦区", "楚州区", "淮阴区", "涟水县", "洪泽县", "金湖县", "盱眙县", "其他"]},{"name": "宿迁","area": ["宿城区", "宿豫区", "沭阳县", "泗阳县", "泗洪县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "浙江","city": [{"name": "杭州","area": ["拱墅区", "西湖区", "上城区", "下城区", "江干区", "滨江区", "余杭区", "萧山区", "建德市", "富阳市", "临安市", "桐庐县", "淳安县", "其他"]},{"name": "宁波","area": ["海曙区", "江东区", "江北区", "镇海区", "北仑区", "鄞州区", "余姚市", "慈溪市", "奉化市", "宁海县", "象山县", "其他"]},{"name": "温州","area": ["鹿城区", "龙湾区", "瓯海区", "瑞安市", "乐清市", "永嘉县", "洞头县", "平阳县", "苍南县", "文成县", "泰顺县", "其他"]},{"name": "嘉兴","area": ["秀城区", "秀洲区", "海宁市", "平湖市", "桐乡市", "嘉善县", "海盐县", "其他"]},{"name": "湖州","area": ["吴兴区", "南浔区", "长兴县", "德清县", "安吉县", "其他"]},{"name": "绍兴","area": ["越城区", "诸暨市", "上虞市", "嵊州市", "绍兴县", "新昌县", "其他"]},{"name": "金华","area": ["婺城区", "金东区", "兰溪市", "义乌市", "东阳市", "永康市", "武义县", "浦江县", "磐安县", "其他"]},{"name": "衢州","area": ["柯城区", "衢江区", "江山市", "龙游县", "常山县", "开化县", "其他"]},{"name": "舟山","area": ["定海区", "普陀区", "岱山县", "嵊泗县", "其他"]},{"name": "台州","area": ["椒江区", "黄岩区", "路桥区", "临海市", "温岭市", "玉环县", "天台县", "仙居县", "三门县", "其他"]},{"name": "丽水","area": ["莲都区", "龙泉市", "缙云县", "青田县", "云和县", "遂昌县", "松阳县", "庆元县", "景宁畲族自治县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "安徽","city": [{"name": "合肥","area": ["庐阳区", "瑶海区", "蜀山区", "包河区", "长丰县", "肥东县", "肥西县", "其他"]},{"name": "芜湖","area": ["镜湖区", "弋江区", "鸠江区", "三山区", "芜湖县", "南陵县", "繁昌县", "其他"]},{"name": "蚌埠","area": ["蚌山区", "龙子湖区", "禹会区", "淮上区", "怀远县", "固镇县", "五河县", "其他"]},{"name": "淮南","area": ["田家庵区", "大通区", "谢家集区", "八公山区", "潘集区", "凤台县", "其他"]},{"name": "马鞍山","area": ["雨山区", "花山区", "金家庄区", "当涂县", "其他"]},{"name": "淮北","area": ["相山区", "杜集区", "烈山区", "濉溪县", "其他"]},{"name": "铜陵","area": ["铜官山区", "狮子山区", "郊区", "铜陵县", "其他"]},{"name": "安庆","area": ["迎江区", "大观区", "宜秀区", "桐城市", "宿松县", "枞阳县", "太湖县", "怀宁县", "岳西县", "望江县", "潜山县", "其他"]},{"name": "黄山","area": ["屯溪区", "黄山区", "徽州区", "休宁县", "歙县", "祁门县", "黟县", "其他"]},{"name": "滁州","area": ["琅琊区", "南谯区", "天长市", "明光市", "全椒县", "来安县", "定远县", "凤阳县", "其他"]},{"name": "阜阳","area": ["颍州区", "颍东区", "颍泉区", "界首市", "临泉县", "颍上县", "阜南县", "太和县", "其他"]},{"name": "宿州","area": ["埇桥区", "萧县", "泗县", "砀山县", "灵璧县", "其他"]},{"name": "巢湖","area": ["居巢区", "含山县", "无为县", "庐江县", "和县", "其他"]},{"name": "六安","area": ["金安区", "裕安区", "寿县", "霍山县", "霍邱县", "舒城县", "金寨县", "其他"]},{"name": "亳州","area": ["谯城区", "利辛县", "涡阳县", "蒙城县", "其他"]},{"name": "池州","area": ["贵池区", "东至县", "石台县", "青阳县", "其他"]},{"name": "宣城","area": ["宣州区", "宁国市", "广德县", "郎溪县", "泾县", "旌德县", "绩溪县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "福建","city": [{"name": "福州","area": ["鼓楼区", "台江区", "仓山区", "马尾区", "晋安区", "福清市", "长乐市", "闽侯县", "闽清县", "永泰县", "连江县", "罗源县", "平潭县", "其他"]},{"name": "厦门","area": ["思明区", "海沧区", "湖里区", "集美区", "同安区", "翔安区", "其他"]},{"name": "莆田","area": ["城厢区", "涵江区", "荔城区", "秀屿区", "仙游县", "其他"]},{"name": "三明","area": ["梅列区", "三元区", "永安市", "明溪县", "将乐县", "大田县", "宁化县", "建宁县", "沙县", "尤溪县", "清流县", "泰宁县", "其他"]},{"name": "泉州","area": ["鲤城区", "丰泽区", "洛江区", "泉港区", "石狮市", "晋江市", "南安市", "惠安县", "永春县", "安溪县", "德化县", "金门县", "其他"]},{"name": "漳州","area": ["芗城区", "龙文区", "龙海市", "平和县", "南靖县", "诏安县", "漳浦县", "华安县", "东山县", "长泰县", "云霄县", "其他"]},{"name": "南平","area": ["延平区", "建瓯市", "邵武市", "武夷山市", "建阳市", "松溪县", "光泽县", "顺昌县", "浦城县", "政和县", "其他"]},{"name": "龙岩","area": ["新罗区", "漳平市", "长汀县", "武平县", "上杭县", "永定县", "连城县", "其他"]},{"name": "宁德","area": ["蕉城区", "福安市", "福鼎市", "寿宁县", "霞浦县", "柘荣县", "屏南县", "古田县", "周宁县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "江西","city": [{"name": "南昌","area": ["东湖区", "西湖区", "青云谱区", "湾里区", "青山湖区", "新建县", "南昌县", "进贤县", "安义县", "其他"]},{"name": "景德镇","area": ["珠山区", "昌江区", "乐平市", "浮梁县", "其他"]},{"name": "萍乡","area": ["安源区", "湘东区", "莲花县", "上栗县", "芦溪县", "其他"]},{"name": "九江","area": ["浔阳区", "庐山区", "瑞昌市", "九江县", "星子县", "武宁县", "彭泽县", "永修县", "修水县", "湖口县", "德安县", "都昌县", "其他"]},{"name": "新余","area": ["渝水区", "分宜县", "其他"]},{"name": "鹰潭","area": ["月湖区", "贵溪市", "余江县", "其他"]},{"name": "赣州","area": ["章贡区", "瑞金市", "南康市", "石城县", "安远县", "赣县", "宁都县", "寻乌县", "兴国县", "定南县", "上犹县", "于都县", "龙南县", "崇义县","信丰县","全南县", "大余县", "会昌县", "其他"]},{"name": "吉安","area": ["吉州区", "青原区", "井冈山市", "吉安县", "永丰县", "永新县", "新干县", "泰和县", "峡江县", "遂川县", "安福县", "吉水县", "万安县", "其他"]},{"name": "宜春","area": ["袁州区", "丰城市", "樟树市", "高安市", "铜鼓县", "靖安县", "宜丰县", "奉新县", "万载县", "上高县", "其他"]},{"name": "抚州","area": ["临川区", "南丰县", "乐安县", "金溪县", "南城县", "东乡县", "资溪县", "宜黄县", "广昌县", "黎川县", "崇仁县", "其他"]},{"name": "上饶","area": ["信州区", "德兴市", "上饶县", "广丰县", "鄱阳县", "婺源县", "铅山县", "余干县", "横峰县", "弋阳县", "玉山县", "万年县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "山东","city": [{"name": "济南","area": ["市中区", "历下区", "天桥区", "槐荫区", "历城区", "长清区", "章丘市", "平阴县", "济阳县", "商河县", "其他"]},{"name": "青岛","area": ["市南区", "市北区", "城阳区", "四方区", "李沧区", "黄岛区", "崂山区", "胶南市", "胶州市", "平度市", "莱西市", "即墨市", "其他"]},{"name": "淄博","area": ["张店区", "临淄区", "淄川区", "博山区", "周村区", "桓台县", "高青县", "沂源县", "其他"]},{"name": "枣庄","area": ["市中区", "山亭区", "峄城区", "台儿庄区", "薛城区", "滕州市", "其他"]},{"name": "东营","area": ["东营区", "河口区", "垦利县", "广饶县", "利津县", "其他"]},{"name": "烟台","area": ["芝罘区", "福山区", "牟平区", "莱山区", "龙口市", "莱阳市", "莱州市", "招远市", "蓬莱市", "栖霞市", "海阳市", "长岛县", "其他"]},{"name": "潍坊","area": ["潍城区", "寒亭区", "坊子区", "奎文区", "青州市", "诸城市", "寿光市", "安丘市", "高密市", "昌邑市", "昌乐县", "临朐县", "其他"]},{"name": "济宁","area": ["市中区", "任城区", "曲阜市", "兖州市", "邹城市", "鱼台县", "金乡县", "嘉祥县", "微山县", "汶上县", "泗水县", "梁山县", "其他"]},{"name": "泰安","area": ["泰山区", "岱岳区", "新泰市", "肥城市", "宁阳县", "东平县", "其他"]},{"name": "威海","area": ["环翠区", "乳山市", "文登市", "荣成市", "其他"]},{"name": "日照","area": ["东港区", "岚山区", "五莲县", "莒县", "其他"]},{"name": "莱芜","area": ["莱城区", "钢城区", "其他"]},{"name": "临沂","area": ["兰山区", "罗庄区", "河东区", "沂南县", "郯城县", "沂水县", "苍山县", "费县", "平邑县", "莒南县", "蒙阴县", "临沭县", "其他"]},{"name": "德州","area": ["德城区", "乐陵市", "禹城市", "陵县", "宁津县", "齐河县", "武城县", "庆云县", "平原县", "夏津县", "临邑县", "其他"]},{"name": "聊城","area": ["东昌府区", "临清市", "高唐县", "阳谷县", "茌平县", "莘县", "东阿县", "冠县", "其他"]},{"name": "滨州","area": ["滨城区", "邹平县", "沾化县", "惠民县", "博兴县", "阳信县", "无棣县", "其他"]},{"name": "菏泽","area": ["牡丹区", "鄄城县", "单县", "郓城县", "曹县", "定陶县", "巨野县", "东明县", "成武县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "河南","city": [{"name": "郑州","area": ["中原区", "金水区", "二七区", "管城回族区", "上街区", "惠济区", "巩义市", "新郑市", "新密市", "登封市", "荥阳市", "中牟县", "其他"]},{"name": "开封","area": ["鼓楼区", "龙亭区", "顺河回族区", "禹王台区", "金明区", "开封县", "尉氏县", "兰考县", "杞县", "通许县", "其他"]},{"name": "洛阳","area": ["西工区", "老城区", "涧西区", "瀍河回族区", "洛龙区", "吉利区", "偃师市", "孟津县", "汝阳县", "伊川县", "洛宁县", "嵩县", "宜阳县", "新安县","栾川县","其他"]},{"name": "平顶山","area": ["新华区", "卫东区", "湛河区", "石龙区", "汝州市", "舞钢市", "宝丰县", "叶县", "郏县", "鲁山县", "其他"]},{"name": "安阳","area": ["北关区", "文峰区", "殷都区", "龙安区", "林州市", "安阳县", "滑县", "内黄县", "汤阴县", "其他"]},{"name": "鹤壁","area": ["淇滨区", "山城区", "鹤山区", "浚县", "淇县", "其他"]},{"name": "新乡","area": ["卫滨区", "红旗区", "凤泉区", "牧野区", "卫辉市", "辉县市", "新乡县", "获嘉县", "原阳县", "长垣县", "封丘县", "延津县", "其他"]},{"name": "焦作","area": ["解放区", "中站区", "马村区", "山阳区", "沁阳市", "孟州市", "修武县", "温县", "武陟县", "博爱县", "其他"]},{"name": "濮阳","area": ["华龙区", "濮阳县", "南乐县", "台前县", "清丰县", "范县", "其他"]},{"name": "许昌","area": ["魏都区", "禹州市", "长葛市", "许昌县", "鄢陵县", "襄城县", "其他"]},{"name": "漯河","area": ["源汇区", "郾城区", "召陵区", "临颍县", "舞阳县", "其他"]},{"name": "三门峡","area": ["湖滨区", "义马市", "灵宝市", "渑池县", "卢氏县", "陕县", "其他"]},{"name": "南阳","area": ["卧龙区", "宛城区", "邓州市", "桐柏县", "方城县", "淅川县", "镇平县", "唐河县", "南召县", "内乡县", "新野县", "社旗县", "西峡县", "其他"]},{"name": "商丘","area": ["梁园区", "睢阳区", "永城市", "宁陵县", "虞城县", "民权县", "夏邑县", "柘城县", "睢县", "其他"]},{"name": "信阳","area": ["浉河区", "平桥区", "潢川县", "淮滨县", "息县", "新县", "商城县", "固始县", "罗山县", "光山县", "其他"]},{"name": "周口","area": ["川汇区", "项城市", "商水县", "淮阳县", "太康县", "鹿邑县", "西华县", "扶沟县", "沈丘县", "郸城县", "其他"]},{"name": "驻马店","area": ["驿城区", "确山县", "新蔡县", "上蔡县", "西平县", "泌阳县", "平舆县", "汝南县", "遂平县", "正阳县", "其他"]},{"name": "焦作","area": ["济源市", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "湖北","city": [{"name": "武汉","area": ["江岸区", "武昌区", "江汉区", "硚口区", "汉阳区", "青山区", "洪山区", "东西湖区", "汉南区", "蔡甸区", "江夏区", "黄陂区", "新洲区", "其他"]},{"name": "黄石","area": ["黄石港区", "西塞山区", "下陆区", "铁山区", "大冶市", "阳新县", "其他"]},{"name": "十堰","area": ["张湾区", "茅箭区", "丹江口市", "郧县", "竹山县", "房县", "郧西县", "竹溪县", "其他"]},{"name": "荆州","area": ["沙市区", "荆州区", "洪湖市", "石首市", "松滋市", "监利县", "公安县", "江陵县", "其他"]},{"name": "宜昌","area": ["西陵区", "伍家岗区", "点军区", "猇亭区", "夷陵区", "宜都市", "当阳市", "枝江市", "秭归县", "远安县", "兴山县", "五峰土家族自治县","长阳土家族自治县","其他"]},{"name": "襄樊","area": ["襄城区", "樊城区", "襄阳区", "老河口市", "枣阳市", "宜城市", "南漳县", "谷城县", "保康县", "其他"]},{"name": "鄂州","area": ["鄂城区", "华容区", "梁子湖区", "其他"]},{"name": "荆门","area": ["东宝区", "掇刀区", "钟祥市", "京山县", "沙洋县", "其他"]},{"name": "孝感","area": ["孝南区", "应城市", "安陆市", "汉川市", "云梦县", "大悟县", "孝昌县", "其他"]},{"name": "黄冈","area": ["黄州区", "麻城市", "武穴市", "红安县", "罗田县", "浠水县", "蕲春县", "黄梅县", "英山县", "团风县", "其他"]},{"name": "咸宁","area": ["咸安区", "赤壁市", "嘉鱼县", "通山县", "崇阳县", "通城县", "其他"]},{"name": "随州","area": ["曾都区", "广水市", "其他"]},{"name": "恩施土家族苗族自治州","area": ["恩施市", "利川市", "建始县", "来凤县", "巴东县", "鹤峰县", "宣恩县", "咸丰县", "其他"]},{"name": "仙桃","area": ["仙桃"]},{"name": "天门","area": ["天门"]},{"name": "潜江","area": ["潜江"]},{"name": "神农架林区","area": ["神农架林区"]},{"name": "其他","area": ["其他"]}]},{"name": "湖南","city": [{"name": "长沙","area": ["岳麓区", "芙蓉区", "天心区", "开福区", "雨花区", "浏阳市", "长沙县", "望城县", "宁乡县", "其他"]},{"name": "株洲","area": ["天元区", "荷塘区", "芦淞区", "石峰区", "醴陵市", "株洲县", "炎陵县", "茶陵县", "攸县", "其他"]},{"name": "湘潭","area": ["岳塘区", "雨湖区", "湘乡市", "韶山市", "湘潭县", "其他"]},{"name": "衡阳","area": ["雁峰区", "珠晖区", "石鼓区", "蒸湘区", "南岳区", "耒阳市", "常宁市", "衡阳县", "衡东县", "衡山县", "衡南县", "祁东县", "其他"]},{"name": "邵阳","area": ["双清区", "大祥区", "北塔区", "武冈市", "邵东县", "洞口县", "新邵县", "绥宁县", "新宁县", "邵阳县", "隆回县", "城步苗族自治县", "其他"]},{"name": "岳阳","area": ["岳阳楼区", "云溪区", "君山区", "临湘市", "汨罗市", "岳阳县", "湘阴县", "平江县", "华容县", "其他"]},{"name": "常德","area": ["武陵区", "鼎城区", "津市市", "澧县", "临澧县", "桃源县", "汉寿县", "安乡县", "石门县", "其他"]},{"name": "张家界","area": ["永定区", "武陵源区", "慈利县", "桑植县", "其他"]},{"name": "益阳","area": ["赫山区", "资阳区", "沅江市", "桃江县", "南县", "安化县", "其他"]},{"name": "郴州","area": ["北湖区", "苏仙区", "资兴市", "宜章县", "汝城县", "安仁县", "嘉禾县", "临武县", "桂东县", "永兴县", "桂阳县", "其他"]},{"name": "永州","area": ["冷水滩区", "零陵区", "祁阳县", "蓝山县", "宁远县", "新田县", "东安县", "江永县", "道县", "双牌县", "江华瑶族自治县", "其他"]},{"name": "怀化","area": ["鹤城区", "洪江市", "会同县", "沅陵县", "辰溪县", "溆浦县", "中方县", "新晃侗族自治县", "芷江侗族自治县", "通道侗族自治县", "靖州苗族侗族自治县","麻阳苗族自治县","其他"]},{"name": "娄底","area": ["娄星区", "冷水江市", "涟源市", "新化县", "双峰县", "其他"]},{"name": "湘西土家族苗族自治州","area": ["吉首市", "古丈县", "龙山县", "永顺县", "凤凰县", "泸溪县", "保靖县", "花垣县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "广东","city": [{"name": "广州","area": ["越秀区", "荔湾区", "海珠区", "天河区", "白云区", "黄埔区", "番禺区", "花都区", "南沙区", "萝岗区", "增城市", "从化市", "其他"]},{"name": "深圳","area": ["福田区", "罗湖区", "南山区", "宝安区", "龙岗区", "盐田区", "其他"]},{"name": "东莞","area": ["莞城", "常平", "塘厦", "塘厦", "塘厦", "其他"]},{"name": "中山","area": ["中山"]},{"name": "潮州","area": ["湘桥区", "潮安县", "饶平县", "其他"]},{"name": "揭阳","area": ["榕城区", "揭东县", "揭西县", "惠来县", "普宁市", "其他"]},{"name": "云浮","area": ["云城区", "新兴县", "郁南县", "云安县", "罗定市", "其他"]},{"name": "珠海","area": ["香洲区", "斗门区", "金湾区", "其他"]},{"name": "汕头","area": ["金平区", "濠江区", "龙湖区", "潮阳区", "潮南区", "澄海区", "南澳县", "其他"]},{"name": "韶关","area": ["浈江区", "武江区", "曲江区", "乐昌市", "南雄市", "始兴县", "仁化县", "翁源县", "新丰县", "乳源瑶族自治县", "其他"]},{"name": "佛山","area": ["禅城区", "南海区", "顺德区", "三水区", "高明区", "其他"]},{"name": "江门","area": ["蓬江区", "江海区", "新会区", "恩平市", "台山市", "开平市", "鹤山市", "其他"]},{"name": "湛江","area": ["赤坎区", "霞山区", "坡头区", "麻章区", "吴川市", "廉江市", "雷州市", "遂溪县", "徐闻县", "其他"]},{"name": "茂名","area": ["茂南区", "茂港区", "化州市", "信宜市", "高州市", "电白县", "其他"]},{"name": "肇庆","area": ["端州区", "鼎湖区", "高要市", "四会市", "广宁县", "怀集县", "封开县", "德庆县", "其他"]},{"name": "惠州","area": ["惠城区", "惠阳区", "博罗县", "惠东县", "龙门县", "其他"]},{"name": "梅州","area": ["梅江区", "兴宁市", "梅县", "大埔县", "丰顺县", "五华县", "平远县", "蕉岭县", "其他"]},{"name": "汕尾","area": ["城区", "陆丰市", "海丰县", "陆河县", "其他"]},{"name": "河源","area": ["源城区", "紫金县", "龙川县", "连平县", "和平县", "东源县", "其他"]},{"name": "阳江","area": ["江城区", "阳春市", "阳西县", "阳东县", "其他"]},{"name": "清远","area": ["清城区", "英德市", "连州市", "佛冈县", "阳山县", "清新县", "连山壮族瑶族自治县", "连南瑶族自治县", "其他"]}]},{"name": "广西","city": [{"name": "南宁","area": ["青秀区", "兴宁区", "西乡塘区", "良庆区", "江南区", "邕宁区", "武鸣县", "隆安县", "马山县", "上林县", "宾阳县", "横县", "其他"]},{"name": "柳州","area": ["城中区", "鱼峰区", "柳北区", "柳南区", "柳江县", "柳城县", "鹿寨县", "融安县", "融水苗族自治县", "三江侗族自治县", "其他"]},{"name": "桂林","area": ["象山区", "秀峰区", "叠彩区", "七星区", "雁山区", "阳朔县", "临桂县", "灵川县", "全州县", "平乐县", "兴安县", "灌阳县", "荔浦县", "资源县","永福县","龙胜各族自治县", "恭城瑶族自治县", "其他"]},{"name": "梧州","area": ["万秀区", "蝶山区", "长洲区", "岑溪市", "苍梧县", "藤县", "蒙山县", "其他"]},{"name": "北海","area": ["海城区", "银海区", "铁山港区", "合浦县", "其他"]},{"name": "防城港","area": ["港口区", "防城区", "东兴市", "上思县", "其他"]},{"name": "钦州","area": ["钦南区", "钦北区", "灵山县", "浦北县", "其他"]},{"name": "贵港","area": ["港北区", "港南区", "覃塘区", "桂平市", "平南县", "其他"]},{"name": "玉林","area": ["玉州区", "北流市", "容县", "陆川县", "博白县", "兴业县", "其他"]},{"name": "百色","area": ["右江区", "凌云县", "平果县", "西林县", "乐业县", "德保县", "田林县", "田阳县", "靖西县", "田东县", "那坡县", "隆林各族自治县", "其他"]},{"name": "贺州","area": ["八步区", "钟山县", "昭平县", "富川瑶族自治县", "其他"]},{"name": "河池","area": ["金城江区", "宜州市", "天峨县", "凤山县", "南丹县", "东兰县", "都安瑶族自治县", "罗城仫佬族自治县", "巴马瑶族自治县", "环江毛南族自治县", "大化瑶族自治县","其他"]},{"name": "来宾","area": ["兴宾区", "合山市", "象州县", "武宣县", "忻城县", "金秀瑶族自治县", "其他"]},{"name": "崇左","area": ["江州区", "凭祥市", "宁明县", "扶绥县", "龙州县", "大新县", "天等县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "海南","city": [{"name": "海口","area": ["龙华区", "秀英区", "琼山区", "美兰区", "其他"]},{"name": "三亚","area": ["三亚市", "其他"]},{"name": "五指山","area": ["五指山"]},{"name": "琼海","area": ["琼海"]},{"name": "儋州","area": ["儋州"]},{"name": "文昌","area": ["文昌"]},{"name": "万宁","area": ["万宁"]},{"name": "东方","area": ["东方"]},{"name": "澄迈县","area": ["澄迈县"]},{"name": "定安县","area": ["定安县"]},{"name": "屯昌县","area": ["屯昌县"]},{"name": "临高县","area": ["临高县"]},{"name": "白沙黎族自治县","area": ["白沙黎族自治县"]},{"name": "昌江黎族自治县","area": ["昌江黎族自治县"]},{"name": "乐东黎族自治县","area": ["乐东黎族自治县"]},{"name": "陵水黎族自治县","area": ["陵水黎族自治县"]},{"name": "保亭黎族苗族自治县","area": ["保亭黎族苗族自治县"]},{"name": "琼中黎族苗族自治县","area": ["琼中黎族苗族自治县"]},{"name": "其他","area": ["其他"]}]},{"name": "重庆","city": [{"name": "重庆","area": ["渝中区", "大渡口区", "江北区", "南岸区", "北碚区", "渝北区", "巴南区", "长寿区", "双桥区", "沙坪坝区", "万盛区", "万州区", "涪陵区", "黔江区","永川区","合川区", "江津区", "九龙坡区", "南川区", "綦江县", "潼南县", "荣昌县", "璧山县", "大足县", "铜梁县", "梁平县", "开县", "忠县", "城口县", "垫江县","武隆县","丰都县", "奉节县", "云阳县", "巫溪县", "巫山县", "石柱土家族自治县", "秀山土家族苗族自治县", "酉阳土家族苗族自治县", "彭水苗族土家族自治县", "其他"]}]},{"name": "四川","city": [{"name": "成都","area": ["青羊区", "锦江区", "金牛区", "武侯区", "成华区", "龙泉驿区", "青白江区", "新都区", "温江区", "都江堰市", "彭州市", "邛崃市", "崇州市","金堂县","郫县","新津县", "双流县", "蒲江县", "大邑县", "其他"]},{"name": "自贡","area": ["大安区", "自流井区", "贡井区", "沿滩区", "荣县", "富顺县", "其他"]},{"name": "攀枝花","area": ["仁和区", "米易县", "盐边县", "东区", "西区", "其他"]},{"name": "泸州","area": ["江阳区", "纳溪区", "龙马潭区", "泸县", "合江县", "叙永县", "古蔺县", "其他"]},{"name": "德阳","area": ["旌阳区", "广汉市", "什邡市", "绵竹市", "罗江县", "中江县", "其他"]},{"name": "绵阳","area": ["涪城区", "游仙区", "江油市", "盐亭县", "三台县", "平武县", "安县", "梓潼县", "北川羌族自治县", "其他"]},{"name": "广元","area": ["元坝区", "朝天区", "青川县", "旺苍县", "剑阁县", "苍溪县", "市中区", "其他"]},{"name": "遂宁","area": ["船山区", "安居区", "射洪县", "蓬溪县", "大英县", "其他"]},{"name": "内江","area": ["市中区", "东兴区", "资中县", "隆昌县", "威远县", "其他"]},{"name": "乐山","area": ["市中区", "五通桥区", "沙湾区", "金口河区", "峨眉山市", "夹江县", "井研县", "犍为县", "沐川县", "马边彝族自治县", "峨边彝族自治县", "其他"]},{"name": "南充","area": ["顺庆区", "高坪区", "嘉陵区", "阆中市", "营山县", "蓬安县", "仪陇县", "南部县", "西充县", "其他"]},{"name": "眉山","area": ["东坡区", "仁寿县", "彭山县", "洪雅县", "丹棱县", "青神县", "其他"]},{"name": "宜宾","area": ["翠屏区", "宜宾县", "兴文县", "南溪县", "珙县", "长宁县", "高县", "江安县", "筠连县", "屏山县", "其他"]},{"name": "广安","area": ["广安区", "华蓥市", "岳池县", "邻水县", "武胜县", "其他"]},{"name": "达州","area": ["通川区", "万源市", "达县", "渠县", "宣汉县", "开江县", "大竹县", "其他"]},{"name": "雅安","area": ["雨城区", "芦山县", "石棉县", "名山县", "天全县", "荥经县", "宝兴县", "汉源县", "其他"]},{"name": "巴中","area": ["巴州区", "南江县", "平昌县", "通江县", "其他"]},{"name": "资阳","area": ["雁江区", "简阳市", "安岳县", "乐至县", "其他"]},{"name": "阿坝藏族羌族自治州","area": ["马尔康县", "九寨沟县", "红原县", "汶川县", "阿坝县", "理县", "若尔盖县", "小金县", "黑水县", "金川县", "松潘县", "壤塘县", "茂县", "其他"]},{"name": "甘孜藏族自治州","area": ["康定县", "丹巴县", "炉霍县", "九龙县", "甘孜县", "雅江县", "新龙县", "道孚县", "白玉县", "理塘县", "德格县", "乡城县", "石渠县", "稻城县","色达县","巴塘县", "泸定县", "得荣县", "其他"]},{"name": "凉山彝族自治州","area": ["西昌市", "美姑县", "昭觉县", "金阳县", "甘洛县", "布拖县", "雷波县", "普格县", "宁南县", "喜德县", "会东县", "越西县", "会理县", "盐源县","德昌县","冕宁县", "木里藏族自治县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "贵州","city": [{"name": "贵阳","area": ["南明区", "云岩区", "花溪区", "乌当区", "白云区", "小河区", "清镇市", "开阳县", "修文县", "息烽县", "其他"]},{"name": "六盘水","area": ["钟山区", "水城县", "盘县", "六枝特区", "其他"]},{"name": "遵义","area": ["红花岗区", "汇川区", "赤水市", "仁怀市", "遵义县", "绥阳县", "桐梓县", "习水县", "凤冈县", "正安县", "余庆县", "湄潭县", "道真仡佬族苗族自治县","务川仡佬族苗族自治县", "其他"]},{"name": "安顺","area": ["西秀区", "普定县", "平坝县", "镇宁布依族苗族自治县", "紫云苗族布依族自治县", "关岭布依族苗族自治县", "其他"]},{"name": "铜仁地区","area": ["铜仁市", "德江县", "江口县", "思南县", "石阡县", "玉屏侗族自治县", "松桃苗族自治县", "印江土家族苗族自治县", "沿河土家族自治县", "万山特区", "其他"]},{"name": "毕节地区","area": ["毕节市", "黔西县", "大方县", "织金县", "金沙县", "赫章县", "纳雍县", "威宁彝族回族苗族自治县", "其他"]},{"name": "黔西南布依族苗族自治州","area": ["兴义市", "望谟县", "兴仁县", "普安县", "册亨县", "晴隆县", "贞丰县", "安龙县", "其他"]},{"name": "黔东南苗族侗族自治州","area": ["凯里市", "施秉县", "从江县", "锦屏县", "镇远县", "麻江县", "台江县", "天柱县", "黄平县", "榕江县", "剑河县", "三穗县", "雷山县", "黎平县","岑巩县","丹寨县", "其他"]},{"name": "黔南布依族苗族自治州","area": ["都匀市", "福泉市", "贵定县", "惠水县", "罗甸县", "瓮安县", "荔波县", "龙里县", "平塘县", "长顺县", "独山县", "三都水族自治县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "云南","city": [{"name": "昆明","area": ["盘龙区", "五华区", "官渡区", "西山区", "东川区", "安宁市", "呈贡县", "晋宁县", "富民县", "宜良县", "嵩明县", "石林彝族自治县","禄劝彝族苗族自治县","寻甸回族彝族自治县", "其他"]},{"name": "曲靖","area": ["麒麟区", "宣威市", "马龙县", "沾益县", "富源县", "罗平县", "师宗县", "陆良县", "会泽县", "其他"]},{"name": "玉溪","area": ["红塔区", "江川县", "澄江县", "通海县", "华宁县", "易门县", "峨山彝族自治县", "新平彝族傣族自治县", "元江哈尼族彝族傣族自治县", "其他"]},{"name": "保山","area": ["隆阳区", "施甸县", "腾冲县", "龙陵县", "昌宁县", "其他"]},{"name": "昭通","area": ["昭阳区", "鲁甸县", "巧家县", "盐津县", "大关县", "永善县", "绥江县", "镇雄县", "彝良县", "威信县", "水富县", "其他"]},{"name": "丽江","area": ["古城区", "永胜县", "华坪县", "玉龙纳西族自治县", "宁蒗彝族自治县", "其他"]},{"name": "普洱","area": ["思茅区", "普洱哈尼族彝族自治县", "墨江哈尼族自治县", "景东彝族自治县", "景谷傣族彝族自治县", "镇沅彝族哈尼族拉祜族自治县", "江城哈尼族彝族自治县","孟连傣族拉祜族佤族自治县","澜沧拉祜族自治县", "西盟佤族自治县", "其他"]},{"name": "临沧","area": ["临翔区", "凤庆县", "云县", "永德县", "镇康县", "双江拉祜族佤族布朗族傣族自治县", "耿马傣族佤族自治县", "沧源佤族自治县", "其他"]},{"name": "德宏傣族景颇族自治州","area": ["潞西市", "瑞丽市", "梁河县", "盈江县", "陇川县", "其他"]},{"name": "怒江傈僳族自治州","area": ["泸水县", "福贡县", "贡山独龙族怒族自治县", "兰坪白族普米族自治县", "其他"]},{"name": "迪庆藏族自治州","area": ["香格里拉县", "德钦县", "维西傈僳族自治县", "其他"]},{"name": "大理白族自治州","area": ["大理市", "祥云县", "宾川县", "弥渡县", "永平县", "云龙县", "洱源县", "剑川县", "鹤庆县", "漾濞彝族自治县", "南涧彝族自治县", "巍山彝族回族自治县","其他"]},{"name": "楚雄彝族自治州","area": ["楚雄市", "双柏县", "牟定县", "南华县", "姚安县", "大姚县", "永仁县", "元谋县", "武定县", "禄丰县", "其他"]},{"name": "红河哈尼族彝族自治州","area": ["蒙自县", "个旧市", "开远市", "绿春县", "建水县", "石屏县", "弥勒县", "泸西县", "元阳县", "红河县", "金平苗族瑶族傣族自治县", "河口瑶族自治县","屏边苗族自治县","其他"]},{"name": "文山壮族苗族自治州","area": ["文山县", "砚山县", "西畴县", "麻栗坡县", "马关县", "丘北县", "广南县", "富宁县", "其他"]},{"name": "西双版纳傣族自治州","area": ["景洪市", "勐海县", "勐腊县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "西藏","city": [{"name": "拉萨","area": ["城关区", "林周县", "当雄县", "尼木县", "曲水县", "堆龙德庆县", "达孜县", "墨竹工卡县", "其他"]},{"name": "那曲地区","area": ["那曲县", "嘉黎县", "比如县", "聂荣县", "安多县", "申扎县", "索县", "班戈县", "巴青县", "尼玛县", "其他"]},{"name": "昌都地区","area": ["昌都县", "江达县", "贡觉县", "类乌齐县", "丁青县", "察雅县", "八宿县", "左贡县", "芒康县", "洛隆县", "边坝县", "其他"]},{"name": "林芝地区","area": ["林芝县", "工布江达县", "米林县", "墨脱县", "波密县", "察隅县", "朗县", "其他"]},{"name": "山南地区","area": ["乃东县", "扎囊县", "贡嘎县", "桑日县", "琼结县", "曲松县", "措美县", "洛扎县", "加查县", "隆子县", "错那县", "浪卡子县", "其他"]},{"name": "日喀则地区","area": ["日喀则市", "南木林县", "江孜县", "定日县", "萨迦县", "拉孜县", "昂仁县", "谢通门县", "白朗县", "仁布县", "康马县", "定结县", "仲巴县","亚东县","吉隆县", "聂拉木县", "萨嘎县", "岗巴县", "其他"]},{"name": "阿里地区","area": ["噶尔县", "普兰县", "札达县", "日土县", "革吉县", "改则县", "措勤县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "陕西","city": [{"name": "西安","area": ["莲湖区", "新城区", "碑林区", "雁塔区", "灞桥区", "未央区", "阎良区", "临潼区", "长安区", "高陵县", "蓝田县", "户县", "周至县", "其他"]},{"name": "铜川","area": ["耀州区", "王益区", "印台区", "宜君县", "其他"]},{"name": "宝鸡","area": ["渭滨区", "金台区", "陈仓区", "岐山县", "凤翔县", "陇县", "太白县", "麟游县", "扶风县", "千阳县", "眉县", "凤县", "其他"]},{"name": "咸阳","area": ["秦都区", "渭城区", "杨陵区", "兴平市", "礼泉县", "泾阳县", "永寿县", "三原县", "彬县", "旬邑县", "长武县", "乾县", "武功县", "淳化县","其他"]},{"name": "渭南","area": ["临渭区", "韩城市", "华阴市", "蒲城县", "潼关县", "白水县", "澄城县", "华县", "合阳县", "富平县", "大荔县", "其他"]},{"name": "延安","area": ["宝塔区", "安塞县", "洛川县", "子长县", "黄陵县", "延川县", "富县", "延长县", "甘泉县", "宜川县", "志丹县", "黄龙县", "吴起县", "其他"]},{"name": "汉中","area": ["汉台区", "留坝县", "镇巴县", "城固县", "南郑县", "洋县", "宁强县", "佛坪县", "勉县", "西乡县", "略阳县", "其他"]},{"name": "榆林","area": ["榆阳区", "清涧县", "绥德县", "神木县", "佳县", "府谷县", "子洲县", "靖边县", "横山县", "米脂县", "吴堡县", "定边县", "其他"]},{"name": "安康","area": ["汉滨区", "紫阳县", "岚皋县", "旬阳县", "镇坪县", "平利县", "石泉县", "宁陕县", "白河县", "汉阴县", "其他"]},{"name": "商洛","area": ["商州区", "镇安县", "山阳县", "洛南县", "商南县", "丹凤县", "柞水县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "甘肃","city": [{"name": "兰州","area": ["城关区", "七里河区", "西固区", "安宁区", "红古区", "永登县", "皋兰县", "榆中县", "其他"]},{"name": "嘉峪关","area": ["嘉峪关市", "其他"]},{"name": "金昌","area": ["金川区", "永昌县", "其他"]},{"name": "白银","area": ["白银区", "平川区", "靖远县", "会宁县", "景泰县", "其他"]},{"name": "天水","area": ["清水县", "秦安县", "甘谷县", "武山县", "张家川回族自治县", "北道区", "秦城区", "其他"]},{"name": "武威","area": ["凉州区", "民勤县", "古浪县", "天祝藏族自治县", "其他"]},{"name": "酒泉","area": ["肃州区", "玉门市", "敦煌市", "金塔县", "肃北蒙古族自治县", "阿克塞哈萨克族自治县", "安西县", "其他"]},{"name": "张掖","area": ["甘州区", "民乐县", "临泽县", "高台县", "山丹县", "肃南裕固族自治县", "其他"]},{"name": "庆阳","area": ["西峰区", "庆城县", "环县", "华池县", "合水县", "正宁县", "宁县", "镇原县", "其他"]},{"name": "平凉","area": ["崆峒区", "泾川县", "灵台县", "崇信县", "华亭县", "庄浪县", "静宁县", "其他"]},{"name": "定西","area": ["安定区", "通渭县", "临洮县", "漳县", "岷县", "渭源县", "陇西县", "其他"]},{"name": "陇南","area": ["武都区", "成县", "宕昌县", "康县", "文县", "西和县", "礼县", "两当县", "徽县", "其他"]},{"name": "临夏回族自治州","area": ["临夏市", "临夏县", "康乐县", "永靖县", "广河县", "和政县", "东乡族自治县", "积石山保安族东乡族撒拉族自治县", "其他"]},{"name": "甘南藏族自治州","area": ["合作市", "临潭县", "卓尼县", "舟曲县", "迭部县", "玛曲县", "碌曲县", "夏河县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "青海","city": [{"name": "西宁","area": ["城中区", "城东区", "城西区", "城北区", "湟源县", "湟中县", "大通回族土族自治县", "其他"]},{"name": "海东地区","area": ["平安县", "乐都县", "民和回族土族自治县", "互助土族自治县", "化隆回族自治县", "循化撒拉族自治县", "其他"]},{"name": "海北藏族自治州","area": ["海晏县", "祁连县", "刚察县", "门源回族自治县", "其他"]},{"name": "海南藏族自治州","area": ["共和县", "同德县", "贵德县", "兴海县", "贵南县", "其他"]},{"name": "黄南藏族自治州","area": ["同仁县", "尖扎县", "泽库县", "河南蒙古族自治县", "其他"]},{"name": "果洛藏族自治州","area": ["玛沁县", "班玛县", "甘德县", "达日县", "久治县", "玛多县", "其他"]},{"name": "玉树藏族自治州","area": ["玉树县", "杂多县", "称多县", "治多县", "囊谦县", "曲麻莱县", "其他"]},{"name": "海西蒙古族藏族自治州","area": ["德令哈市", "格尔木市", "乌兰县", "都兰县", "天峻县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "宁夏","city": [{"name": "银川","area": ["兴庆区", "西夏区", "金凤区", "灵武市", "永宁县", "贺兰县", "其他"]},{"name": "石嘴山","area": ["大武口区", "惠农区", "平罗县", "其他"]},{"name": "吴忠","area": ["利通区", "青铜峡市", "盐池县", "同心县", "其他"]},{"name": "固原","area": ["原州区", "西吉县", "隆德县", "泾源县", "彭阳县", "其他"]},{"name": "中卫","area": ["沙坡头区", "中宁县", "海原县", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "新疆","city": [{"name": "乌鲁木齐","area": ["天山区", "沙依巴克区", "新市区", "水磨沟区", "头屯河区", "达坂城区", "东山区", "乌鲁木齐县", "其他"]},{"name": "克拉玛依","area": ["克拉玛依区", "独山子区", "白碱滩区", "乌尔禾区", "其他"]},{"name": "吐鲁番地区","area": ["吐鲁番市", "托克逊县", "鄯善县", "其他"]},{"name": "哈密地区","area": ["哈密市", "伊吾县", "巴里坤哈萨克自治县", "其他"]},{"name": "和田地区","area": ["和田市", "和田县", "洛浦县", "民丰县", "皮山县", "策勒县", "于田县", "墨玉县", "其他"]},{"name": "阿克苏地区","area": ["阿克苏市", "温宿县", "沙雅县", "拜城县", "阿瓦提县", "库车县", "柯坪县", "新和县", "乌什县", "其他"]},{"name": "喀什地区","area": ["喀什市", "巴楚县", "泽普县", "伽师县", "叶城县", "岳普湖县", "疏勒县", "麦盖提县", "英吉沙县", "莎车县", "疏附县", "塔什库尔干塔吉克自治县","其他"]},{"name": "克孜勒苏柯尔克孜自治州","area": ["阿图什市", "阿合奇县", "乌恰县", "阿克陶县", "其他"]},{"name": "巴音郭楞蒙古自治州","area": ["库尔勒市", "和静县", "尉犁县", "和硕县", "且末县", "博湖县", "轮台县", "若羌县", "焉耆回族自治县", "其他"]},{"name": "昌吉回族自治州","area": ["昌吉市", "阜康市", "奇台县", "玛纳斯县", "吉木萨尔县", "呼图壁县", "木垒哈萨克自治县", "米泉市", "其他"]},{"name": "博尔塔拉蒙古自治州","area": ["博乐市", "精河县", "温泉县", "其他"]},{"name": "石河子","area": ["石河子"]},{"name": "阿拉尔","area": ["阿拉尔"]},{"name": "图木舒克","area": ["图木舒克"]},{"name": "五家渠","area": ["五家渠"]},{"name": "伊犁哈萨克自治州","area": ["伊宁市", "奎屯市", "伊宁县", "特克斯县", "尼勒克县", "昭苏县", "新源县", "霍城县", "巩留县", "察布查尔锡伯自治县", "塔城地区", "阿勒泰地区","其他"]},{"name": "其他","area": ["其他"]}]},{"name": "台湾","city": [{"name": "台湾","area": ["台北市", "高雄市", "台北县", "桃园县", "新竹县", "苗栗县", "台中县", "彰化县", "南投县", "云林县", "嘉义县", "台南县", "高雄县", "屏东县","宜兰县","花莲县", "台东县", "澎湖县", "基隆市", "新竹市", "台中市", "嘉义市", "台南市", "其他"]},{"name": "其他","area": ["其他"]}]},{"name": "澳门","city": [{"name": "澳门","area": ["花地玛堂区", "圣安多尼堂区", "大堂区", "望德堂区", "风顺堂区", "嘉模堂区", "圣方济各堂区", "路凼", "其他"]}]},{"name": "香港","city": [{"name": "香港","area": ["中西区", "湾仔区", "东区", "南区", "深水埗区", "油尖旺区", "九龙城区", "黄大仙区", "观塘区", "北区", "大埔区", "沙田区", "西贡区", "元朗区","屯门区","荃湾区", "葵青区", "离岛区", "其他"]}]},{"name": "钓鱼岛","city": [{"name": "钓鱼岛","area": ["钓鱼岛"]}]}]
解决Vue3的H5端使用onShow加载数据报错的问题
错误信息:
Cannot destructure property 'firstElementChild' of 'rootRef.value' as it is null.
解决:
使用setTimeout延迟加载数据,代码如下:
onShow(() => {
setTimeout(() => { // 解决h5端返回首页加载关注列表报错的问题
getFollowDevices()
}, 10)
})
uni-datetime-picker
1.vue3项目中设置输入框当前值要使用:model-value,不能使用:value。
2.实现点击某日期选中一整周(需要修改组件源码)
<view class="vertical-center">
<uni-datetime-picker
:ref="getWeekPickerRef"
type="daterange"
date-separator="."
:start="min"
:end="Date.now()"
:clear-icon="false"
:border="false"
v-model="weekRange"
@click="handleClick"
@change="weekChange"
/>
<uni-icons type="bottom" size="16" color="#091622" @click="openWeekPicer"></uni-icons>
</view>
import { ref, watch } from 'vue'
import util from '@/utils/util.js'
/**
* 接收父组件传参
*/
const props = defineProps({
// 开始
modelValue: {
type: [String, Number],
default: ''
},
// 结束
end: {
type: [String, Number],
default: ''
},
// 最小日期
min: {
type: String,
default: '2019-01-01'
}
})
/**
* 按周业务
*/
const weekRange = ref([props.modelValue, props.end])
const weekPicker = ref(null)
const getWeekPickerRef = e => weekPicker.value = e
const openWeekPicer = () => weekPicker.value.show()
watch(() => [props.modelValue, props.end], () => weekRange.value = [props.modelValue, props.end])
const handleClick = date => {
if (typeof date === 'string') { // 解决点击事件重复触发的问题
const weekStart = util.getWeekFirst({format: 'yyyy-MM-dd', date: new Date(date)})
const weekEnd = util.getWeekLast({format: 'yyyy-MM-dd', date: new Date(date)})
weekRange.value = [weekStart, weekEnd]
}
}
/**
* 事件处理
*/
const emit = defineEmits(['update:modelValue', 'update:end', 'change'])
const toast = (title, duration = 1500) => {
if (!title) {
return
}
uni.showToast({
title,
icon: 'none',
duration
})
}
const weekChange = ([weekStart, weekEnd]) => {
emit('update:modelValue', weekStart)
emit('update:end', weekEnd)
emit('change', { start: weekStart, end: weekEnd })
}
// util.js
export default {
// 日期格式化
formatDate({date = new Date(), format = 'yyyy/MM/dd hh:mm:ss'} = {}) {
if (date !== 'Invalid Date') {
const o = {
'M+': date.getMonth() + 1, // month
'd+': date.getDate(), // day
'h+': date.getHours(), // hour
'm+': date.getMinutes(), // minute
's+': date.getSeconds(), // second
'q+': Math.floor((date.getMonth() + 3) / 3), // quarter
'S': date.getMilliseconds() // millisecond
}
if (/(y+)/.test(format)) {
format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
}
for (let k in o) {
if (new RegExp('(' + k + ')').test(format)) {
format = format.replace(RegExp.$1,RegExp.$1.length == 1 ? o[k] :('00' + o[k]).substr(('' + o[k]).length))
}
}
return format
}
return ''
},
// 获取指定日期所在周的周一日期
getWeekFirst({date = new Date(), format = 'yyyy/MM/dd hh:mm:ss'} = {}) {
let day = date.getDay()
if (day === 1) { // 若是周一直接返回格式化日期
return this.formatDate({date, format})
}
if (!day) {
day = 7
}
const millisecondDiff = (day - 1) * 24 * 60 * 60 * 1000 // 周一距离当前日期的毫秒数
return this.formatDate({date: new Date(date.getTime() - millisecondDiff), format})
},
// 获取指定日期所在周的周日日期
getWeekLast({date = new Date(), format = 'yyyy/MM/dd hh:mm:ss'} = {}) {
const day = date.getDay()
if (day === 7) { // 若是周日直接返回格式化日期
return this.formatDate({date, format})
}
const millisecondDiff = (7 - day) * 24 * 60 * 60 * 1000 // 周日距离当前日期的毫秒数
return this.formatDate({date: new Date(date.getTime() + millisecondDiff), format})
}
}
/* 修改组件默认样式 */
:deep(.uni-date__x-input),
:deep(.range-separator) {
height: auto;
font-size: 32rpx;
color: #091622;
line-height: 1.1;
}
:deep(.uni-date),
:deep(.uni-date__x-input) {
flex: 0 1 58%;
}
:deep(.uni-date-x) {
justify-content: flex-start;
}
:deep(.icon-calendar) {
display: none;
}
:deep(.uni-calendar-item__weeks-box .uni-calendar-item--checked) {
border: none;
background-color: #f6f7fc;
.uni-calendar-item--checked-text {
color: #333;
}
}
修改组件源码:
// uni_modules\uni-datetime-picker\components\uni-datetime-picker\calendar.vue
// 找到change函数,添加一行代码
/**
* 变化触发
*/
change() {
this.setEmit('date-click') // 添加的代码
if (!this.insert) return
this.setEmit('change')
},
<!-- uni_modules\uni-datetime-picker\components\uni-datetime-picker\uni-datetime-picker.vue -->
<!-- 找到displayRangeValue.startDate,将该行代码修改如下: -->
<view class="uni-date__x-input text-center">
{{ dateSeparator && displayRangeValue.startDate ? displayRangeValue.startDate.replace(/-/g, dateSeparator) : (displayRangeValue.startDate || startPlaceholderText) }}
</view>
<!-- 找到displayRangeValue.endDate,将该行代码修改如下: -->
<view class="uni-date__x-input text-center">
{{ dateSeparator && displayRangeValue.endDate ? displayRangeValue.endDate.replace(/-/g, dateSeparator) : (displayRangeValue.endDate || endPlaceholderText) }}
</view>
<!-- 找到ref="mobile"对应的Calendar组件,增加date-click事件监听: -->
@date-click="handleClick"
// uni_modules\uni-datetime-picker\components\uni-datetime-picker\uni-datetime-picker.vue
// props增加一个属性:
dateSeparator: {
type: String,
default: ''
},
// methods中增加一个函数:
handleClick(e) {
if (this.type === 'daterange' && e.fulldate) {
this.$emit('click', e.fulldate)
}
},
微信分享
1.实现分享位置信息到微信后,用户点击分享链接可以打开高德地图显示位置及导航的功能
<uni-popup ref="sharePopup" type="bottom">
<view class="share-popup">
<view class="both-center medium-font share-title">分享位置至</view>
<view class="uni-flex share-list">
<view class="share-list-item" v-for="item in shareList" :key="item.id" @tap="share(item.id)">
<view class="both-center list-item-icon" :style="{background: item.bgc}">
<view :class="item.prefix + ' ' + item.icon" v-if="item.prefix === 't-icon'"></view>
<uni-icons :custom-prefix="item.prefix" :type="item.icon" size="24" :color="item.color" v-else></uni-icons>
</view>
<text class="list-item-label">{{ item.name }}</text>
</view>
</view>
</view>
</uni-popup>
/* 微信分享 */
const sharePopup = ref(null)
const shareList = [
{
name: '微信好友',
id: 'WXSceneSession',
prefix: '',
icon: 'weixin',
color: '#fff',
bgc: '#50b674'
},
{
name: '朋友圈',
id: 'WXSceneTimeline',
prefix: 't-icon',
icon: 't-icon-friends',
bgc: '#fff'
}
]
// 显示分享弹窗
const handleShare = () => sharePopup.value.open()
// 分享
const share = scene => uni.share({
provider: 'weixin',
scene,
type: 0,
href: `https://uri.amap.com/marker?position=${gpsInfo.value.lngenc},${gpsInfo.value.latenc}`, // 调用高德URI API实现设备位置信息展示
title: props.data.vincode,
summary: gpsInfo.value.location,
imageUrl: vehicleImage.getVehicleImage(props.data.productname),
success: res => toast('分享成功'),
fail: err => toast('分享失败')
})
解决APP启动失败的问题
1.安卓自定义基座包真机调试启动后在启动界面停留几秒后自动退出
原因:启动图使用的图片格式或大小不符合要求。
解决:更换启动图图片,一定要是.png格式,强烈推荐使用.9.png图片(Android平台启动图使用.9.png图片 - DCloud问答),并在保证清晰度的基础上图片尽量小一些。
composable封装
1.useRequest.js 接口请求组合式函数
// 接口请求组合式函数
export default () => {
// #ifdef APP-PLUS
const interfaceUrl = 'http://xx.xx.xx.xx:8080/' // 正式服务
// #endif
// #ifdef H5
const interfaceUrl = '/' // 正式服务 // 用于本地nginx
// #endif
const uploadPath = interfaceUrl + 'upload/file'
const prefix = 'lk-'
const toast = (title, duration = 1500) => {
if (!title) {
return
}
uni.showToast({
title,
icon: 'none',
duration
})
}
const setToken = token => uni.setStorageSync(prefix + 'token', token)
const getToken = () => uni.getStorageSync(prefix + 'token')
// 清除缓存
const clearCache = () => {
uni.removeStorageSync(prefix + 'token')
uni.removeStorageSync(prefix + 'user')
}
const request = ({
url,
data = null,
method = 'GET',
loading = false,
type = false,
needToken = true,
responseType = null,
loadText = '请稍候...'
}) => {
if (loading) {
uni.showLoading({
mask: true,
title: loadText
})
}
return new Promise((resolve, reject) => uni.request({
url: url.indexOf('http') >= 0 ? url : interfaceUrl + url,
data,
header: {
'content-type': type ? 'application/x-www-form-urlencoded' : 'application/json',
token: needToken ? getToken() : '' // 使用token
},
method, // 请求方式
dataType: 'json',
responseType,
success: res => {
loading && uni.hideLoading()
const d = res.data
if (typeof d === 'boolean' || (d.errorCode == -1 && d.success) || Object.prototype.toString.call(d) === '[object ArrayBuffer]') {
resolve(d)
} else if (d.code == 401) {
reject(d)
toast(d.msg)
setTimeout(() => {
uni.navigateTo({
url: '/pages/login/login'
})
}, 500)
} else {
reject(d)
if (d.msg) {
toast(d.msg === 'Bad credentials' ? '用户名或密码错误' : d.msg, 2500)
}
}
},
fail: err => {
if (loading) {
uni.hideLoading()
toast('网络不给力,请稍后再试')
}
reject(err)
}
}))
}
return {
interfaceUrl,
uploadPath,
setToken,
getToken,
clearCache,
request,
toast
}
}
使用:
import useRequest from '@/composables/useRequest.js' // 接口请求工具
const { request, toast } = useRequest()
// 取消关注
const handleFollow = id => request({
url: 'cancelFollow',
method: 'POST',
data: {
starStatus: 0,
id
}
}).then(() => {
toast('取消关注成功')
})
2.useDict.js 字典项处理组合式函数
import { ref } from 'vue'
// 字典项处理组合式函数
export default opts => {
const {
request, // 请求函数
form = {}, // 表单对象
dicList = [] // 字典项字段列表
} = opts
const dictionary = ref({ // 字典项
role: [
{
label: '机主',
value: 0
},
{
label: '机手',
value: 1
},
{
label: '设备管理',
value: 2
}
]
})
// 获取服务器字典项数据并与本地字典项数据合并
const getRemoteDics = () => {
if (!dicList || !dicList.length) {
return
}
const len = dicList.length
const promiseList = new Array(len)
for (let i = 0; i < len; i++) {
promiseList[i] = request({
url: 'sys/dict/getDictValueByType',
data: {
type: dicList[i]
}
})
}
Promise.all(promiseList).then(resList => {
for (let i = 0; i < resList.length; i++) {
dictionary.value[dicList[i]] = []
const dicInfo = resList[i].body.list
for (let key in dicInfo) {
dictionary.value[dicList[i]].push({
label: dicInfo[key],
value: +key
})
}
}
}).catch(err => {
console.log(err)
handleError()
})
}
const handleError = () => {
for (let i = 0; i < dicList.length; i++) {
dictionary.value[dicList[i]] = []
}
}
// 根据字典的value显示label
const findByvalue = (dic, value) => {
let result = ''
if (!dic) return value
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
let index = 0
index = findArray(dic, value)
result = index !== -1 ? dic[index].label : ''
} else if (value instanceof Array) {
result = []
let index = 0
value.forEach(ele => {
index = findArray(dic, ele)
result.push(index !== -1 ? dic[index].label : '')
})
result = result.toString()
}
return result
}
// 选中字典项
const dictionaryChange = (index, formKey, dicKey = formKey) => {
if (typeof formKey === 'string') {
form[formKey] = dictionary.value[dicKey][index].value
} else {
formKey(dictionary.value[dicKey][index].value)
}
}
// 据字典的value查找对应的index
const findArray = (dic, value) => {
for (let i = 0; i < dic.length; i++) {
if (dic[i].value == value) {
return i
}
}
return -1
}
return {
dictionary,
findByvalue,
dictionaryChange,
getRemoteDics
}
}
使用:
<picker
range-key="label"
:range="dictionary[dictKey]"
@change="e => {dictionaryChange(e.detail.value, 'feedbackType', dictKey)}"
>
<view class="between-center form-item">
<view class="no-shrink item-lable">反馈类型</view>
<view class="vertical-center flex-auto" :class="{'holder-text': form.feedbackType == null}">
{{ findByvalue(dictionary[dictKey], form.feedbackType) || '请选择' }}
</view>
<uni-icons type="forward" size="20" color="#506f8c"></uni-icons>
</view>
</picker>
import useRequest from '@/composables/useRequest.js' // 接口请求工具
import useDict from '@/composables/useDict.js' // 字典项工具
/**
* 字典项业务
*/
const { request, toast } = useRequest()
const dictKey = 'feedback_type'
const { dictionary, findByvalue, dictionaryChange, getRemoteDics } = useDict({form, request, dicList: [dictKey]})
getRemoteDics()
3.useGeocoder.js 逆地理解析组合式函数
/**
* 逆地理解析组合式函数
*/
export default () => {
// 解析单条数据
const analysis = async (lng, lat) => {
if (lng > 0 && lat > 0) {
let location = ''
// #ifdef APP-PLUS
location = await reverseGeoApp(lng, lat)
// #endif
// #ifdef H5
location = await reverseGeoH5(lng, lat)
// #endif
return location
}
return ''
}
// 解析列表数据
const analysisList = async ({list, lng = 'lng', lat = 'lat', lngFun, latFun}) => {
for (let i = 0; i < list.length; i++) {
const item = list[i]
if (item.location && item.location !== '地理位置解析失败') {
continue
}
const longitude = lngFun ? +lngFun(item) : +item[lng]
const latitude = latFun ? +latFun(item) : +item[lat]
if ((!longitude || !latitude) && !item.location) {
item.location = '地理位置解析失败'
continue
}
// #ifdef APP-PLUS
item.location = await reverseGeoApp(longitude, latitude)
// #endif
// #ifdef H5
item.location = await reverseGeoH5(longitude, latitude)
// #endif
}
}
// APP-VUE逆地理解析
const reverseGeoApp = (longitude, latitude) => {
const point = new plus.maps.Point(longitude, latitude)
return new Promise(resolve => {
plus.maps.Map.reverseGeocode(point, {}, res => resolve(res.address), () => resolve('地理位置解析失败'))
})
}
// H5逆地理解析
const reverseGeoH5 = (lng, lat) => new Promise(resolve => {
uni.request({
url: 'https://restapi.amap.com/v3/geocode/regeo',
data: {
key: '高德key',
location: lng + ',' + lat
},
dataType: 'json',
method: 'GET',
success: result => {
const res = result.data;
if (res.status == 1) {
const address = res.regeocode.formatted_address
resolve(address && address.length ? address : '地理位置解析失败')
} else {
resolve('地理位置解析失败')
}
},
fail: () => resolve('地理位置解析失败')
})
})
return {
analysis,
analysisList,
reverseGeoH5
}
}
使用:
import useGeocoder from '@/composables/useGeocoder.js' // 逆地理解析工具
/* 逆地理解析 */
const { reverseGeoH5 } = useGeocoder()
const location = ref('')
reverseGeoH5(lng, lat).then(res => {
location.value = res
})
4.usePage.js 列表页面分页查询处理组合式函数
// 列表页面分页查询处理组合式函数
import { ref } from 'vue'
import { onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app'
export default opts => {
let {
url,
request,
params = {},
pageSize = 10,
loading = false,
method = 'get',
listKey = 'list', // 数据列表字段名
totalKey = 'count', // 数据总数字段名
onRefresh = true,
refreshFun, // 刷新函数,一般用于重置筛选条件
resolveResource, // 处理数据源函数
afterFun // 处理请求后的数据函数,一般用于异步数据处理
} = opts
let pageNo = 1
const list = ref([])
const status = ref('loading')
// 分页查询
const loadData = () => request({
url,
data: {
pageSize,
pageNo,
...params
},
method,
loading
}).then(({body}) => {
const res = resolveResource ? resolveResource(body) : body[listKey]
if (res.length) {
list.value = [...list.value, ...res]
if (afterFun) {
afterFun(list.value)
}
if (list.value.length >= body[totalKey]) {
status.value = 'noMore'
} else {
pageNo++
status.value = 'more'
}
} else {
status.value = 'noMore'
}
}).catch(err => {
console.error(err)
status.value = 'more'
})
// 更新查询接口
const updateUrl = newUrl => url = newUrl
const refresh = () => {
status.value = 'loading'
pageNo = 1
list.value = []
if (refreshFun) {
refreshFun()
}
loadData()
}
onPullDownRefresh(() => {
if (!onRefresh) {
return
}
refresh()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1000)
})
onReachBottom(() => {
if (status.value === 'more') {
status.value = 'loading'
loadData()
}
})
return {
loadData,
list,
refresh,
status,
updateUrl
}
}
使用:
import { onLoad } from '@dcloudio/uni-app'
import useRequest from '@/composables/useRequest.js' // 接口请求工具
import usePage from '@/composables/usePage.js' // 分页查询工具
/**
* 获取页面传参业务
*/
let lastList = [] // 上次选中的设备编号列表
let from = '' // 页面跳转标识,用于返回选中后返回上一页面的业务处理
const params = {}
onLoad(param => {
lastList = param.list || []
from = param.from
params.detailStatus = param.detailStatus
if (param.detailStatus) {
params.pageSize = 1000
} else {
params.deptId = param.deptId
}
if (param.url) {
updateUrl(param.url) // 更新查询接口
}
loadData()
})
/**
* 查询业务
*/
const { request, toast } = useRequest()
const {
loadData,
status,
list,
updateUrl
} = usePage({
url: 'getList',
request,
resolveResource: ({list}) => { // 默认选中上次选中的设备
uni.showLoading({
mask: true,
title: '请稍候...'
})
selectList.value = []
for (let i = 0; i < list.length; i++) {
if (lastList.includes(list[i].dbdVehicle.vincode)) {
selectList.value.push(list[i])
}
}
uni.hideLoading()
return list
},
params
})
5.useTabPage.js 标签栏页面业务处理组合式函数
// 标签栏页面业务处理组合式函数
import { computed, ref, reactive, nextTick } from 'vue'
import { onPullDownRefresh, onReachBottom, onPageScroll } from '@dcloudio/uni-app'
export default opts => {
const {
tabs,
loadData,
status,
isRefresh = true // 是否开启刷新
} = opts
const tabList = reactive(tabs.map(tab => {
tab.getRef = e => pageRefs.includes(e) || pageRefs.push(e)
tab.scrollTop = 0
return tab
}))
const tabName = ref(tabList[0].name)
const components = ref([tabList[0]])
const tabIndex = computed(() => {
for (let i = 0; i < tabList.length; i++) {
if (tabList[i].name === tabName.value) {
return i
}
}
return 0
})
const tabChange = tab => {
if (tab.name === tabName.value) {
return
}
tabName.value = tab.name
if (!components.value.includes(tab)) {
components.value.push(tab)
}
nextTick(() => uni.pageScrollTo({
scrollTop: tabList[tabIndex.value].scrollTop,
duration: 0
}))
}
/**
* 下拉刷新业务
*/
const pageRefs = []
const refresh = () => {
for (let i = 0; i < pageRefs.length; i++) {
if (pageRefs[i].name === tabName.value) {
if (pageRefs[i].refresh) {
pageRefs[i].refresh()
}
break
}
}
}
onPullDownRefresh(() => {
if (!isRefresh) {
return
}
refresh()
setTimeout(() => {
uni.stopPullDownRefresh()
}, 1000)
})
/**
* 开启上拉加载
*/
onReachBottom(() => {})
/**
* 页面滚动业务
*/
onPageScroll(e => tabList[tabIndex.value].scrollTop = e.scrollTop)
return {
tabList,
tabName,
components,
refresh,
tabChange
}
}
使用:
<view class="both-center tab-box">
<lk-tab-list :tab-list="tabList" :model-value="tabName" @change="({tab}) => tabChange(tab)"></lk-tab-list>
</view>
<!-- 标签页-->
<component
:ref="page.getRef"
v-for="page in components"
:key="page.name"
:is="page.component"
v-show="page.name === tabName"
/>
import { markRaw } from 'vue'
import useTabPage from '@/composables/useTabPage.js' // 标签栏页面业务处理工具
import currentAlarm from './current.vue'
import historyAlarm from './history.vue'
/**
* tab页业务
*/
const tabs = [
{
name: '当前',
component: markRaw(currentAlarm)
},
{
name: '历史',
component: markRaw(historyAlarm)
}
]
const { tabList, tabName, components, tabChange, refresh } = useTabPage({ tabs, isRefresh: false })
6.useVersion.js 版本更新业务处理
import { ref } from 'vue'
/**
* 版本更新业务处理
* @description 接收一个 opts 参数,返回列表所需数据
* @param {String} opts.updateUrl - 查询最新版本信息接口
*/
export default opts => {
const { request, toast, updateUrl } = opts
const isAndroid = plus.os.name === 'Android'
const version = ref({})
const currrentVersion = ref('')
const isLastVersion = ref(true)
// 检测新版本
const getNewVersion = showModal => request({ url: updateUrl, deviceType: isAndroid ? 1 : 2 }).then(({ body }) => {
const res = body.data
plus.runtime.getProperty(plus.runtime.appid, wgtinfo => {
const wgtVersion = wgtinfo.version
currrentVersion.value = wgtVersion
version.value = res
if (wgtVersion === res.version) {
if (latestVersionTip) {
toast('已是最新版本')
}
return
}
let hasNewVersion = false
const localVersion = wgtVersion.split('.') // 当前版本号
const serviceVersion = res.version.split('.') // 最新版本号
for (let i = 0; i < serviceVersion.length; i++) { // 比较每个版本号大小,只要不相等就一定会比较出结果
if (+serviceVersion[i] > +localVersion[i]) {
hasNewVersion = true
break
} else if (+serviceVersion[i] < +localVersion[i]) {
hasNewVersion = false
break
}
}
if (hasNewVersion) {
isLastVersion.value = false
if (!showModal) {
return
}
uni.showModal({
title: '系统检测到有新版本发布,是否更新?',
confirmText: '确定更新',
content: res.remark,
success: result => {
if (result.confirm) {
if (isAndroid) { // 安卓系统下载新版本安装包
confirmDownload(res.url)
} else { // iOS系统打开AppStore对应页面
plus.runtime.openURL(encodeURI(res.url), () => toast('自动跳转AppStore失败,请手动打开AppStore更新版本', 3000))
}
} else if (result.cancel && res.isForceUpdates == 1) { // 强制更新
if (isAndroid) {
plus.runtime.quit() // 退出应用
} else { // iOS只能通过手机物理键退出应用,无法通过代码退出应用,所以只能跳转登录页面
uni.redirectTo({
url: '/pages/login/login'
})
}
}
}
})
} else {
if (latestVersionTip) {
toast('已是最新版本')
}
}
})
})
// 版本更新
const confirmDownload = url => {
uni.showLoading({
mask: true,
title: '更新中...'
})
const dtask = plus.downloader.createDownload(url, {
method: 'GET',
filename: '_doc/update/xcmg-zhulu.apk'
}, (downloadResult, status) => {
uni.hideLoading()
if (status === 200) {
plus.runtime.install(downloadResult.filename, {
force: false
}, () => {
plus.downloader.clear() // 清除下载任务
if (downloadResult.filename.indexOf('.wgt') > 0) {
plus.runtime.restart()
} else {
plus.runtime.quit()
}
}, () => {
toast('安装失败')
plus.downloader.clear() // 清除下载任务
})
} else {
toast('下载失败')
plus.downloader.clear() // 清除下载任务
}
})
dtask.start()
}
return {
getNewVersion,
version,
currrentVersion,
isLastVersion
}
}
使用:
// #ifdef APP-PLUS
import useRequest from '@/composables/useRequest.js' // 接口请求工具
import useVersion from '@/composables/useVersion.js' // 版本更新工具
const { request, toast } = useRequest()
const { getNewVersion } = useVersion({ request, toast, updateUrl: 'APPInfo' })
getNewVersion()
// #endif
7.useImage.js 图片处理组合式函数
import { ref } from 'vue'
// #ifdef APP-PLUS
import permision from '@/utils/permission.js'
// #endif
import { pathToBase64 } from '@/js_sdk/mmmm-image-tools/index.js' // 图片路径与base64互转工具,可以在DCloud插件市场找到
/**
* 图片处理组合式函数
* defaultImg: String 默认图片路径
* limit: Number 图片数量上限
* changeFun: Function 图片选择成功后的回调函数
* crop: Object 图片裁剪参数
*/
export default opts => {
const {
defaultImg = '/static/img/error/img-default.png',
limit = 12,
changeFun,
crop
} = opts || {}
/**
* 图片加载失败业务
*/
// 图片加载失败时显示默认图片
const handleImgError = (item, key, img) => item[key] = img || defaultImg
/**
* 图片上传业务
*/
const imageList = ref([]) // 图片列表
// 从相册中选择图片或拍照并压缩后转base64
const chooseToBase64 = () => uni.chooseImage({
sizeType: ['compressed'], // original 原图,compressed 压缩图(压缩50%左右),默认二者都有
count: limit,
crop,
success: ({tempFilePaths}) => {
uni.showLoading({
mask: true,
title: '请稍候...'
})
const promiseList = []
for (let i = 0; i < tempFilePaths.length; i++) {
promiseList.push(new Promise(resolve => uni.getImageInfo({ // 获取图片的本地存储路径
src: tempFilePaths[i],
success: result => {
pathToBase64(result.path).then(base64 => {
resolve(base64)
})
}
})))
}
Promise.all(promiseList).then(resList => {
uni.hideLoading()
if (changeFun) {
changeFun(resList)
}
imageList.value = resList
}).catch(errMsg => {
uni.hideLoading()
console.error(errMsg)
})
},
fail: err => {
console.error(err)
// #ifdef APP-PLUS
if (err.code && err.code !== 0) {
checkPermission(err.code)
}
// #endif
}
})
// 检查权限,并引导开启浏览相册权限和相机
const checkPermission = async code => {
const type = code ? code - 1 : 2
let status = null
if (permision.isIOS) {
status = permision.judgeIosPermissionCamera() && permision.judgeIosPermissionPhotoLibrary()
} else {
status = await permision.requestAndroidPermission(type === 0 ? 'android.permission.CAMERA' :'android.permission.READ_EXTERNAL_STORAGE')
}
if (status === null) {
return 1;
} else if (status != 1) {
uni.showModal({
content: '当前操作需要您的授权',
confirmText: '是否去设置?',
success: res => {
if (res.confirm) {
permision.gotoAppSetting()
}
}
});
}
return status
}
return {
defaultImg,
handleImgError,
chooseToBase64,
imageList
}
}
/**
* permission.js
* 本模块封装了Android、iOS的应用权限判断、打开应用权限设置界面、以及位置系统服务是否开启
*/
let isIos
// #ifdef APP-PLUS
isIos = (plus.os.name == "iOS")
// #endif
// 判断推送权限是否开启
function judgeIosPermissionPush() {
var result = false;
var UIApplication = plus.ios.import("UIApplication");
var app = UIApplication.sharedApplication();
var enabledTypes = 0;
if (app.currentUserNotificationSettings) {
var settings = app.currentUserNotificationSettings();
enabledTypes = settings.plusGetAttribute("types");
console.log("enabledTypes1:" + enabledTypes);
if (enabledTypes == 0) {
console.log("推送权限没有开启");
} else {
result = true;
console.log("已经开启推送功能!")
}
plus.ios.deleteObject(settings);
} else {
enabledTypes = app.enabledRemoteNotificationTypes();
if (enabledTypes == 0) {
console.log("推送权限没有开启!");
} else {
result = true;
console.log("已经开启推送功能!")
}
console.log("enabledTypes2:" + enabledTypes);
}
plus.ios.deleteObject(app);
plus.ios.deleteObject(UIApplication);
return result;
}
// 判断定位权限是否开启
function judgeIosPermissionLocation() {
var result = false;
var cllocationManger = plus.ios.import("CLLocationManager");
var status = cllocationManger.authorizationStatus();
result = (status != 2)
console.log("定位权限开启:" + result);
// 以下代码判断了手机设备的定位是否关闭,推荐另行使用方法 checkSystemEnableLocation
/* var enable = cllocationManger.locationServicesEnabled();
var status = cllocationManger.authorizationStatus();
console.log("enable:" + enable);
console.log("status:" + status);
if (enable && status != 2) {
result = true;
console.log("手机定位服务已开启且已授予定位权限");
} else {
console.log("手机系统的定位没有打开或未给予定位权限");
} */
plus.ios.deleteObject(cllocationManger);
return result;
}
// 判断麦克风权限是否开启
function judgeIosPermissionRecord() {
var result = false;
var avaudiosession = plus.ios.import("AVAudioSession");
var avaudio = avaudiosession.sharedInstance();
var permissionStatus = avaudio.recordPermission();
console.log("permissionStatus:" + permissionStatus);
if (permissionStatus == 1684369017 || permissionStatus == 1970168948) {
console.log("麦克风权限没有开启");
} else {
result = true;
console.log("麦克风权限已经开启");
}
plus.ios.deleteObject(avaudiosession);
return result;
}
// 判断相机权限是否开启
function judgeIosPermissionCamera() {
var result = false;
var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
if (authStatus == 3) { // 相机权限已经开启
result = true;
}
plus.ios.deleteObject(AVCaptureDevice);
return result; // 相机权限没有开启
}
// ios判断相册权限是否开启
function judgeIosPermissionPhotoLibrary() {
var result = false;
var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
var authStatus = PHPhotoLibrary.authorizationStatus();
if (authStatus == 3) { // 相册权限已经开启
result = true;
}
plus.ios.deleteObject(PHPhotoLibrary);
return result; // 相册权限没有开启
}
// 判断通讯录权限是否开启
function judgeIosPermissionContact() {
var result = false;
var CNContactStore = plus.ios.import("CNContactStore");
var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
if (cnAuthStatus == 3) {
result = true;
console.log("通讯录权限已经开启");
} else {
console.log("通讯录权限没有开启");
}
plus.ios.deleteObject(CNContactStore);
return result;
}
// 判断日历权限是否开启
function judgeIosPermissionCalendar() {
var result = false;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
if (ekAuthStatus == 3) {
result = true;
console.log("日历权限已经开启");
} else {
console.log("日历权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
// 判断备忘录权限是否开启
function judgeIosPermissionMemo() {
var result = false;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
if (ekAuthStatus == 3) {
result = true;
console.log("备忘录权限已经开启");
} else {
console.log("备忘录权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
// Android权限查询
function requestAndroidPermission(permissionID) {
return new Promise((resolve, reject) => {
plus.android.requestPermissions(
[permissionID], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
function(resultObj) {
var result = 0;
for (var i = 0; i < resultObj.granted.length; i++) {
var grantedPermission = resultObj.granted[i];
console.log('已获取的权限:' + grantedPermission);
result = 1
}
for (var i = 0; i < resultObj.deniedPresent.length; i++) {
var deniedPresentPermission = resultObj.deniedPresent[i];
console.log('拒绝本次申请的权限:' + deniedPresentPermission);
result = 0
}
for (var i = 0; i < resultObj.deniedAlways.length; i++) {
var deniedAlwaysPermission = resultObj.deniedAlways[i];
console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
result = -1
}
resolve(result);
// 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
// if (result != 1) {
// gotoAppPermissionSetting()
// }
},
function(error) {
console.log('申请权限错误:' + error.code + " = " + error.message);
resolve({
code: error.code,
message: error.message
});
}
);
});
}
// 使用一个方法,根据参数判断权限
function judgeIosPermission(permissionID) {
if (permissionID == "location") {
return judgeIosPermissionLocation()
} else if (permissionID == "camera") {
return judgeIosPermissionCamera()
} else if (permissionID == "photoLibrary") {
return judgeIosPermissionPhotoLibrary()
} else if (permissionID == "record") {
return judgeIosPermissionRecord()
} else if (permissionID == "push") {
return judgeIosPermissionPush()
} else if (permissionID == "contact") {
return judgeIosPermissionContact()
} else if (permissionID == "calendar") {
return judgeIosPermissionCalendar()
} else if (permissionID == "memo") {
return judgeIosPermissionMemo()
}
return false;
}
// 跳转到**应用**的权限页面
function gotoAppPermissionSetting() {
if (isIos) {
var UIApplication = plus.ios.import("UIApplication");
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import("NSURL");
// var setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES");
var setting2 = NSURL2.URLWithString("app-settings:");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
} else {
// console.log(plus.device.vendor);
var Intent = plus.android.importClass("android.content.Intent");
var Settings = plus.android.importClass("android.provider.Settings");
var Uri = plus.android.importClass("android.net.Uri");
var mainActivity = plus.android.runtimeMainActivity();
var intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
intent.setData(uri);
mainActivity.startActivity(intent);
}
}
// 检查系统的设备服务是否开启
// var checkSystemEnableLocation = async function () {
function checkSystemEnableLocation() {
if (isIos) {
var result = false;
var cllocationManger = plus.ios.import("CLLocationManager");
var result = cllocationManger.locationServicesEnabled();
console.log("系统定位开启:" + result);
plus.ios.deleteObject(cllocationManger);
return result;
} else {
var context = plus.android.importClass("android.content.Context");
var locationManager = plus.android.importClass("android.location.LocationManager");
var main = plus.android.runtimeMainActivity();
var mainSvr = main.getSystemService(context.LOCATION_SERVICE);
var result = mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER);
console.log("系统定位开启:" + result);
return result
}
}
export default {
judgeIosPermission: judgeIosPermission,
requestAndroidPermission: requestAndroidPermission,
checkSystemEnableLocation: checkSystemEnableLocation,
gotoAppPermissionSetting: gotoAppPermissionSetting
}
使用:
<text class="info-label header-label">头像</text>
<image class="user-header" :src="photo || defaultImg" mode="aspectFit" @error="handleImgError" @click="chooseToBase64"></image>
import useImage from '@/composables/useImage.js' // 图片处理工具
import useRequest from '@/composables/useRequest.js' // 接口请求工具
/**
* 修改头像业务
*/
const { request, toast } = useRequest()
// 修改头像
const userHeaderChange = images => {
form.photo = images[0]
// 调用修改头像接口
request({
url,
method: 'POST',
data
}).then(({body}) => {
toast('头像修改成功')
userInfo.value.photo = images[0]
store.commit('saveUserInfo', userInfo.value) // 缓存用户信息
}).catch(() => {
toast('头像修改失败')
})
}
const { defaultImg, handleImgError, chooseToBase64 } = useImage({ limit: 1, changeFun: userHeaderChange })
顶部导航栏搜索框
// pages.json
{
"path": "pages/vehcile/vehcile",
"style": {
"navigationBarTitleText": "设备",
"enablePullDownRefresh": true,
"pullToRefresh": {
"style": "circle"
},
"app-plus": {
"bounce": "none",
"scrollIndicator": "none",
"titleNView": {
"paddingLeft": 12,
"searchInput": {
"borderRadius": "6px", // 输入框圆角
"align": "left",
"backgroundColor": "#ffffff",
"placeholder": "搜索关键字"
},
"buttons": [ // 原生标题栏按钮配置
{
"fontSrc": "/static/font/iconfont/iconfont.ttf",
"text": "\ue604", // 原生标题栏矢量图标按钮,点击事件可通过页面的 onNavigationBarButtonTap 函数进行监听
"fontSize": "24px",
"color": "#0070ff",
"width": "60px"
}
]
}
}
}
}
/**
* 搜索业务
*/
let searchKey = ''
onNavigationBarSearchInputConfirmed(({text}) => {
searchKey = text.trim()
refresh()
})
/**
* 新增业务
*/
onNavigationBarButtonTap(() => uni.navigateTo({
url: './bind/bind'
}))
// 重置筛选条件
const reset = () => {
// #ifdef APP-PLUS
const pages = getCurrentPages() // 得到所有页面对象
const page = pages[pages.length - 1] // 获取当前页面对象
const webview = page.$getAppWebview() // 获取当前页面webview对象
webview.setTitleNViewSearchInputText('') // 清空导航栏搜索框
// #endif
// #ifdef H5
document.querySelector('.uni-input-input').value = ''
// #endif
searchKey = ''
}
uni-calendar
1.使用作用域插槽展示每日的数据(需要修改组件源码)
修改源码:
<!-- uni-calendar.vue 中找到uni-calendar__weeks类名元素 -->
<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
<calendar-item class="uni-calendar-item--hook" :weeks="weeks" :calendar="calendar" :selected="selected" :lunar="lunar" @change="choiceDate">
<template #extraInfo="{info}">
<slot name="extraInfo" :info="info"></slot>
</template>
</calendar-item>
</view>
</view>
<!-- uni-calendar-item.vue 组件中搜索weeks.extraInfo.info字段,将所有包含有weeks.extraInfo.info字段的代码替换成以下代码 -->
<view
class="uni-calendar-item__weeks-lunar-text"
:class="{
'uni-calendar-item--extra':weeks.extraInfo.info,
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--before-checked':weeks.beforeMultiple,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--after-checked':weeks.afterMultiple,
'uni-calendar-item--disable':weeks.disable,
}"
v-if="weeks.extraInfo && weeks.extraInfo.info"
>
<text v-if="typeof weeks.extraInfo.info === 'string'">{{ weeks.extraInfo.info }}</text>
<slot name="extraInfo" :info="weeks.extraInfo.info"></slot>
</view>
通过uni-calendar-item__weeks-box-item类名可以设置单元格高度。
使用:
<uni-calendar insert :selected="attendanceList" :show-month="false" @monthSwitch="calendarChange">
<template #extraInfo="{info}">
<view class="is-info-bg calendar-value calendar-work-time">
<view class="calendar-value-inner">
{{ info.worktime }}H
</view>
</view>
<view class="is-warn-bg calendar-value">
<view class="calendar-value-inner">
{{ info.fuelconsum }}L
</view>
</view>
</template>
</uni-calendar>
/*
* 日历业务
*/
const attendanceList = ref([])
const thisDate = new Date()
let startDate = util.getMonthFirst(thisDate)
let endDate = util.getMonthLast(thisDate)
const calendarChange = ({year, month}) => {
const changeDate = new Date(year, month - 1, 1)
startDate = util.getMonthFirst(changeDate)
endDate = util.getMonthLast(changeDate)
loadCalendar()
}
const loadCalendar = () => {
let url = '' // 数据查询接口
let data = { // 数据查询参数
}
request({
url,
data,
method: 'get'
}).then(({body}) => {
attendanceList.value = body.data.map(item => ({
date: item.datetime,
info: {
worktime: item.worktime,
fuelconsum: item.fuelconsum
}
}))
})
}
.is-info-bg {
color: $uni-bg-color;
background: #0070ff;
}
.is-warn-bg {
color: $uni-bg-color;
background: #ff9300;
}
.calendar-value {
padding: 2px 0;
text-align: center;
.calendar-value-inner {
transform: scale(0.75);
}
}
.calendar-work-time {
margin-bottom: 8rpx;
}
:deep(.uni-calendar) {
.uni-calendar__backtoday,
.uni-calendar-item__weeks-box-circle {
display: none;
}
.uni-calendar-item__weeks-box-text {
font-weight: 600;
}
.uni-calendar-item--isDay {
background-color: transparent;
opacity: 1;
color: #0070ff;
}
.uni-calendar-item--extra {
display: flex;
flex-direction: column;
justify-content: space-around;
width: 100%;
font-size: 24rpx;
color: $uni-text-color-inverse;
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)