记录编码每一个细节

Element Plus中el-tabs左右滑动动画的实现

问题:使用Transition,TransitionGroup解决不了时,可以使用以下方式:

<template>
  <el-tabs v-model="activeName" class="demo-tabs" @tab-click="tabClick">
    <el-tab-pane label="User" name="first" :class="tabContentClass">
      <A></A>
    </el-tab-pane>
    <el-tab-pane label="Config" name="second" :class="tabContentClass">
      <B></B>
    </el-tab-pane>
    <el-tab-pane label="Role" name="third" :class="tabContentClass">
      <C></C>
    </el-tab-pane>
  </el-tabs>
</template>
<script setup>
import { ref, reactive, markRaw, nextTick, computed } from 'vue'
import A from '@/views/pageTest/components/A.vue'
import B from '@/views/pageTest/components/B.vue'
import C from '@/views/pageTest/components/C.vue'
const activeName = ref('first')
const activeObj = reactive({
  preIndex: 0,
  curIndex: 0,
})
function tabClick(tab) {
  activeObj.preIndex = Number(activeObj.curIndex)
  activeObj.curIndex = Number(tab.index)

  //使用nextTick并不会失效,因为切换执行速度太快,反应不及
  // nextTick(() => {
  //   console.log('更新了...')
  //   activeObj.preIndex = Number(activeObj.curIndex)

  // })
  //小技巧:使用延迟执行函数解决,迟一点再改变值
  setTimeout(() => {
    activeObj.preIndex = Number(activeObj.curIndex)
  }, 200)
}
const tabContentClass = computed(() => {
  return {
    'slide-enter-active': true,
    'slide-leave-active': activeObj.curIndex > activeObj.preIndex,
    'slide-enter': activeObj.curIndex < activeObj.preIndex,
    'slide-leave-to': activeObj.curIndex > activeObj.preIndex,
  }
})
</script>

<style scoped>
.slide-enter-active,
.slide-leave-active {
  transition: all 0.5s;
}
.slide-enter {
  transform: translateX(100%);
  opacity: 0;
}
.slide-leave-to {
  transform: translateX(-100%);
  opacity: 0;
}
</style>

在这里插入图片描述


vue使用<TransitionGroup>对列表项使用过渡动画,效果只会作用在最后一个元素的问题

原因:v-for没有使用 :key 绑定,自然不知道对那个元素使用动画效果
解决:绑定 :key 即可

在 Vue 3 中,原生的 Vue 响应式系统并不直接支持监听 DOM 元素的宽度和高度变化,因为这些属性不是 Vue 的响应式依赖。

使用 ResizeObserver
ResizeObserver 是一个内置的浏览器 API,用于异步观察元素尺寸的变化。这是一个更现代且可靠的方法来监听元素的尺寸变化。

<template>
  <el-button @click="addHeight">加高+</el-button>
  <div ref="resizableElement" class="resizable">
    <!-- Your content here -->
  </div>
</template>

<script>
import { ref, onMounted, onUnmounted } from 'vue'

export default {
  setup() {
    const resizableElement = ref(null)

    const handleResize = (entries) => {
      for (let entry of entries) {
        const { width, height } = entry.contentRect
        console.log(`Element size is ${width}px wide x ${height}px tall`)
        // 在这里你可以将新的宽度和高度设置为 Vue 的响应式数据
      }
    }
    // 创建一个 ResizeObserver 实例
    const resizeObserver = new ResizeObserver(handleResize)

    onMounted(() => {
      if (resizableElement.value) {
        resizeObserver.observe(resizableElement.value)
      }
    })

    onUnmounted(() => {
      if (resizableElement.value) {
        resizeObserver.unobserve(resizableElement.value)
      }
    })
    let cur = 0
    const addHeight = () => {
      cur += 10
      resizableElement.value.style.height = 100 + cur + 'px'
      resizableElement.value.style.width = 100 + cur + 'px'
    }
    return {
      resizableElement,
      addHeight,
    }
  },
}
</script>

<style scoped>
.resizable {
  width: 100px;
  height: 100px;
  border: 1px solid black;
}
</style>

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦境之冢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值