如果你想开发一个应用(1-19)

##手动定位##
在上一章节里,定位功能已经在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>

因为这个面板只提供一个值,所以也不需要独立的关闭按钮,选择之后关闭即可,最终效果如下:

至此,这个新建页面所需的全部附属功能已经完成,等等,如果你还记得的画,开始说好了天气要自动匹配的,只有匹配失败了,才会让大家手动操作,那么自动的该如何进行呢?鉴于篇幅已经够长,所以由下一章完成.

谢谢观看