「豆包Marscode体验官」改进tabs组件切换效果,丝滑的动画获得一致好评~

1,090 阅读7分钟

我正在参加「豆包MarsCode初体验」征文活动

豆包云编译器vscode:www.marscode.cn/home?utm_so…

项目背景

周末的时候,产品突然给我指了一个bug,说客户觉得tabs切换组件样式很丑,让我优化一下。

由于项目使用的是Elemnt Plus ,于是我立即反驳,Elemnt Plus就是这样设计的啊,改不了!

但是产品不死心,找到了我的组长!于是领导让我调研调研,看看有没有更好的组件库改一改。

我看了一眼Ant Desgn,但样式大差不差。

没办法,只能自己手搓一个tabs组件了!于是,经过我的不懈努力,终于开发出了一款样式非常丝滑的tabs切换组件!最终效果也是获得了同事们的一致称赞!

由于家里的电脑配置比较低,也没有安装前端开发的环境,为了尽快完成这个小需求,我决定使用最近字节新出的工具:豆包MarsCode

豆包MarsCode简介

豆包MarsCode(www.MarsCode.cn/home) 是基于字节跳动豆包大模型打造的更智能开发工具,提供云IDE 及 AI 编程助手两种使用形态。

其中,它的云IDE是一个非常新颖的工具,只要有网,就可以随时随地进行项目开发!

  • 它内置了各种语言的的模板,选择即可使用
  • 不用配置任何环境,也不吃电脑配置

我们的项目是基于vue3的,使用它内置的vue模板,完美符合我的工作场景!

Tabs组件开发

开发前准备工作

开发组件前,我们先创建vue模板,完成项目搭建。

使用豆包创建项目

模板的生成非常容易,点击创建按钮,选择vue模板即可。

豆包IDE生成的模板和vue官方一致,而且IDE布局非常简洁和VSCODE很像,没有任何额外的学习成本。

插件下载

创建模板后,项目所用的依赖已经帮我们下载好了,因此,我们不用执行npm i手动下载依赖。豆包云IDE和vscode一样,支持拓展插件下载,为了保持代码风格,我们可以安装喜好,给我们的云编译器安装一些插件。

  • indent-rainbow

插件的下载很容易,点击IDE右侧的拓展按钮搜索插件即可。

indent-rainbow主要是用来美化代码的,可以给代码生成好看的缩进。

  • Auto Rename Tag

快捷重命名html标签的一个工具。

开发思路分析

先参考最终效果图

上面的动画其实主要是两部分

  • 鼠标hover增加白底效果
  • 点击按钮背景色块进行移动

hover有手就会,就不说了,主要是如何实现点击按钮,背景色块跟随移动

我的思路是这样的:

首先,整个按钮的区域有一个背景色块,默认情况是透明的。当点击某个按钮时,色块颜色变白,然后根据点击结果动态计算其移动的位置和宽度即可。

代码开发

我们先借助豆包AI帮我们生成这个代码试试

试试它这个代码的效果

效果还行啊,改改样式说不定能用!

样式优化

Tabs.vue

<template>
  <div class="tabs-wrap">
    <div class="tabs">
      <-- tabs按钮 -->
      <div 
        v-for="(tab, index) in tabs" 
        :key="index" 
        :class="['tab', { active: activeTab === index }]" 
      >
        {{ tab }}
      </div>
      <-- 背景色块 -->
      <div class="tab-bacgroudd" :style="blueBarStyle"></div>
    </div>
  </div>
</template>

<script setup>

const tabs = ref(['豆包', '稀土掘金','快乐就是哈哈']);

const activeTab = ref(0);

</script>

<style scoped>
.tabs-wrap {
  padding: 4px;
  border-radius: 4px;
  background-color: #e8ecf0;
}

.tabs {
  display: flex;
  align-items: center;
  cursor: pointer;
  position: relative;
  z-index: 0;
}
.tab{
  padding: 5px 16px;
}
.tab.active {
  color: #007BFF;
}

.tab-bacgroudd {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  z-index: -1;
  width: 67px;
  border-radius: 4px;
  background: #fff;
}
</style>

看看效果:

可以看出,样式效果还是非常不错的!现在,我们使用js动态的改变色块的位置及宽度。

色块动画实现

我们基于豆包刚才生成的代码进行修改优化

<script setup>
import { ref, onMounted, nextTick, watch } from 'vue';

const tabs = ref(['豆包', '稀土掘金','快乐就是哈哈']);

const activeTab = ref(0);
const tabRefs = ref([]);
const blueBarStyle = ref({});

const switchTab = (index) => {
  activeTab.value = index;
  updateBlueBar();
};

const updateBlueBar = async () => {
  await nextTick();
  const activeTabEl = tabRefs.value[activeTab.value];
  if (activeTabEl) {
    const left = activeTabEl.offsetLeft;
    const width =activeTabEl.offsetWidth;
    blueBarStyle.value = {
      left: `${left}px`,
      width: `${width}px`,
    };
  }
};

onMounted(() => {
  updateBlueBar();
  window.addEventListener('resize', updateBlueBar);
});

</script>

如果代码看不明白,没关系,我们可以使用豆包AI生成注释

完成的代码

<template>
  <div class="tabs-wrap">
    <div class="tabs">
      <div 
        v-for="(tab, index) in tabs" 
        :key="index" 
        :class="['tab', { active: activeTab === index }]" 
        @click="switchTab(index)"
        ref="tabRefs"
      >
        {{ tab }}
      </div>
      <div class="tab-bacgroudd" :style="blueBarStyle"></div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick, watch } from 'vue';

const tabs = ref(['豆包', '稀土掘金','快乐就是哈哈']);

// 创建一个响应式变量 activeTab,默认值为 0
const activeTab = ref(0);
// 创建一个响应式变量 tabRefs,默认值为空数组
const tabRefs = ref([]);
// 创建一个响应式变量 blueBarStyle,默认值为一个空对象
const blueBarStyle = ref({});

// 定义一个常量 switchTab,用于切换标签页
const switchTab = (index) => {
  activeTab.value = index;
  // 更新蓝色条的显示
  updateBlueBar();
};

// 定义一个名为 updateBlueBar 的异步函数,用于更新蓝色条的样式
const updateBlueBar = async () => {
  // 等待下一个滴答,以确保所有更新完成
  await nextTick();
  // 获取当前激活的标签元素
  const activeTabEl = tabRefs.value[activeTab.value];
  // 如果找到了激活的标签元素
  if (activeTabEl) {
    // 获取元素的左偏移值
    const left = activeTabEl.offsetLeft;
    // 获取元素的宽度值
    const width =activeTabEl.offsetWidth;
    // 更新 blueBarStyle 的值,以设置蓝色条的位置和宽度
    blueBarStyle.value = {
      left: `${left}px`,
      width: `${width}px`,
    };
  }
};

onMounted(() => {
  updateBlueBar();
  window.addEventListener('resize', updateBlueBar);
});

</script>

<style scoped>
.tabs-wrap {
  padding: 4px;
  border-radius: 4px;
  background-color: #e8ecf0;
}

.tabs {
  display: flex;
  align-items: center;
  cursor: pointer;
  position: relative;
  z-index: 0;
}
.tab{
  padding: 5px 16px;
}
.tab.active {
  color: #007BFF;
  
}

.tab-bacgroudd {
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: -1;
  border-radius: 4px;
  background: #fff;
  transition: left 0.3s ease, width 0.3s ease, backgroundColor 0.3s ease; 
}
</style>

我们在看看最终效果:

非常丝滑啊!至此,我们这个组件基本上核心的部分就开发完了,我们只需要在其他地方引入使用即可!

给大家展示下项目中其他地方的使用效果:

项目上传git

项目开发完毕后,我需要将代码推送至git,这样下周去公司我就可以用电脑直接拉取代码了!豆包中推送代码的方式和本地开发几乎是一致的。

  • 如果我们没有使用代码仓库对豆包授权,我们可以配置ssh直接关联远程仓库,推送代码。
  • 如果我们使用仓库授权过豆包,那么git是随时可用的。

在豆包中,我们点击git的小图标,按照提示即可完成代码推送!

总结

由于传统的tabs组件样式难以满足定制化需求,因此,本文实现了一种带过渡动画的新型tabs组件,简单易用!相信大家可以很容易的应用到项目开发中。

值得一提的是,这个组件的开发完全是基于豆包MarsCode的,因此,我也来说说豆包MarsCode的一些使用感受。


首先,豆包云IDE真是一个非常不错的在线工具!就如我一开始说的,它无需配置任何环境,只要打开网页就能开心的进行代码开发,这一点,是本地开发无法比及的。


豆包云IDE的设计非常简洁,这让我们很容易知道如何操作,只要会使用vscode,基本上就可以完美的使用豆包IDE。在实际开发中,豆包的表现也是非常流畅的,开发体验相当不错,和本地开发几乎没有区别,可以看出字节在这个工具上的用心。


其次,豆包IDE内置了豆包AI助手,这让我们开发时,能获得更优质的AI辅助,能更大程度的提升我们的开发效率。比如,豆包AI的代码一键注释就设计的非常好,在同类产品中也是出类拔萃的!


但美中不足的是,豆包AI的代码生成结果感觉还是不尽人意,感觉和ChatGpt还是有一定的差距,不过也能接受,毕竟是免费产品。


希望豆包能做的更好!也希望各位读者能从这篇文章中获得到一点点知识!感谢大家!


是小姐姐,不是小哥