手动定位
在上一章节里,定位功能已经在cordova层面已经完成,接下来我们先忘记这个功能,想一下如果定位不成功怎么办? 所以最终还是需要一个手动定位的功能。
这个功能很简单,其实就是一个联动下拉列表,按照一般的情况,只需要精确到市级即可,这个库网上有现成的,作为vue的数据模型即可:
const address = {
'北京': ['北京'],
'广东': ['广州', '深圳', '珠海', '汕头', '韶关', '佛山', '江门', '湛江', '茂名', '肇庆', '惠州', '梅州', '汕尾', '河源', '阳江', '清远', '东莞', '中山', '潮州', '揭阳', '云浮'],
'上海': ['上海'],
'天津': ['天津'],
'重庆': ['重庆'],
'辽宁': ['沈阳', '大连', '鞍山', '抚顺', '本溪', '丹东', '锦州', '营口', '阜新', '辽阳', '盘锦', '铁岭', '朝阳', '葫芦岛'],
'江苏': ['南京', '苏州', '无锡', '常州', '镇江', '南通', '泰州', '扬州', '盐城', '连云港', '徐州', '淮安', '宿迁'],
'湖北': ['武汉', '黄石', '十堰', '荆州', '宜昌', '襄樊', '鄂州', '荆门', '孝感', '黄冈', '咸宁', '随州', '恩施土家族苗族自治州', '仙桃', '天门', '潜江', '神农架林区'],
'四川': ['成都', '自贡', '攀枝花', '泸州', '德阳', '绵阳', '广元', '遂宁', '内江', '乐山', '南充', '眉山', '宜宾', '广安', '达州', '雅安', '巴中', '资阳', '阿坝藏族羌族自治州', '甘孜藏族自治州', '凉山彝族自治州'],
'陕西': ['西安', '铜川', '宝鸡', '咸阳', '渭南', '延安', '汉中', '榆林', '安康', '商洛'],
'河北': ['石家庄', '唐山', '秦皇岛', '邯郸', '邢台', '保定', '张家口', '承德', '沧州', '廊坊', '衡水'],
'山西': ['太原', '大同', '阳泉', '长治', '晋城', '朔州', '晋中', '运城', '忻州', '临汾', '吕梁'],
'河南': ['郑州', '开封', '洛阳', '平顶山', '安阳', '鹤壁', '新乡', '焦作', '濮阳', '许昌', '漯河', '三门峡', '南阳', '商丘', '信阳', '周口', '驻马店'],
'吉林': ['长春', '吉林', '四平', '辽源', '通化', '白山', '松原', '白城', '延边朝鲜族自治州'],
'黑龙江': ['哈尔滨', '齐齐哈尔', '鹤岗', '双鸭山', '鸡西', '大庆', '伊春', '牡丹江', '佳木斯', '七台河', '黑河', '绥化', '大兴安岭地区'],
'内蒙古': ['呼和浩特', '包头', '乌海', '赤峰', '通辽', '鄂尔多斯', '呼伦贝尔', '巴彦淖尔', '乌兰察布', '锡林郭勒盟', '兴安盟', '阿拉善盟'],
'山东': ['济南', '青岛', '淄博', '枣庄', '东营', '烟台', '潍坊', '济宁', '泰安', '威海', '日照', '莱芜', '临沂', '德州', '聊城', '滨州', '菏泽'],
'安徽': ['合肥', '芜湖', '蚌埠', '淮南', '马鞍山', '淮北', '铜陵', '安庆', '黄山', '滁州', '阜阳', '宿州', '巢湖', '六安', '亳州', '池州', '宣城'],
'浙江': ['杭州', '宁波', '温州', '嘉兴', '湖州', '绍兴', '金华', '衢州', '舟山', '台州', '丽水'],
'福建': ['福州', '厦门', '莆田', '三明', '泉州', '漳州', '南平', '龙岩', '宁德'],
'湖南': ['长沙', '株洲', '湘潭', '衡阳', '邵阳', '岳阳', '常德', '张家界', '益阳', '郴州', '永州', '怀化', '娄底', '湘西土家族苗族自治州'],
'广西': ['南宁', '柳州', '桂林', '梧州', '北海', '防城港', '钦州', '贵港', '玉林', '百色', '贺州', '河池', '来宾', '崇左'],
'江西': ['南昌', '景德镇', '萍乡', '九江', '新余', '鹰潭', '赣州', '吉安', '宜春', '抚州', '上饶'],
'贵州': ['贵阳', '六盘水', '遵义', '安顺', '铜仁地区', '毕节地区', '黔西南布依族苗族自治州', '黔东南苗族侗族自治州', '黔南布依族苗族自治州'],
'云南': ['昆明', '曲靖', '玉溪', '保山', '昭通', '丽江', '普洱', '临沧', '德宏傣族景颇族自治州', '怒江傈僳族自治州', '迪庆藏族自治州', '大理白族自治州', '楚雄彝族自治州', '红河哈尼族彝族自治州', '文山壮族苗族自治州', '西双版纳傣族自治州'],
'西藏': ['拉萨', '那曲地区', '昌都地区', '林芝地区', '山南地区', '日喀则地区', '阿里地区'],
'海南': ['海口', '三亚', '五指山', '琼海', '儋州', '文昌', '万宁', '东方', '澄迈县', '定安县', '屯昌县', '临高县', '白沙黎族自治县', '昌江黎族自治县', '乐东黎族自治县', '陵水黎族自治县', '保亭黎族苗族自治县', '琼中黎族苗族自治县'],
'甘肃': ['兰州', '嘉峪关', '金昌', '白银', '天水', '武威', '酒泉', '张掖', '庆阳', '平凉', '定西', '陇南', '临夏回族自治州', '甘南藏族自治州'],
'宁夏': ['银川', '石嘴山', '吴忠', '固原', '中卫'],
'青海': ['西宁', '海东地区', '海北藏族自治州', '海南藏族自治州', '黄南藏族自治州', '果洛藏族自治州', '玉树藏族自治州', '海西蒙古族藏族自治州'],
'新疆': ['乌鲁木齐', '克拉玛依', '吐鲁番地区', '哈密地区', '和田地区', '阿克苏地区', '喀什地区', '克孜勒苏柯尔克孜自治州', '巴音郭楞蒙古自治州', '昌吉回族自治州', '博尔塔拉蒙古自治州', '石河子', '阿拉尔', '图木舒克', '五家渠', '伊犁哈萨克自治州'],
'香港': ['香港'],
'澳门': ['澳门'],
'台湾': ['台北市', '高雄市', '台北县', '桃园县', '新竹县', '苗栗县', '台中县', '彰化县', '南投县', '云林县', '嘉义县', '台南县', '高雄县', '屏东县', '宜兰县', '花莲县', '台东县', '澎湖县', '基隆市', '新竹市', '台中市', '嘉义市', '台南市']
}
然后增加一个图标,如果手机定位失败显示:
<mu-icon value="room" v-on:click="chooseAddress" v-if="locationBtn"/>
其中click事件点击后弹出地点选择对话框,而v-if是vue的条件选择语句,即只有locationBtn为true的时候,才会显示这个图标。
因为locationBtn是跨组件的,所以暂时把他定义在store中:
locationBtn:true
还需要定义一个选择定位地点的弹出框,同样适用museui的dialog,然后对样式进行稍微的改动:
<mu-dialog :open="adddialog" title="请选择" >
<mu-picker :slots="addressSlots" :visible-item-count="5" @change="addressChange" :values="address"/>
<mu-flat-button slot="actions" primary @click="addressClose" label="确定"/>
</mu-dialog>
很简单,只有一个picker和一个关闭按钮,这样就很清晰了,chooseAddress方法只有一行:
chooseAddress:function(event){
this.adddialog=true;
},
这时候弹框会显示,而addressChange的方法体是一个数组的联动效果,联动之后同时进行赋值:
addressChange:function(value, index) {
switch (index) {
case 0:
this.addressProvince = value
const arr = address[value]
this.addressSlots[1].values = arr
this.addressCity = arr[0]
break
case 1:
this.addressCity = value
break
}
this.address = [this.addressProvince, this.addressCity]
},
很明显,定义几个数据项还是必须的:
addressSlots: [
{
width: '100%',
textAlign: 'right',
values: Object.keys(address)
}, {
width: '100%',
textAlign: 'left',
values: ['北京']
}
],//列表
address: ['北京', '北京'],
addressProvince: '北京',
addressCity: '北京',
最终效果如下:
当选择后,会在页面中显示已经选择的地点,比如随便选择一个后的结果:
现在手动定位和自动定位均已完成,逻辑是只有自动定位失败的时候,手动定位图标才会出现。
手动修改天气
接下来你可能已经看到,第二幅效果图比第一份多出来一个太阳的图标,这是做什么的呢?这个是一个天气设置 的功能,和定位一样,当自动获取天气失败的时候,会出现这个图标,用来手动设置天气,这个图标的相关代码如下:
<mu-icon value="wb_sunny" v-on:click="chooseWeather" v-if="weatherBtn"/>
weatherBtn同样在store中设置:
weatherBtn:false
而chooseWeather方法也和定位基本一样,只有一行逻辑代码代码,但多出一行调用设置默认天气语句的方法:
chooseWeather:function(event){
this.setWeatherText();
this.weatherdialog=true
}
在介绍setWeatherText之前,先看一下本页面定义的几个属性的含义和值:
low:9, //最低气温 小于最高气温
lowMin:-10, //最低气温最小值
lowMax:34, //最低气温最大值
high:10, //最高气温 大于最低气温
highMin:-9, //最高气温最小值
highMax:35, //最高气温最大值
weatherIcon0:"weatherIconActive", //天气图标0 选中状态
weatherIcon1:"weatherIcon", //天气图标1
weatherIcon2:"weatherIcon", //天气图标2
weatherIcon3:"weatherIcon", //天气图标3
weatherIcon4:"weatherIcon", //天气图标4
weatherIcon5:"weatherIcon", //天气图标5
weatherText:"晴 10度/9度", //窗体中显示文言
weatherIconText:["晴","多云","阴","雨","雪","霾"],//不同图标代表的文字
weatherIconIndex:0, //选中的天气图标
weatherContent:"", //实际天气值
定义的变量好多呀,但其实除去几个最大最小值和图标样式之外,和定位也就没什么区别了。接下看一下弹出窗体的代码:
<mu-dialog :open="weatherdialog" title="请选择">
<div style="text-align:center">
<img src="../assets/3d_60/0.png" :class="weatherIcon0" @click="chooseWeatherIcon(0)">
<img src="../assets/3d_60/7.png" :class="weatherIcon1" @click="chooseWeatherIcon(1)">
<img src="../assets/3d_60/9.png" :class="weatherIcon2" @click="chooseWeatherIcon(2)">
<img src="../assets/3d_60/13.png" :class="weatherIcon3" @click="chooseWeatherIcon(3)">
<img src="../assets/3d_60/24.png" :class="weatherIcon4" @click="chooseWeatherIcon(4)">
<img src="../assets/3d_60/30.png" :class="weatherIcon5" @click="chooseWeatherIcon(5)">
</div>
<div>
<div class="weatherNumber">
{{highMin}}
</div>
<div class="weatherSlider">
<mu-slider v-model="high" :max="highMax" :min="highMin" :step="1" @change="highSliderChange"/>
</div>
<div class="weatherNumber">
{{highMax}}
</div>
</div>
<div class="clr"></div>
<div>
<div class="weatherNumber">
{{lowMin}}
</div>
<div class="weatherSlider">
<mu-slider v-model="low" :max="lowMax" :min="lowMin" :step="1" @change="lowSliderChange"/>
</div>
<div class="weatherNumber">
{{lowMax}}
</div>
</div>
<div class="clr"></div>
<div style="text-align:center">
{{weatherText}}
</div>
<mu-flat-button slot="actions" primary @click="weatherClose" label="确定"/>
</mu-dialog>
看着有点长?其实拆分后没啥,一个图标按钮组,两个滚动条,一个显示文言的字符串,还有一个按钮,接下来看看他长得样子吧:
选择图标chooseWeatherIcon方法的代码如下:
chooseWeatherIcon:function(index){
this.weatherIconIndex=inidex;
for(var i=0;i<6;i++){
this["weatherIcon"+i]="weatherIcon";
}
this["weatherIcon"+this.weatherIconIndex]="weatherIconActive";
this.setWeatherText();
},
逻辑也比较简单,首先将几个图标的css全部复位,然后在给选中的赋予active状态的css,之后同样调用了setWeatherText()方法
滚动条的方法几乎不用说,就是判断一下high和low两值的关系,确保最高气温永远大于最低气温即可(只列出最高气温的滚动条时间方法):
highSliderChange:function(event){
//最低气温不能高过此值
if(this.low>=this.high){
this.low=this.high-1;
}
this.setWeatherText();
},
这时候,在看setWeatherText方法的代码就很简单了,其实就是一个字符串拼接的过程:
setWeatherText:function(){
this.weatherText= this.weatherIconText[(this.weatherIconIndex)]+" "+this.high+"度/"+this.low+"度";
},
最后,还是随便选择一个天气状况,然后看一下效果:
点击确定后:
达成了我们所需的效果。
此刻心情
最后,还有一个在这个组件内不显示,但列表中需要显示的功能,那就是心情,这个就很简单了,实际上只要选择好了图标,就是把天气的滚动条删除就好:
<mu-dialog :open="mooddialog">
<div style="text-align:center">
<div style="text-align:center;float:left">
<mu-icon value="sentiment_very_satisfied" :size="40" v-on:click="moodClose(0)"/>
<div style="font-size: 11px;">惊喜</div>
</div>
<div style="text-align:center;float:left">
<mu-icon value="sentiment_satisfied" :size="40" v-on:click="moodClose(1)"/>
<div style="font-size: 11px;">开心</div>
</div>
<div style="text-align:center;float:left">
<mu-icon value="sentiment_neutral" :size="40" v-on:click="moodClose(2)"/>
<div style="font-size: 11px;">一般</div>
</div>
<div style="text-align:center;float:left">
<mu-icon value="sentiment_dissatisfied" :size="40" v-on:click="moodClose(3)"/>
<div style="font-size: 11px;">不好</div>
</div>
<div style="text-align:center;float:left">
<mu-icon value="sentiment_very_dissatisfied" :size="40" v-on:click="moodClose(4)"/>
<div style="font-size: 11px;">伤心</div>
</div>
</div>
</mu-dialog>
因为这个面板只提供一个值,所以也不需要独立的关闭按钮,选择之后关闭即可,最终效果如下:
至此,这个新建页面所需的全部附属功能已经完成,等等,如果你还记得的画,开始说好了天气要自动匹配的,只有匹配失败了,才会让大家手动操作,那么自动的该如何进行呢?鉴于篇幅已经够长,所以由下一章完成.
谢谢观看