【记账本实战】05 记账本实战之导航栏

记账本实战之导航栏

前言

人人都能做的 Vue 记账本实战 专栏的前5篇文章中,我教大家从零开始搭建 Vue3.x + Vant4.x 的开发环境。如果小伙伴们还没有搭建好开发环境,建议先去看该专栏的前5篇文章,学完之后,相信你们都能亲手搭建一套属于自己的模板项目了,有了这个模板,就能够帮助你快速的启动一个项目了,而不需要每一次都从零开始手动搭建项目。还不止如此,你还可以根据时下的新技术,不断的去优化和完善你自己的这套模板项目,实现学习新知识的同时,还能优化和完善模板项目,可谓是一举两得。

另外,我也将教程制作成了 pdf 版,需要的小伙伴可以点赞收藏评论关注我私信免费获取,下面是 pdf 版的截图:

在这里插入图片描述

好的,言归正传,接下来进入我们本文的主题,移动端的项目,导航栏的制作是不可或缺的,本文将带大家实现底部导航栏和公用头部组件。当然,不是所有的页面都需要底部导航,所以这里还会涉及到路由的监听,判断哪些路径下要显示底部导航栏。并且我们还会使用 Vant 的 TabbarNavBar 组件来实现我们的需求。

底部导航栏的制作

首先我们打开前面我们搭建好的项目,在 src/components 目录下新建 NavBar.vue 组件,代码如下:

<template>
  <van-tabbar v-model="active">
    <van-tabbar-item icon="notes-o" @click="link('/home')">
      明细
    </van-tabbar-item>
    <van-tabbar-item icon="bar-chart-o" @click="link('/data')">
      统计
    </van-tabbar-item>
    <van-tabbar-item icon="user-o" @click="link('/user')">
      我的
    </van-tabbar-item>
  </van-tabbar>
</template>

<script>
import { ref } from "vue";
import { useRouter } from "vue-router";
export default {
  name: "NavBar",
  props: {
    msg: String,
  },
  setup() {
    const router = useRouter();
    const active = ref(0);

    const link = (path) => {
      router.push({ path });
    };

    return {
      active,
      link,
    };
  },
};
</script>

上面的代码,我们引入了 Tabbar 组件,v-model 默认绑定选中标签的索引值,通过修改 v-model 即可切换选中的标签。我们在 tabbar 组件中添加了三个导航选项,这三个导航通过 link 方法切换相应路径对应的页面。

然后我们在 src/views 目录下新建两个空白页面 Data.vueUser.vue,再修改 Home.vue 里面的代码,具体的代码内容如下:

Home.vue 代码:

<template>
  <div>明细</div>
</template>

<script>
export default {
  name: "HomeViews",
};
</script>

<style scoped></style>

Data.vue 代码:

<template>
  <div>统计</div>
</template>

<script>
export default {
  name: "DataViews",
};
</script>

<style scoped></style>

User.vue 代码:

<template>
  <div>个人中心</div>
</template>

<script>
export default {
  name: "UserViews",
};
</script>

<style scoped></style>

然后进入 src/router/inedx.js 将这三个页面给定对应的路径,也就是我们上述导航栏 link 方法传参的路径,如下所示:

// 1. 从依赖包中导入路由函数 createRouter 和 createWebHashHistory
import { createRouter, createWebHashHistory } from "vue-router";

// 2. 从其他文件导入路由组件(路由懒加载)
const Home = () => import("../views/Home.vue"); // 明细
const Data = () => import("../views/Data.vue"); // 统计
const User = () => import("../views/User.vue"); // 个人中心

// 3. 定义一些路由
// 每个路由都需要映射到一个组件
const routes = [
  {
    path: "/",
    redirect: "/home",
  },
  {
    path: "/home",
    name: "home",
    component: Home,
  },
  {
    path: "/data",
    name: "data",
    component: Data,
  },
  {
    path: "/user",
    name: "user",
    component: User,
  },
];

// 4. 使用 createRouter 方法创建一个路由实例 router
const router = createRouter({
  // 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式
  history: createWebHashHistory(),
  routes, // `routes: routes` 的缩写
});

// 5. 导出路由对象
export default router;

大家是否还记得我们在 src/router/index.js 路由配置文件中是如何引入页面组件的呢?🤔

没错,就是下面这种方式:

// 2. 从其他文件导入路由组件
import Home from "../views/Home.vue";

接下来,为大家提供一个新的导入方案,它可以让我们在需要使用到该组件页面的时候再加载它,从而做到页面的按需加载,也叫懒加载。其实现也比较简单,我们只需对上面的代码做如下修改即可:

// 2. 从其他文件导入路由组件(路由懒加载)
const Home = () => import("../views/Home.vue"); // 明细
const Data = () => import("../views/Data.vue"); // 统计
const User = () => import("../views/User.vue"); // 个人中心

或者也可以直接写入到路由配置项中:

// 3. 定义一些路由
// 每个路由都需要映射到一个组件
const routes = [
  {
    path: "/",
    redirect: "/home",
  },
  {
    path: "/home",
    name: "home",
    component: () => import("../views/Home.vue"),
  },
  {
    path: "/data",
    name: "data",
    component: () => import("../views/Data.vue"),
  },
  {
    path: "/user",
    name: "user",
    component: () => import("../views/User.vue"),
  },
];

通过观察我们不难看出,它实际上就是将每个组件的导入封装在了一个箭头函数中,只有在访问该页面的时候才会触发该箭头函数运行,从而将组件 import 进来。

然后在 App.vue 中引入 NavBar 组件,如下所示:

在这里插入图片描述

接下来我们将对不需要底部的页面进行过滤,打开 App.vue,代码如下:

<template>
  <div>
    <!-- 设置路由页面显示区域 -->
    <router-view></router-view>
    <!--代码1-->
    <NavBar v-if="show"></NavBar>
  </div>
</template>

<script>
import { reactive, toRefs } from "vue";
import NavBar from "./components/NavBar.vue";
import { useRouter } from "vue-router";
export default {
  name: "App",
  components: {
    NavBar,
  },
  setup() {
    const state = reactive({
      // 代码2
      menu: ["/home", "/data", "/user"],
      show: false,
    });
    const router = useRouter();
    router.afterEach(() => {
      // menu 内的路径都是需要展示底部导航栏的
      state.show = state.menu.includes(router.currentRoute.value.path);
    });
    return {
      ...toRefs(state),
    };
  },
};
</script>

<style scoped></style>

代码 1 处添加了一个 show 变量用于控制是否显示底部导航栏。代码 2 为需要导航栏的页面路径,通过引入 useRouter 拿到 router 实例,实例中有一个方法属性,名为 afterEach,它的作用是当更换路径时,会执行回调方法。我们在回调方法内通过 router.currentRoute.value.path 属性拿到当前路径,根据 menu 变量去做判断,如果当前路径在 menu 数组内,则返回 true 赋值给 show 变量。这样就能动态的控制底部导航栏的显示隐藏。

我们来测试一下,新建一个不需要导航栏的页面。下一个教程中我们会讲登录注册模块,它是不需要底部导航栏的,所以我们在 src/views 下新建 Login.vue 文件,代码如下:

<template>
  <div>登录页面</div>
</template>

<script>
export default {
  name: "LoginViews",
};
</script>

<style scoped></style>

src/router/index.js 下添加登录页面组件,关键代码如下:

// 2. 从其他文件导入路由组件(路由懒加载)
// 省略......
const Login = () => import("../views/Login.vue"); // 登录

// 3. 定义一些路由
// 每个路由都需要映射到一个组件
const routes = [
	// 省略......
  {
    path: "/login",
    name: "login",
    component: Login,
  },
];

User.vue 下添加一个前往登录页面的路由跳转:

<template>
  <div>
    <router-link to="/login">前往登录页面</router-link>
  </div>
</template>

<script>
export default {
  name: "UserViews",
};
</script>

<style scoped></style>

打开浏览器页面效果如下所示:

在这里插入图片描述

可以看到,登录页面的底部导航栏已经不显示了。

公用头部组件的制作

src/components 目录下新建公用头部组件 Header.vue,代码如下:

<template>
  <!--代码1-->
  <div class="block"></div>
  <!--代码2-->
  <van-nav-bar
    class="header"
    :title="title"
    left-text="返回"
    left-arrow
    @click-left="back"
  >
    <template #right>
      <!--代码3-->
      <i class="iconfont icon-gengduo"></i>
    </template>
  </van-nav-bar>
</template>

<script>
import { useRouter } from "vue-router";

export default {
  name: "Header",
  // 代码4
  props: {
    title: {
      type: String,
      default: "",
    },
  },
  setup() {
    const router = useRouter();
    // 代码5
    // 返回方法
    const back = () => {
      router.back();
    };
    return {
      back,
    };
  },
};
</script>

<style lang="less" scoped>
.block {
  width: 100%;
  height: 46px;
}

.header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  .more {
    font-size: 20px;
  }
}
</style>

分析上述代码,代码 2 引入 NavBar 组件,title 通过变量的形式从外部传入。再给一个固定定位,将它固定在页面的顶部,此时下方的页面便会顶上来,所以代码 1 为占位标签,给的高度和 NavBar 组件一样高,这样就能将顶部撑开,不会让页面有一部分隐藏在 NavBar 后面。代码 3 为 iconfont 的字体图标,伙伴们自行引入改名便可使用。代码 4 为外部引用组件时传入的 title 变量。当我们点击公用头部的左侧“返回”时,需要做出响应,代码 5 便是该方法,点击之后调用 router.back() 返回上一级。

我们在 Login.vue 引入上述组件:

<template>
  <Header title="登录页面"></Header>
  登录页面
</template>

<script>
import Header from "../components/Header.vue";
export default {
  name: "LoginViews",
  components: {
    Header,
  },
};
</script>

<style scoped></style>

此时我们打开浏览器查看页面效果:

在这里插入图片描述

完成到这一步,我们的公用头部组件就算完成了。

总结

本文带大家完成了导航栏和公用头部组件的制作,后续的页面都会基于这三个导航栏页面展开。所以前期的工作一定要准备到位,否则到了后期再修改公用组件,会牵一发动全身,得不偿失。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值