vue3 文档总结 -过渡&&动画

本文总结了Vue3中过渡和动画的使用,包括通过opacity和transform实现硬件加速,利用transition组件进行单元素/组件过渡,以及如何在列表过渡中使用transition-group。还介绍了不同过渡模式、过渡类名的自定义以及监听过渡完成的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

过渡&&动画描述

  1. 动画的实现不仅仅可以通过 margin,或者设置 top 来实现。还可以通过 transform,perspective 等来实现。
  2. 我们希望尽可能对元素动画进行硬件加速。并且使用不触发重绘的 property。
  3. 我们可以通过工具,如 CSS Triggers[https://csstriggers.com/]来查看哪些属性在动画时会触发重绘
  4. opacity, transform 不会触发任何几何形状的变化或者绘制。是在 web 上做元素移动的理想选择
  5. 注入 perspective、backface-visibility 和 transform:translateZ(x)等属性将让浏览器知道你需要硬件加速,如果你需要对一个元素进行硬件加速,可以使用任意一个

进入过渡 && 离开过渡

单元素/组件过渡

  • vue 提供了 transition 组件,无需引入。添加至组件可以控制过渡效果
    – v-if
    – v-for
    – component is (动态组件) - 多组件过渡
    – 组件根节点
    – transition 组件只接受一个组件或者标签。渲染多个元素时 v-if/v-else 最终渲染的也是一个标签
<template>
  <transition name="container">
    <div v-show="show">show something</div>
  </transition>
  <button @click="show = !show">toggle show</button>
</template>
import { defineComponent, ref } from "vue";
export default defineComponent({
  name: "App",
  components: {},
  setup(props) {
    const show = ref(false);
    return {
      show,
    };
  },
});
.container-enter-active,
.container-leave-active {
  transition: opacity 0.5s ease;
}

.container-enter-from,
.container-leave-to {
  opacity: 0;
}
  • 过渡 class(指定具体 name,或者使用默认的 v)
  1. [name]-enter-active: 定义进入过渡生效时的状态

  2. [name]-leave-active: 定义离开过渡生效时的状态

  3. [name]-enter-from: 定义进入过渡的开始状态

  4. [name]-leave-from: 定义离开过渡的开始状态

  5. [name]-enter-to: 定义进入过渡的结束状态

  6. [name]-leave-to: 离开过渡的结束状态。

  • transtion 组件接受以下属性来自定义过渡类名
  1. enter-from-class
  2. enter-active-class
  3. enter-to-class…
  • transtion 组件接受 transitionend/animationend 监听过渡的完成。取决于 css 规则
<transition name="container" @transitionend="alertcom">
  <div v-show="show">show something</div>
</transition>
<button @click="show = !show">toggle show</button>
setup(props) {
    const show = ref(false);
    const alertcom = () => {
      console.log('alertcom')
    }
    return {
      show,
      alertcom
};
  • transition 组件接受的其他参数(属性或者事件)
  1. type: 当前过渡是那种类型。取值范围为 animation/transition-参数

  2. duration: 过渡时间-参数

  3. before-enter: JS 钩子-事件

  4. enter: JS 钩子-事件

  • 过渡模式 - mode - 属性
  1. in-out:新元素先进行过渡,完成之后当前元素过渡离开
  2. out-in:当前元素先进行过渡,完成之后新元素过渡进入(Tips: 大多数情况下的理想状态)

列表过渡

  • 可以结合 v-for 使用
  • 使用到 transition-group 组件。可以接收多个组件,列表。不用必须绑定 v-if/v-show
<template>
  <button @click="add">Add</button>
  <button @click="deleteNum">Delete</button>
  <transition-group name="container">
    <span v-for="item in NumArr" :key="item" class="list-item">
      {{ item }}
    </span>
  </transition-group>
</template>
import { defineComponent, ref } from "vue";
const useGetRandomIdx = (arr) => {
  if (Array.isArray(arr)) {
    return Math.floor(Math.random() * arr.length);
  }
};

export default defineComponent({
  name: "App",
  components: {},
  setup(props) {
    const NumArr = ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
    const maxNum = ref(10);
    const add = () => {
      NumArr.value.splice(useGetRandomIdx(NumArr.value), 0, maxNum.value++);
    };
    const deleteNum = () => {
      NumArr.value.splice(useGetRandomIdx(NumArr.value), 1);
    };
    return {
      NumArr,
      add,
      deleteNum,
    };
  },
});
button {
  margin-right: 20px;
}
.list-item {
  margin-right: 10px;
}
.container-enter-active,
.container-leave-active {
  transition: opacity 1s ease;
}

.container-enter-from,
.container-leave-to {
  opacity: 0;
}
  • transtion-group 组件不仅可以进入和离开动画,还可以改变定位。改变定位时,周围的元素会瞬间移动到他们的新布局的位置,而不是平滑的过渡。解决这个问题,可以用 v-move (或者[name]-move)设置在改变位置时候的动画。(使用 FLIP 过渡的元素不能设置为 display: inline。可以放到 flex 里或者设置 display: inline-block)
<template>
  <button @click="shufer">shufer</button>
  <button @click="add">Add</button>
  <button @click="deleteItem">deleteItem</button>
  <transition-group name="container" tag="div">
    <span v-for="item in NumArr" :key="item" class="list-item">
      {{ item }}
    </span>
  </transition-group>

  <Child />
</template>
import { defineComponent, ref } from "vue";
import Child from "./components/HelloWorld.vue";
const useGetRandomIdx = (arr) => {
  if (Array.isArray(arr)) {
    return Math.floor(Math.random() * arr.length);
  }
};

export default defineComponent({
  name: "App",
  components: { Child },
  setup(props) {
    const NumArr = ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
    const max = ref(10);
    const shufer = () => {
      const idx = useGetRandomIdx(NumArr.value);
      const start = NumArr.value[idx];
      const end = NumArr.value[10 - idx];
      NumArr.value[idx] = end;
      NumArr.value[10 - idx] = start;
    };

    const add = () => {
      const idx = useGetRandomIdx(NumArr.value);
      NumArr.value.splice(idx, 0, max.value++);
    };

    const deleteItem = () => {
      const idx = useGetRandomIdx(NumArr.value);
      NumArr.value.splice(idx, 1);
    };
    return {
      NumArr,
      shufer,
      add,
      deleteItem,
    };
  },
});
button {
  margin-right: 20px;
}
.list-item {
  transition: all 0.8s ease;
  margin-right: 10px;
  display: inline-block;
}

.container-enter-from,
.container-leave-to {
  opacity: 0;
  transform: translateY(30px);
}

.container-leave-active {
  position: absolute;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值