防止Vue中的DOM刷新

问题描述 投票:0回答:2

我正在尝试实现一个动画轮播,代码如下:

<template>
<div v-for="(slides, id)" v-if="id > middle_id - 2 || id < middle_id + 2">
<div :class="'slide'+id"><slide :key="id" :slide-data="slide" /></div>
</div>
</template>

幻灯片的数量是可变的,但只显示中间的 5 张。动画仅使用基于幻灯片编号的 css 动画。

如果我一次添加或删除一张幻灯片,则效果很好 - 现有的 dom 元素不会更改,只添加一张新幻灯片。但是,如果我在末尾添加一张幻灯片并同时从开头删除一张幻灯片,vue 似乎会重新渲染滑动窗口中的所有 dom 元素。

有没有办法保证在这个操作过程中,中间3张没有改变的slide不会在dom中更新?

javascript vue.js dom
2个回答
0
投票

Vue 3.2+

在 Vue 3.2 及更高版本中,可以使用

v-memo

来完成
<div v-memo="[valueA, valueB]">
  ...
</div>

当组件重新渲染时,如果 valueA 和 valueB 保持不变,则该组件及其子组件的所有更新都将被跳过。 事实上,甚至 Virtual DOM VNode 创建也将被跳过,因为子组件的记忆副本-树可以重复使用。

https://vuejs.org/api/built-in-directives.html#v-memo


0
投票

我在使用Vue实现轮播文本时遇到了类似的问题,我找到了有效解决该问题的解决方案。

Vue 在其源代码中采用了某些启发式方法来确定是否在不同场景下回收 DOM 元素。具体来说,Vue 在以下情况下不会回收 DOM 元素

  • 删除单个节点,或者
  • 添加单个节点,或者
  • 节点的属性被修改。

就您而言,当您一步添加和删除幻灯片时就会出现问题。当您添加一张幻灯片,然后在下一步中删除另一张幻灯片时,Vue 不会触发 DOM 元素的重新渲染。

Vue 异步更新 DOM,这意味着对数据的多次修改将被打包为一次,并且 DOM 只会更新一次。为了确保添加和删除幻灯片被视为单独的步骤,我发现利用

await Vue.nextTick()
(或
await this.$nextTick()
)是一种有效的方法。
await Vue.nextTick()
表示在 DOM 更新之前永远不要执行该行下面的代码。

要实现此解决方案,您可以按照下面提供的示例代码进行操作:

async function updateSlides() {
    // Add a new slide to the array
    this.arr.push({ ... })

    // Wait for the DOM update, ensuring separate steps
    await this.$nextTick()

    // Remove the first slide from the array
    this.arr.splice(0, 1)
}

通过遵循这种方法,您应该能够达到预期的结果并有效地解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.