记账本实战之导航栏
前言
在人人都能做的 Vue 记账本实战 专栏的前5篇文章中,我教大家从零开始搭建 Vue3.x + Vant4.x 的开发环境。如果小伙伴们还没有搭建好开发环境,建议先去看该专栏的前5篇文章,学完之后,相信你们都能亲手搭建一套属于自己的模板项目了,有了这个模板,就能够帮助你快速的启动一个项目了,而不需要每一次都从零开始手动搭建项目。还不止如此,你还可以根据时下的新技术,不断的去优化和完善你自己的这套模板项目,实现学习新知识的同时,还能优化和完善模板项目,可谓是一举两得。
另外,我也将教程制作成了 pdf 版,需要的小伙伴可以点赞收藏评论关注我私信免费获取,下面是 pdf 版的截图:
好的,言归正传,接下来进入我们本文的主题,移动端的项目,导航栏的制作是不可或缺的,本文将带大家实现底部导航栏和公用头部组件。当然,不是所有的页面都需要底部导航,所以这里还会涉及到路由的监听,判断哪些路径下要显示底部导航栏。并且我们还会使用 Vant 的 Tabbar 和 NavBar 组件来实现我们的需求。
底部导航栏的制作
首先我们打开前面我们搭建好的项目,在 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.vue
,User.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>
此时我们打开浏览器查看页面效果:
完成到这一步,我们的公用头部组件就算完成了。
总结
本文带大家完成了导航栏和公用头部组件的制作,后续的页面都会基于这三个导航栏页面展开。所以前期的工作一定要准备到位,否则到了后期再修改公用组件,会牵一发动全身,得不偿失。