uni-app卖座电影多端开发纪实(二):搭建导航

253 阅读3分钟

@创建4个Tab页

创建一个测试页hello

  • 在pages目录上右键,新建页面
  • 执行如图操作,即可全自动生成页面组件+页面注册(pages.json)

image.png

pages.json 中会生成这么一个玩意,就是页面声明了

pages:[
    {
        "path" : "pages/hello/hello",
        "style" :                                                                                    
        {
            "navigationBarTitleText": "",
            "enablePullDownRefresh": false
        } 
    }
]

创建4个Tab页

  • 上面的动作如法炮制,声明出电影页film.vue + 影院页cinema.vue + 资讯页news.vue + 个人中心mine.vue
  • pages.json中的pages数组中也会出现4个页面声明对象,形如上面的hello.vue

image.png

@使用Tabbar导航

想要这种效果↓↓

image.png

uView的Tabbar使用

uView文档Tabbar示例代码

封装Tabbar组件

  • 我们基于uView的Tabbar封装一个自己的Tabbar出来;
  • 其中涉及到的图标都来自 uView/Icon
  • 其实并没有什么改动,只是封装一下,后续在每个页面中直接部署一下就得了,免得搬砖!

components/Tabbar.vue

<template>
   <!-- 将来直接放到每个页面的最下方 -->
   <!-- props:current=当前选中Tab序号 list=Tab配置 active-color=被激活的字体颜色 -->
   <!-- events:@change=用户切换Tab时的回调 事件载荷即所点击的Tab序号 -->
   <u-tabbar
      v-model="current"
      :list="list"
      active-color="orange"
      @change="onChange">
   </u-tabbar>
</template>

<script>
export default {
   data() {
      return {
         /* 4个Tab页的定义 */
         list: [
            {
               pagePath: "pages/film/film",
               iconPath: "play-right",
               selectedIconPath: "play-right-fill",
               text: "电影",
               customIcon: false,
            },
            {
               pagePath: "pages/cinema/cinema",
               iconPath: "photo",
               selectedIconPath: "photo-fill",
               text: "影院",
               customIcon: false,
            },
            {
               pagePath: "pages/news/news",
               iconPath: "chat",
               selectedIconPath: "chat-fill",
               text: "资讯",
               customIcon: false,
            },
            {
               pagePath: "pages/mine/mine",
               iconPath: "account",
               selectedIconPath: "account-fill",
               text: "我的",
               customIcon: false,
            },
         ],
         current: 0,
      };
   },

   methods: {
      /* 点击某个Tab时 */
      onChange(index) {
         console.log("onChange", index);

         // 根据Tab序号切换对应的页面
         uni.switchTab({
            url: "/" + this.list[index].pagePath,
         });
      },
   },
};
</script>

<style lang="scss"></style>

注册Tabbar为全局组件

main.js

import Tabbar from "./components/Tabbar.vue"
Vue.component('tabbar', Tabbar)

Tabbar部署到每个Tab页

  • 有人会觉得每个页面都丢一个Tabbar很笨拙,直接用在根组件中部署一个Tabbar,使用动态组件<component :is="xxx"></component>切换页面不就得了吗?
  • 事实是:小程序跟纯Vue项目还是有区别的,小程序的逻辑是:每个页面都是完全独立存在的,在渲染逻辑上并没有所谓公共父组件的存在;
  • news.vue为例,其余三个如法炮制;

pages/news/news.vue

<template>
   <!-- 页面须有唯一根布局 -->
   <view class="wrapper">
      <!-- 这里是自己封装过的导航栏 -->
      <my-navbar
         v-show="showNavbar"
         :title="title"></my-navbar>

      <!-- 这里是内容区 -->
      <div
         style="margin-top: 50rpx"
         class="content"
         v-html="content"></div>

      <!-- 这里是自己封装过的Tabbar -->
      <!-- 已经注册为全局组件了,无需引入拿来直接用 -->
      <tabbar></tabbar>
   </view>
</template>

修改pages.json

  • 我们使用了第三方的Tabbar,页面声明也要相应地进行必要改动

pages.json

{
    ...
    
   /* 页面声明 */
   "pages": [
      /* 一个页面声明 */
      // {
      //     "path" : "pages/hello/hello",
      //     "style" : {
      //         "navigationBarTitleText": "",
      //         "enablePullDownRefresh": false
      //     }
      // },
      
      /* 4个Tab页 */
      {
         // 组件位置:pages/film/film.vue
         "path": "pages/film/film",
         // 使用自定义的NavBar覆盖uni-app原生的导航栏
         "style": {
            "navigationStyle": "custom",
            "navigationBarTextStyle": "black"
         }
      },
      {
         "path": "pages/cinema/cinema",
         "style": {
            "navigationStyle": "custom",
            "navigationBarTextStyle": "black"
         }
      },
      {
         "path": "pages/news/news",
         "style": {
            "navigationStyle": "custom",
            "navigationBarTextStyle": "black"
         }
      },
      {
         "path": "pages/mine/mine",
         "style": {
            "navigationStyle": "custom",
            "navigationBarTextStyle": "black"
         }
      }
   ],
   
   /* 自定义底部TabBar */
   "tabBar": {
      "color": "#7A7E83",
      "selectedColor": "#3cc51f",
      "borderStyle": "white",
      "backgroundColor": "#f4f5f7",
      
      // 使用自定义Tabbar
      "custom": true,
      
      /* 定义4个tab */
      "list": [
         {
            "pagePath": "pages/film/film",
            // "iconPath": "home",
            // "selectedIconPath": "home-fill",
            "text": "电影",
            "customIcon": false
         },
         {
            "pagePath": "pages/cinema/cinema",
            // "iconPath": "photo",
            // "selectedIconPath": "photo-fill",
            "text": "影院",
            "customIcon": false
         },
         {
            "pagePath": "pages/news/news",
            // "iconPath": "play-right",
            // "selectedIconPath": "play-right-fill",
            "text": "资讯",
            "customIcon": false
         },
         {
            "pagePath": "pages/mine/mine",
            // "iconPath": "account",
            // "selectedIconPath": "account-fill",
            "text": "我的",
            "customIcon": false
         }
      ],
      // 默认选中第0个tab
      "current": 0
   },
   
   ...
}

Tabbar导航齐活!😎😎😎

@使用NavBar导航

  • Tabbar在地上导航,NavBar在天上导航,手机屏幕不就这几板斧吗?🙃

uView的Navbar使用

先把这个搂一眼→_→ uView/Navbar文档

封装MyNavbar

  • 基于uView/Navbar我们自己封装一个出来以免到处搬砖;
  • 原理与Tabbar相同,Navbar也必须每个页面一个,每个页面都是完全独立的,不存在多个页面共用一个实例这个选项;
  • 基于easy-com规范,形如components/xxx/xxx.vue的组件无需引入和声明即可直接在任何页面的模板上直接使用;
  • 在components文件夹上右键-新建组件,做如下配置,即全自动生成符合easy-com规范的组件;

image.png

我们封装想要实现如下效果↓↓

image.png

components/my-navbar/my-navbar.vue

<template>
   <!-- 参见 http://v1.uviewui.com/components/navbar.html 末尾的API -->
   <u-navbar
      :is-back="true"
      back-text="广州"
      :custom-back="onBack"
      back-icon-name="arrow-down"
      back-icon-size="0"
      :z-index="10"
      style="height: 100rpx"
      v-show="showNavbar"
      :title="title">
   </u-navbar>
</template>

<script>
export default {
   name: "my-navbar",

   /* 
   从父组件接收props:
   title = 导航栏标题
   showNavbar = 是否需要显示导航栏(很多情况下我们不显示它)
   */
   props: {
      title: String,
      showNavbar: Boolean,
   },

   data() {
      return {};
   },

   methods: {
      /* 传统的回退区域:我们跳转【城市选择页】 */
      onBack(arg) {
         console.log("onBack", arg);
         uni.navigateTo({
            url: "/pages/sub/cities/cities",
         });
      },
   },
};
</script>

<style>
/* 一些细枝末节的样式改动 */
[data-custom-hidden="true"],
[bind-data-custom-hidden="true"] {
   display: block !important;
}
</style>

在Tab页部署导航栏

  • 无需引入直接部署就好,传入props
  • 以资讯页为例:

pages/news/news.vue

<template>
   <!-- 页面须有唯一根布局 -->
   <view class="wrapper">
   
      <!-- 这里是自己封装过的导航栏 -->
      <my-navbar
         v-show="showNavbar"
         :title="title"></my-navbar>

      <!-- 这里是内容区 -->
      <div
         style="margin-top: 50rpx"
         class="content"
         v-html="content"></div>

      <!-- 这里是自己封装过的Tabbar -->
      <!-- 已经注册为全局组件了,无需引入拿来直接用 -->
      <tabbar></tabbar>
   </view>
</template>

<script>
export default {
   data() {
      return {
         title: "资讯", //导航栏标题
         showNavbar: true, //显示导航栏
         content: "",
      };
   },

   mounted() {...},

   methods: {...},
};
</script>

<style lang="scss">
.wrapper {
   display: flex;
   flex-direction: column;
   height: 100vh;
   background-color: #eee;

   .page {
      flex-grow: 1;
   }
}
</style>

城市选择页的导航栏

  • 直接使用uView/Navbar,因为在城市选择页导航栏左侧点击,要的就是uView/Navbar的默认回退功能;

pages/cities/cities.vue

<template>
   <view>
      <!-- 没有用自己封装的MyNavbar,因为点击左侧要的就是【默认的回退功能】 -->
      <u-navbar
         back-icon-name="close"
         back-icon-size="35"
         v-show="showNavbar"
         :title="title"></u-navbar>

      <!-- 城市列表插件 -->
      <t-index-address @select="select"></t-index-address>
   </view>
</template>

<script>
export default {
   data() {
      return {
         title: "当前城市",
         showNavbar: true,
         content: "",
      };
   },
   methods: {
      select(data) {
         console.log(data);
      },
   },
};
</script>

<style></style>

实现效果如下↓↓

image.png

再关注一下pages.json

  • 所有需要使用导航栏的页面声明长成这样子:
  {
     "path": "pages/news/news",
     
     // 使用自定义导航栏了
     "style": {
        "navigationStyle": "custom",
        "navigationBarTextStyle": "black"//写black就好,white时文字与背景同色不可见了
     }
  },

NavBar导航齐活!收工!🥱🥱


😈 点赞收藏加关注了吗??

image.png

本项目源码 watch,follow,fork!!!

祝大家撸码愉快~