animation 和 transition

animation 和 transition 不能同时控制同一个属性(width),否则会发生冲突:

animation:通常在元素创建时执行一次,执行完后属性就固定了,后续数据变化不会触发。

transition:只有在元素已存在且属性值发生变化时才生效,初始渲染时通常不生效。

要想同时拥有"首屏加载动画"和"数据更新动画",最佳方案是分离职责:

首屏加载动画:使用 animation 控制 transform: scaleX()(视觉上的缩放),不影响布局。

数据更新动画:使用 transition 控制 width(实际宽度的变化)。

这样既保证了第一次加载时有"生长"效果,又保证了后续数据变动时有"平滑过渡"效果。

html 复制代码
<template>
  <div class="home-page">
    <div class="left-panel">
      <div class="bar-wrap">
        <div class="left-bar" :style="{ width: leftBarWidth }"></div>
        <div class="right-bar" :style="{ width: rightBarWidth }"></div>
      </div>
    </div>
    <div class="right-panel"></div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'

const info = ref({
  inNum: 0,
  outNum: 0,
  total: 0
})

const leftBarWidth = computed(() => {
  if (info.value.total) {
    return `${info.value.inNum / info.value.total * 100}%`
  } else {
    return '0'
  }
})

const rightBarWidth = computed(() => {
  if (info.value.total) {
    return `${info.value.outNum / info.value.total * 100}%`
  } else {
    return '0'
  }
})

setTimeout(() => {
  info.value = {
    inNum: 10,
    outNum: 5,
    total: 15
  }
}, 1000)

setTimeout(() => {
  info.value = {
    inNum: 5,
    outNum: 10,
    total: 15
  }
}, 3000)

setTimeout(() => {
  info.value = {
    inNum: 10,
    outNum: 5,
    total: 15
  }
}, 5000)
</script>

<style lang="scss" scoped>
.home-page {
  width: 100%;
  height: 100%;
  background: linear-gradient(180.00deg, rgba(15, 28, 65, 1), rgba(13, 14, 33, 1));
  position: relative;
  padding: 136px 24px 24px 24px;

  .left-panel,
  .right-panel {
    width: 348px;
    height: 100%;
    background: linear-gradient(138.01deg, rgba(67, 140, 255, 0.96) -1.974%, rgba(39, 65, 113, 0.31) 27.287%);
    float: left;
    animation: fromLeft .5s ease-out forwards;	// 快速启动,缓慢结束
    /* 确保动画在合成层运行 */
    backface-visibility: hidden;
    /* 或者 (旧版 Webkit) */
    -webkit-backface-visibility: hidden;
    padding: 10px;
  }

  .right-panel {
    float: right;
    animation: fromRight .5s ease-out forwards;
  }

  .bar-wrap {
    width: 100%;
    height: 22px;
    display: flex;
    align-items: center;

    .left-bar {
      height: 12px;
      background: linear-gradient(90.00deg, rgba(124.6, 244.75, 217.88, 1), rgba(15, 251, 240, 1) 99.419%);
      clip-path: polygon(6px 0%, 100% 0%, calc(100% - 6px) 100%, 0% 100%);
      transition: all 1.2s ease-out;
    }

    .right-bar {
      height: 12px;
      background: linear-gradient(90.00deg, rgba(245, 187, 125, 1), rgba(251, 130, 15, 1) 99.419%);
      clip-path: polygon(6px 0%, 100% 0%, calc(100% - 6px) 100%, 0% 100%);
      transition: all 1.2s ease-out;
    }
  }

  @keyframes fromLeft {
    from {
      transform: translateX(-100%);
    }

    to {
      transform: translateX(0);
    }
  }

  @keyframes fromRight {
    from {
      transform: translateX(100%);
    }

    to {
      transform: translateX(0);
    }
  }
}
</style>
相关推荐
千叶风行5 小时前
Text-to-SQL 技术设计与注意事项
前端·人工智能·后端
软件开发技术深度爱好者6 小时前
HTML5+JavaScript读取DOCX 文档完整内容
前端·html5
幽络源小助理6 小时前
苹果CMS V10 MXPro V4.5模版下载, 自适应视频主题源码, 幽络源源码
前端·开源·源码·php源码
kyriewen6 小时前
坏了,黑客学会用AI写外挂了
前端·程序员·ai编程
xiangxiongfly9157 小时前
Vue3 根据角色权限动态加载路由
前端·javascript·vue.js·动态加载路由
达达尼昂7 小时前
Claude 多 Agent 系统:从零搭建一个 4 Agent 团队
前端·架构·ai编程
容智信息8 小时前
AI Agent(智能体)的输出格式应该从 Markdown 转向 HTML吗?
前端·人工智能·rust·编辑器·html·prompt
_风满楼8 小时前
TDD 进阶:换个角度看会议室预约
前端·javascript·github
Amy_yang8 小时前
uni-app 安卓端纯前端预览 DOCX 的实现思路
前端·vue.js
x_y_8 小时前
分享一个自己总结的前端开发skill~ requirement-to-delivery
前端·ai编程