美文网首页
vue创建天气webapp

vue创建天气webapp

作者: 心知天气 | 来源:发表于2018-09-14 14:56 被阅读0次

    vue创建天气webapp

    项目的仓库weather-forecast-vue
    项目demo
    目前完成了以下功能

    • [x] 当前定位城市天气信息查看
    • [x] 下拉刷新天气信息
    • [x] 上拉加载古诗信息
    • [x] 查看24小时逐小时天气信息
    • [x] 查看未来6天天气信息
    • [x] 日落日出时间展示
    • [x] 生活信息简略详细展示
    • [x] 城市管理
    • [x] 天气分享
    • [x] 语音播报

    先让我们来看看最终的效果是什么样的~

    <iframe height=432 width=768 src='https://player.youku.com/embed/XMzgxMjI2MjY0OA==' frameborder=0 'allowfullscreen'></iframe>

    话不多说,动手实现吧~

    Step1 安装vue-cli

    此处默认你的电脑当中已经安装 node.jsnpm

    1. 全局安装webpack
    npm install webpack -g
    
    1. 全局安装vue-cli
    npm install --global vue-cli
    

    Step2 构建项目并安装插件

    构建 vue 项目

    vue init webpack vueWeather //vueWeather为此项目的名称你也可以使用其他的
    cd ./vueWeather //进入到项目目录
    npm install
    npm run dev //以dev方式执行项目
    

    此时你就可以在浏览器当中看到你正在运行的项目

    当第一个命令执行后,会有几个选项让你选:

    • Project name项目名称
    • Project description (A Vue.js project)项目描述,也可直接点击回车,使用默认名字
    • Author ()作者
    • Runtime + Compiler: recommended for most users运行加编译,回车选择yesRuntime-only: about 6KB lighter min+gzip, but templates (or any Vue-specificHTML) are ONLY allowed in .vue files - render functions are required elsewhere仅运行时,已经有推荐了就选择第一个了
    • Install vue-router? (Y/n)是否安装vue-router,项目中我们会使用vue-router来做路由,所以选择yes
    • Use ESLint to lint your code? (Y/n)是否使用ESLint管理代码,根据自己的情况做出选择
    • Setup unit tests with Karma + Mocha? (Y/n)是否安装单元测试,笔者本次没有安装
    • Setup e2e tests with Nightwatch(Y/n)?是否安装e2e测试,笔者本次没有安装

    插件安装

    vue拥有丰富的轮子,所以我们可以直接使用已经写好的轮子,从而提高开发效率。

    1. 安装axios
      Vue 原本有一个官方推荐的 ajax 插件 vue-resource,但是自从 Vue 更新到 2.0 之后,尤雨溪宣布停止更新 vue-resource,并推荐大家使用axios之后,越来越多的 Vue 项目,都选择 axios 来完成 ajax 请求,而大型项目会使用 Vuex 来管理数据。
    npm install axios --save
    

    大部分的插件可以在 main.js 文件中引入后进行 Vue.use(),但是 axios 不能 use。只能每个需要发送请求的组件中即时引入。为了解决这个问题,有两种开发思路,一是在引入 axios 之后,修改原型链,二是结合 Vuex,封装一个 aciton。这里只说修改原型链的方式
    main.js 中引入 axios

    import axios from 'axios'
    

    这时候如果在其它的组件中,是无法使用 axios 命令的。所以我们将 axios 改写为 Vue 的原型属性

    Vue.prototype.$http= axios
    

    main.js 中添加了这两行代码之后,就能直接在组件的 methods 中使用 $http命令

    1. 安装muse-ui
      由于要实现手机端的webapp,于是在比较流行的框架中选择了muse-ui进行开发,具体使用方式如下,你也可以查看官方文档,进行跟深一步的学习。
    npm i muse-ui --save
    

    安装完成后,在main.js文件中进行引用

    import MuseUI from 'muse-ui';
    import 'muse-ui/dist/muse-ui.css';
    
    Vue.use(MuseUI);
    

    除此之外,还用到了 muse-ui 中提供的 muse-ui-loadingmuse-ui-progress
    muse-ui-loading用于实现加载动画

    npm install muse-ui-loading --save
    
    import 'muse-ui-loading/dist/muse-ui-loading.css'; // load css
    import Loading from 'muse-ui-loading';
    Vue.use(Loading);
    

    muse-ui-progress用于实现页面加载的进度条

    npm install muse-ui-progress --save
    
    //index.js 文件
    import 'muse-ui-progress/dist/muse-ui-progress.css';
    import NProgress from 'muse-ui-progress';
    Vue.use(NProgress);
    

    index.html 引入 muse-ui 推荐的Material Design Icons字体图标库

    <link rel="stylesheet" href="https://cdn.bootcss.com/material-design-icons/3.0.1/iconfont/material-icons.css">
    
    1. 安装vue-xc-city
      使用vue-xc-city这个插件用于城市搜索
    npm install vue-xc-city --save
    

    安装完成后,在main.js文件中进行引用

    import vueXcCity from 'vue-xc-city';  
    import 'vue-xc-city/dist/xc-city.css';  
    
    Vue.use(vueXcCity);
    
    1. 安装vue-slip-delete
      使用vue-slip-delete这个插件用于实现城市左滑删除
    npm install vue-slip-delete --save
    
    1. 安装v-distpicker
      使用v-distpicker这个插件用于实现城市选择功能
    npm install v-distpicker --save
    

    Step3 定位与天气API

    因为要查看当前位置的天气信息,所有要使用到定位API和天气API。

    天气API

    笔者在这里选用了心知天气提供的付费API

    心知天气支持全国2567个、全球24,373个城市和地点。

    定位API

    这次所使用的是高德地图所提供的API

    Step4 解决跨域问题

    vue 项目中,前端与后台进行数据请求或者提交的时候,如果后台没有设置跨域,前端本地调试代码的时候就会报“ No 'Access-Control-Allow-Origin' header is present on the requested resource. ” 这种跨域错误。
    这样的问题解决办法如下:
    config/index.js 中找到 proxyTable,将内容修改为如下

    proxyTable: {
      '/apis': {    //将www.exaple.com印射为/apis
        target: '',  // 接口域名
        secure: false,  // 如果是https接口,需要配置这个参数
        changeOrigin: true,  //是否跨域
        pathRewrite: {
          '^/apis': ''   //需要rewrite的,
        }
      }
    },
    

    这样修改后,使用 axios 就可以直接这样用:

    getData () { 
     this.$http.get('/apis/XXX', function (res) { 
       console.log(res) 
     })
    

    Step5 修改字体

    scr 目录下新建 common/font 目录,将要添加/修改的字体拷贝进去,然后新建 font.css 文件,样例为思源黑体。

    @font-face {
      font-family: 'SourceHanSansCN';
      src: url('./SourceHanSansCN.otf');
      font-weight: normal;
      font-style: normal;
    }
    
    

    Step6 编写 Vue 组件

    这一部分,笔者会挑组件中相对比较复杂的组件进行说明,其他组件大家直接看GitHub中的代码即可!

    Weather 组件

    这一组件用于显示天气信息,是一个复用的组件,展示当前城市天气,以及其他城市天气信息。
    这一页面由其他多个组件共同构成,通过传参来显示信息。

    下拉刷新

    这个页面的下拉刷新使用的是muse-ui所提供的组件。

    <mu-load-more @refresh="refresh" :refreshing="refreshing" :loading="loading" @load="load" :loading-text="localPeom">
    
    </mu-load-more>
    

    HelloWorld 组件

    这个组件是路由的默认页面,页面中只包含了 Weather 组件,HelloWorld 组件用于获取用户当前位置信息,然后再传递给 Weather 组件。

    index.html 中添加以下代码

      <script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.9&key=你的key"></script>
    
    GaoDeAPI(){
        var _this = this;
        var map, geolocation;
        //加载地图,调用浏览器定位服务
        map = new AMap.Map('FakeContainer', {
          resizeEnable: true
        });
        map.plugin('AMap.Geolocation', function() {
          geolocation = new AMap.Geolocation({
            enableHighAccuracy: true,//是否使用高精度定位,默认:true
            timeout: 10000,          //超过10秒后停止定位,默认:无穷大
            buttonOffset: new AMap.Pixel(10, 20),//定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
            zoomToAccuracy: true,      //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
            buttonPosition:'RB'
          });
          map.addControl(geolocation);
          geolocation.getCurrentPosition();
          AMap.event.addListener(geolocation, 'complete', onComplete);//返回定位信息
          AMap.event.addListener(geolocation, 'error', onError);      //返回定位出错信息
        });
        //解析定位结果
        function onComplete(data) {
          var str=['定位成功'];
          str.push('经度:' + data.position.getLng());
          str.push('纬度:' + data.position.getLat());
          _this.lon = data.position.getLng();
          _this.lat = data.position.getLat();
          var c = data.addressComponent.city;
          c= c.substring(0,c.length-1);
          localStorage.setItem('currentCity',c);
          console.log(c);
          if(data.accuracy){
            str.push('精度:' + data.accuracy + ' 米');
          }//如为IP精确定位结果则没有精度信息
          str.push('是否经过偏移:' + (data.isConverted ? '是' : '否'));
          //console.log(str);
        }
        //解析定位错误信息
        function onError(data) {
          console.log("gaode:"+data.message);
        }
    },
    

    HourWeather 组件

    这一组件用来显示未来24小时,逐小时天气信息。

    这个模块重点要实现左右滑动的效果

    <div class="HourBorder">
      <div class="HourAuto">
        <div class="context">
          <ul style="list-style:none;">
            <li v-for="(item,index) in hourData" :key="index" class="aDay" style="float:left; padding:0; ">
              <p>{{backTime(item.time)}}</p>
              <img :src="imgList[item.code]" alt="icon" ondragstart="return false;" oncontextmenu="return false;">
              <p>{{item.temperature}}°</p>
            </li>
          </ul>
        </div>
      </div>
    </div>
    

    HourBorder 类用于控制逐小时显示的大小,overflow: hidden 的设置使超出div的部分隐藏,不会使整个页面变形。
    HourAuto 类用于横向滑动,当元素宽度超过父容器时,自动左右滑动。

    City 组件

    这一组件当中,用到了 vue-slip-delete 这一插件,用于删除已添加的城市。

    <slip-del
    v-for="(item, i) in list"
        :key="i"
        ref="slipDel"
        @slip-open="slipOpen"
        @del-click="del(i)"
        v-if="i!=0"
    >
    <div class="demo-item">
      <mu-row class="d2" @click="navToFav(item.results[0].location.name)" :style="{backgroundImage:'url('+item.results[0].now.imageurl+dayOrNight+'.jpg'}">
        <mu-col span="9">
          <div class="d3">
            &nbsp;{{item.results[0].now.text}}
          </div>
          <div class="d4">
            {{item.results[0].location.name}}
          </div>
        </mu-col>
        <mu-col span="3">
          <div class="d5">
            {{item.results[0].now.temperature}}
          </div>
        </mu-col>
      </mu-row>
    </div>
    <div slot="del">
      <mu-icon size="32" value="delete" style="display: block; margin: 0 auto;"></mu-icon>
    </div>
    </slip-del>
    

    del()函数用于处理用户删除后的操作,这里我们将索引传入,用于删除相对应的城市。

    Favourite 组件

    Favourite 组件与 HelloWorld组件有类似的地方:整个组件是由 Weather 组件组成。不同的是,在城市列表页选择了城市后,跳转到 Favourite 组件中,并显示指定城市的天气情况。

    CitySelect 组件

    这个组件的作用是选择想要添加的城市,可以通过搜索和三级联动进行选择。分别用到了第三方插件vue-xc-cityv-distpicker

    <xc-city @get-data="getData"></xc-city>
    <div class="divwrap" v-if="show">
      <v-distpicker type="mobile" hide-area @province="onChangeProvince" @city="onChangeCity" @area="onChangeArea"></v-distpicker>
    </div>
    

    其他组件

    其他组件大部分都是展示像后台请求到的信息,使用不同的布局进行展示,以达到简洁但不简单的效果!

    详细代码可以查看weather-forecast-vue

    转自https://hanyuzhou.com/2018/09/07/a-vue-weather-forecast-webapp/

    欢迎学习交流~

    相关文章

      网友评论

          本文标题:vue创建天气webapp

          本文链接:https://www.haomeiwen.com/subject/vpyogftx.html