搜公众号
推荐 原创 视频 Java开发 开发工具 Python开发 Kotlin开发 Ruby开发 .NET开发 服务器运维 开放平台 架构师 大数据 云计算 人工智能 开发语言 其它开发 iOS开发 前端开发 JavaScript开发 Android开发 PHP开发 数据库
Lambda在线 > 懒癌患者维尼 > vue结合HBuilder开发机票航班app

vue结合HBuilder开发机票航班app

懒癌患者维尼 2019-02-10
举报

现如今移动端已是越发蓬勃,相较于前几年web盛行的时代,手机用户才是王道,对于我们web前端的开发er们,我们也来撸一个app,什么不会安卓?不会swift?对不起,只要会javascript,html,css就行。

前期准备工作

vue环境搭建
 
   
   
 
  1. npm i vue-cli -g

 
   
   
 
  1. npm install vue-cli -g

本项目基于vue自带脚手架搭建的web项目;然后命令行输入:

 
   
   
 
  1. vue init webpack-simple yida(项目名)

然后一路回车,默认配置就行,这时你的目录就会生成很多文件,这时vue默认脚手架为我们搭建的框架,最后在命令行输入:

 
   
   
 
  1. npm install    (###安装依赖)

  2. ###依赖装完后启动项目

  3. npm run dev

然后你就可以在浏览器访问项目了,说明vue项目搭建成功。

框架选型

JS框架已经选择好,那么就开始整合UI框架,本项目使用Muse-UI框架——一个基于vue2.0的Material Design风格的UI组件库。详细介绍可以参考官网。

这里只简单介绍引入框架,在main.js中添加如下代码:

 
   
   
 
  1. import MuseUI from 'muse-ui'     //引入museUI框架

  2. import minireset from 'minireset.css'

  3. import materialIcons from './assets/iconfont/material-icons.css'

  4. // import myIconfont from './assets/myIconfont/iconfont.css'

  5. import 'muse-ui/dist/muse-ui.css'

  6. import 'muse-ui/dist/theme-light.css' // 使用 light 主题

  7. Vue.use(MuseUI);

另外Muse-UI 推荐使用 Google 的 Material 字体图标库,有关所有可用图标的列表,请访问官方的Material Icons页面。这里我是直接下载了这个字体文件,放在了assets目录,当然你也可以像官网一样使用cdn引入字体图标。

当时做这个项目的时候还没出3.0,项目中使用的是2.10版本的MuseUI有问题的地方和有坈余的地方可以直接参考官网。

竟然是开发移动端App自然少不了手势插件,引入vue-touch插件:

 
   
   
 
  1. import VueTouch from 'vue-touch'      //手机touch事件插件

  2. Vue.use(VueTouch, { name: 'v-touch' });

组件开发

路由组件

首先我们分析下app的页面结构,如下图:

底部一个导航菜单,四个页面,很简单,复制粘贴四个路由就搞定,如下:

 
   
   
 
  1.        {

  2.            path: 'home',

  3.            name: 'Home',

  4.            meta: { index: 5 },

  5.            component: resolve => require(['@/pages/Home'], resolve),

  6.        }, {

  7.            path: 'favoriteFlight',

  8.            name: 'FavoriteFlight',

  9.            meta: { index: 6 },

  10.            component: resolve => require(['@/pages/FavoriteFlight'], resolve),

  11.        }, {

  12.            path: 'order',

  13.            name: 'OrderPage',

  14.            meta: { index: 7 },

  15.            component: resolve => require(['@/pages/OrderPage'], resolve),

  16.        }, {

  17.            path: 'person',

  18.            name: 'Person',

  19.            meta: { index: 8 },

  20.            component: resolve => require(['@/pages/Person'], resolve),

  21.        }

是不是很简单,万能的复制粘贴(手动滑稽)。但是城市选择页面如下所示:

vue结合HBuilder开发机票航班app

不包含底部导航栏,占据整个页面,很显然只有一个路由渲染钩子是不行的,我们需要嵌套路由。首先我们定义一个app.vue,

 
   
   
 
  1. /*

  2. * @Author: lsp

  3. * @Date: 2017-05-19 13:22:02

  4. * @Last Modified by:   lsp

  5. * @Last Modified time: 2017-05-22 13:22:02

  6. * @describe 没有头部标题和尾部导航的页面

  7. */

  8. <template>

  9.  <div id="app">

  10.    <transition :name="transitionName">

  11.            <router-view></router-view>

  12.        </transition>

  13.  </div>

  14. </template>

不包含顶部和头部的占据整个页面的一个路由,然后再在里面嵌套一个layout.vue,

 
   
   
 
  1. /* * @Author: lsp

  2. * @Date: 2017-05-19 13:22:02

  3. * @Last Modified by: lsp

  4. * @Last Modified time: 2017-05-22 13:22:02

  5. */

  6. <template>

  7.    <div>

  8.        <app-header v-show="showHeader"></app-header>

  9.        <transition :name="transitionName">

  10.            <router-view></router-view>

  11.        </transition>

  12.        <bottom-navigation class="bottom_nav"></bottom-navigation>

  13.    </div>

  14. </template>

  15. <script>

  16.    import appHeader from './components/Header'

  17.    import bottomNavigation from './components/BottomNavigation'

然后我们重新定义我们的路由,如下:

 
   
   
 
  1.    {

  2.        path: '/',

  3.        name: 'Layout',

  4.        component: resolve => require(['@/Layout'], resolve),

  5.        meta: { index: 4 },//meta对象的index用来定义当前路由的层级,由小到大,由低到高

  6.        redirect: '/guide1',

  7.        children: [{

  8.            path: 'home',

  9.            name: 'Home',

  10.            meta: { index: 5 },

  11.            component: resolve => require(['@/pages/Home'], resolve),

  12.        }, {

  13.            path: 'favoriteFlight',

  14.            name: 'FavoriteFlight',

  15.            meta: { index: 6 },

  16.            component: resolve => require(['@/pages/FavoriteFlight'], resolve),

  17.        }, {

  18.            path: 'order',

  19.            name: 'OrderPage',

  20.            meta: { index: 7 },

  21.            component: resolve => require(['@/pages/OrderPage'], resolve),

  22.        }, {

  23.            path: 'person',

  24.            name: 'Person',

  25.            meta: { index: 8 },

  26.            component: resolve => require(['@/pages/Person'], resolve),

  27.        }]

  28.    }, {

  29.        path: '/cityChoose',

  30.        name: 'CityChoose',

  31.        meta: { index: 9 },

  32.        component: resolve => require(['@/pages/CityChoose'], resolve),

  33.    }, {

  34.        path: '/flightList',

  35.        name: 'FlightList',

  36.        meta: { index: 10 },

  37.        component: resolve => require(['@/pages/FlightList'], resolve),

  38.    }, {

  39.        path: '/flightDetail',

  40.        name: 'FlightDetail',

  41.        meta: { index: 11 },

  42.        component: resolve => require(['@/pages/FlightDetail'], resolve),

  43.    }, {

  44.        path: '/login',

  45.        name: 'Login',

  46.        meta: { index: 12 },

  47.        component: resolve => require(['@/pages/Login'], resolve),

  48.    }, {

  49.        path: '/register',

  50.        name: 'Register',

  51.        meta: { index: 13 },

  52.        component: resolve => require(['@/pages/Register'], resolve),

  53.    }, {

  54.        path: '/personMessage',

  55.        name: 'PersonMessage',

  56.        meta: { index: 14 },

  57.        component: resolve => require(['@/pages/PersonMessage'], resolve),

  58.    }, {

  59.        path: '/setting',

  60.        name: 'Setting',

  61.        meta: { index: 15 },

  62.        component: resolve => require(['@/pages/Setting'], resolve),

  63.    }

这样我们就定义好我们的路由了,主页和关注航班这种作为子路由,想城市选择这种作为外层的路由,这样就可以完美解决刚刚的问题啦。细心的同学可能看到我定义的路由里面有一个meta属性,那么它们是干什么的呢?各位看官继续往下看。

页面切换动画

我们的app在页面切换的时候都是有一个慢慢转场的动画的,这样的用户体验才是最好的,不是直白的直接切换页面,点击右边的导航菜单会向左滑动切换页面,点左边的菜单会向右滑动切换页面,具体效果如下:

vue结合HBuilder开发机票航班app

那么如何实现呢,还记得上一个路由组件里面我们定义了一个神奇的属性meta,官网的描述是这样的:

vue结合HBuilder开发机票航班app

因此我们用这个属性记录页面的层级和和标识,并且约定,meta字段如果递增说明页面是前进的状态,动画效果向左滑,反之向右:

 
   
   
 
  1. <transition :name="transitionName">

  2.        <router-view></router-view>

  3. </transition>

  4. watch: {//使用watch 监听$router的变化

  5.    $route(to, from) {

  6.        //如果to索引大于from索引,判断为前进状态,反之则为后退状态

  7.        if(to.meta.index > from.meta.index){

  8.            //设置动画名称

  9.            this.transitionName = 'slide-left';

  10.        }else{

  11.            this.transitionName = 'slide-right';

  12.        }

  13.    }

  14. }

  15. /* 页面切换效果 */

  16. .slide-right-enter-active,

  17. .slide-right-leave-active,

  18. .slide-left-enter-active,

  19. .slide-left-leave-active {

  20.  will-change: transform;

  21.  transition: all 500ms;

  22.  position: absolute;

  23. }

  24. .slide-right-enter {

  25.  opacity: 0;

  26.  transform: translate3d(-100%, 0, 0);

  27. }

  28. .slide-right-leave-active {

  29.  opacity: 0;

  30.  transform: translate3d(100%, 0, 0);

  31. }

  32. .slide-left-enter {

  33.  opacity: 0;

  34.  transform: translate3d(100%, 0, 0);

  35. }

  36. .slide-left-leave-active {

  37.  opacity: 0;

  38.  transform: translate3d(-100%, 0, 0);

  39. }

因此我们需要在路由中定义好每个页面的meta的大小,来赋予它左滑还是右滑,具体请看代码。

loading组件

数据加载还需要有loading加载动画,我们继续封装loding组件,这部分我是使用css动画来实现的,具体代码请看github。

启动页组件

一般app启动都会有一个启动页,占据全屏,左上角有个跳过,本项目我也做了几个启动页,利用路由,首先导航至guide页面,然后添加手机滑动事件,滑动到下一个引导页,实现思路如下:

 
   
   
 
  1. <!-- vue-touch提供的滑动事件指令,可以参考vue-touch文档 -->

  2.        <v-touch @swipeleft="onSwipeLeft" @swiperight="onSwipeRight">

  3.            <transition :name="transitionName">

  4.                <router-view ></router-view>

  5.            </transition>

  6.        </v-touch>

  7.        onSwipeLeft() {

  8.            // router转场后会自动触发vueg的转场特效

  9.            switch (this.$route.name) {

  10.                case 'default':

  11.                case 'guide1':

  12.                    this.$router.push('guide2');

  13.                    break

  14.                case 'guide2':

  15.                    this.$router.push('guide3');

  16.                    break

  17.            }

  18.        },

  19.        onSwipeRight() {

  20.            this.$router.back();

  21.        },

vue结合HBuilder开发机票航班app

gif可能会有卡顿,大家可以直接clone代码,本地运行看看。

服务端

我们这个demo项目,航班数据是抓取某东的机票数据,接口请求过于频繁可能会受限制,需要验证码,服务端我是使用的bmob,个人感觉不好用,不如使用leancloud,因为bmob没有模块化的包,引入到vue很麻烦,当时也是踩了很多坑。短信服务也是使用的bmob的sdk的短信api,各位读者可以自行测试玩玩。本项目作为一个入门级的vue项目,各位大佬不喜勿喷,有问题大家一起学习交流,感谢支持。

项目打包

首先运行vue-cli的打包命令,npm run build;然后用hbuilder打开build生成的dist文件夹,如下操作:

按照提示一路打包,等待一会dist目录会多一个unpackage的文件夹,app文件就打包在release目录,可以直接在手机上安装体验。

以上就是本项目一点点介绍,有问题,欢迎大家一起来探讨。


版权声明:本站内容全部来自于腾讯微信公众号,属第三方自助推荐收录。《vue结合HBuilder开发机票航班app》的版权归原作者「懒癌患者维尼」所有,文章言论观点不代表Lambda在线的观点, Lambda在线不承担任何法律责任。如需删除可联系QQ:516101458

文章来源: 阅读原文

相关阅读

关注懒癌患者维尼微信公众号

懒癌患者维尼微信公众号:vonnielovezy

懒癌患者维尼

手机扫描上方二维码即可关注懒癌患者维尼微信公众号

懒癌患者维尼最新文章

精品公众号随机推荐

举报