Vue学习Day13 封装一个TabBar组件

想利用暑假时间好好学习一下vue,会记录每一天的学习内容。
今天是学习vue的第13天!

起起伏伏乃人生常态,继续加油~

这一篇比较适合新手小白看!有vue项目经验的可以不用看了,挺基础的



TabBar

1. TabBar实现思路

  1. 如果在下方有一个单独的TabBar组件,如何封装
    • 自定义TabBar组件,在App中使用
    • TabBar处于底部,并且设置相关样式
  2. TabBar中显示的内容由外界决定
    • 定义插槽
    • flex布局平分TabBar
  3. 自定义TabBarItem,可以传入图片和文字
    • 定义TabBarItem,并且定义两个插槽:图片、文字
    • 给两个插槽外层包装div,用于设置样式
    • 填充插槽,实现底部TabBar的效果
  4. 传入 高亮图片
    • 定义另外一个插槽,插入item-active-icon的数据
    • 定义一个变量isActive,通过v-if来决定是否显示高亮的item-icon
  5. TabBarItem绑定路由数据
    • 安装路由,vue-router
    • 完成router/index.js的内容,创建对应的组件
    • main.js中注册router
    • App中加入<router-view>组件
  6. 点击item跳转到对应路由,并且动态决定isActive
    • 监听item的点击,通过this.$router.push()替换路由路径
    • 通过this.$router.path.includes(this.path)来判断是否是active
  7. 动态计算active样式
    • 封装新的计算属性:this.isActive ? {'color': 'red'}: {}

2. 具体实现

基本结构搭建

用vue-cli建一个新项目

vue create tabbar

components文件夹里建一个tabbar文件夹,在里面建TabBar.vue文件
(这里建文件夹是为了便于管理)
在这里插入图片描述
为了能显示,要在App.vue中引入并注册
在这里插入图片描述
目前效果:
在这里插入图片描述


TabBar和TabBarItem组件封装

assets文件夹中放一些资源,创建img文件夹、css文件夹
在这里插入图片描述

放一些icon
在这里插入图片描述
图片也一起放进来
在这里插入图片描述在这里插入图片描述
⚠️:虽然这样实现看起来没什么问题,但是目前我们的TabBarTabBarItem耦合度太高了,我们的 TabBar.vue文件中应该是只关心TabBar的逻辑,而里面的TabBarItem的标签、样式,不应该在这个文件中去实现


tabbar文件夹中新建一个TabBarItem.vue文件
TabBarItem相关的模版和样式转移过来
直接在App组件中使用tab-bar-item组件,记得注册和导入
在这里插入图片描述
这里TabBarItem组件的模板暂时写死了,后面会改成能动态修改的
在这里插入图片描述
目前效果:
虽然看起来还不如刚才,但是结构清晰了很多
在这里插入图片描述


TabBarItem组件中的图片和文字都应该由外界决定,不能写死,所以这里替换成两个具名插槽
在这里插入图片描述
App组件中:<template>中的内容都会被传入对应名字的插槽
在这里插入图片描述
目前效果:
在这里插入图片描述


给TabBarItem传入active图片

为了显示活跃状态的图片,再设置一个插槽
(这里因为我用的都是png格式的图片,不是很方便通过样式改变颜色)
在这里插入图片描述
在这里插入图片描述
这样会出现两个图标,所以还要加个判断
在这里插入图片描述
文字颜色也要变
⚠️:

 <slot :class="{active: !isActive}" name="item-text"></slot>
.active {
    color: #fe6b57;
}

这样是不会生效的,因为插槽部分会被替换掉,替换的元素上面没有active

<div :class="{active: isActive}"> <slot name="item-text"></slot></div>

外面再套一层 div 就ok
v-if 为什么成功渲染了,不是很清楚,所以保险起见还是都套一层div

<div class="tab-bar-item">
    <div v-if="!isActive">
      <slot name="item-icon"></slot>
    </div>
    <div v-else>
      <slot name="item-icon-active"></slot>
    </div>
    <div :class="{ active: isActive }">
      <slot name="item-text"></slot>
    </div>
  </div>

TabBarItem和路由结合

我们希望点击TabBar的每个item都能跳转到相应的页面,这里就要用到路由了

安装vue-router

npm install vue-router --save

在这里插入图片描述
src文件夹中建一个router文件夹,在里面建index.js文件来配置vue-router
前两天刚学的,就不多说啦
在这里插入图片描述
main.js中导入,挂载路由实例
在这里插入图片描述
接下来要配置映射关系,我们需要配置4个映射关系,所以要先创建这4个组件
但是对于这种大的页面,一般不在components里面创建了,components放复用性比较高的组件

src文件夹下新建一个views文件夹
在这里插入图片描述
配置路由映射关系
也采用了路由的懒加载
在这里插入图片描述
我们希望在点击TabBarItem的时候完成切换,所以要监听它们的click事件
不要在App组件的<tab-bar-item>监听,不然要监听4个,直接在TabBarItem组件内部监听就好

<div class="tab-bar-item" @click="itemClick">
methods: {
      itemClick() {     
      }
  }

在点击事件发生的时候我们要执行的应该是路由的跳转,用到$router.push()$router.replace(),但这里的路径也不能写死,所以定义一个props,从App组件中将路径传进TabBarItem组件
(父子组件通信,父App,子TabBarItem

(这里不用动态绑定,写固定的)
在这里插入图片描述
在这里插入图片描述
然后因为哈希模式的路径会让我获取不到正确的pathname,所以我火速去改成history模式了
(有很多别的方法也可以使其不报错,这里就先用这个了)
(history模式个人也更喜欢)

const router = new VueRouter({
    routes,
    mode: 'history'
})

现在点击下方的TabBarItem已经能够跳转对应的路由,但是什么都没有显示出来
因为,我们没有用<router-view>
在这里插入图片描述
现在已经能成功跳转并显示了
在这里插入图片描述


TabBarItem颜色动态控制

接下来解决TabBarItem颜色问题
这里用计算属性解决了
$route.path拿到当前活跃的路由的路径
这里判断用了includes是因为后面可能还会有嵌套路由,如果直接用相等,不合适
在这里插入图片描述
成功了
在这里插入图片描述


还有一个需求,就是文字的颜色,希望能由外界决定,而不是被我们直接写死
在这里插入图片描述
在这里插入图片描述

但是这个activeColor在css里拿不到,所以这里要动态绑定style
在这里插入图片描述
现在传的颜色是blue
在这里插入图片描述
结束啦


Vue组件是可重用的UI元素,可以封装为公共组件供其他组件和应用程序使用。下面是一个简单的步骤来封装一个Vue的公共组件。 1. 创建组件文件:在项目中创建一个组件文件,命名为Example.vue。 2. 编组件内容:在Example.vue文件中定义组件的模板、样式和行为。 3. 导出组件:在Example.vue文件中使用export default将组件导出,以便其他组件和应用程序可以使用它。 4. 引入组件:在需要使用该组件的文件中,使用import Example from './Example.vue'导入该组件。 5. 注册组件:在需要使用该组件Vue实例中,使用Vue.component('example', Example)注册该组件,其中'example'是组件的名称,可以在模板中使用该名称来引用该组件。 6. 使用组件:在该Vue实例的模板中使用<example></example>标签来使用该组件。 下面是一个简单的示例,演示如何封装一个Vue的公共组件: Example.vue文件: ``` <template> <div class="example"> <h2>{{ title }}</h2> <p>{{ content }}</p> </div> </template> <script> export default { name: 'Example', props: { title: String, content: String } } </script> <style> .example { border: 1px solid #ccc; padding: 10px; } .example h2 { margin-top: 0; } </style> ``` 在需要使用该组件的文件中: ``` <template> <div> <example title="Hello" content="This is an example component"></example> </div> </template> <script> import Example from './Example.vue' export default { components: { Example } } </script> ``` 在Vue实例中注册组件: ``` Vue.component('example', Example) ``` 使用组件: ``` <example title="Hello" content="This is an example component"></example> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值