gpt4 book ai didi

javascript - 如何正确使用 v-show 渲染我的元素?

转载 作者:行者123 更新时间:2023-12-01 16:17:33 24 4
gpt4 key购买 nike

我有一个轮播,它只在用户打开 Accordion 菜单时显示。

我正在使用 v-show 隐藏轮播,直到它被打开。但是,除非我调整浏览器窗口的大小,否则它不会正确呈现轮播,第一张幻灯片显示但点击其他幻灯片不会显示。

Web inspect 在加载 translate: transform() 时显示幻灯片为空,直到调整浏览器窗口大小。

我认为这与 v-show 及其在 DOM 中的呈现方式有关,我看到有人使用 .$nextTick.$watch 来修复类似的问题,但我对它们的理解还不足以将它们应用到我的代码中。

有没有办法使用带有 .nextTick().watch() 的 v-show 来解决这个问题?

<div :key="project.id">
<!-- project header -->
<li
class="project accordion columns is-flex vcenter"
@click="toggleItem"
style="margin-left: 0; margin-right: 0;"
>
<h3 class="project-title column is-one-quarter">{{ project.Name }}</h3>
<h4 class="project-summary column is-two-thirds">
{{ project.Summary }}
</h4>
<span class="column is-one-half is-gapless project-icon">
<img
src="../static/SVG/Circle.svg"
alt="circle icon for branding & identity"
/>
</span>
</li>

我的隐藏内容在这里,它仅在使用 v-show 打开 Accordion 时显示。

<div class="showcase-content columns" v-show="show">
<p class="project-description column is-one-third">
{{ project.Description }}
</p>
<agile :fade="true">
<div
class="image-box column is-two-thirds"
v-for="image in project.image"
:key="image.url"
>
<img :src="buildImageUrl(image.url)" alt="" />
</div>
</agile>
</div>

编辑 我最初注入(inject)了一些我的 Accordion ,并重构了 Accordion 和我的代码,怀疑注入(inject)可能不是 react 性的,但同样的问题仍然存在。这道题的代码是我现在的代码。

<script>
export default {
name: 'ProjectItem',
data: function () {
return {
show: false,
}
},
props: ['project'],
methods: {
toggleItem: function () {
this.show = !this.show
},
buildImageUrl(image) {
if (!image) return '../static/images/SamB.png'
return `http://localhost:1337${image}`
},
},
}
</script>

最佳答案

注意:保留这部分答案,因为它可能对遇到类似问题的任何人都有用。但是,它是在问题未指定 slider 库时添加的。要阅读实际答案,请跳到分隔符之后

  • 使用 v-show 意味着轮播使用 display: none 呈现
  • 大多数轮播在 init 时设置幻灯片的大小,并在 window.resize 上更新

这意味着您的旋转木马 init-ing 的高度为 0。而且它只会在 window.resize 上重新调整,而不管 v-show 元素的 display 属性发生什么变化。

一个快速而肮脏的修复是在控制 v-show 的属性更改时触发 window.resize。即:

toggleItem: function () {
this.show = !this.show;
window.dispatchEvent(new Event('resize'));
},

但是它很脏而且它可能也很昂贵,这取决于其他组件/库正在监听什么resize

一个更好的解决方案是在 v-show 条件改变时调用轮播库公开的任何 update 方法。
如果您不知道该怎么做,我建议将轮播库(带版本)添加到问题中。

另一个潜在的问题是轮播的容器是否是动画的(即:您在其上使用某种类型的过渡)。在这种情况下,当容器具有正确的大小时,您需要在动画结束时触发 window.resize/carousel.update。这就是为什么最好提供 minmal reproducible example .
该问题的(另一个)快速而肮脏的解决方案是在动画元素上添加一个 transitionend 监听器并在该回调中调度 window.resize ,在这种情况下你没有不再需要其他任何东西。此外,我实际上会检查 v-show 条件,并且仅在 true 时分派(dispatch) window.resize。但是,同样,它并不是很干净,而且可能会产生副作用。


编辑:由于您使用vue-agile,这里是您的问题的答案in documentation :

It is also possible to use v-show, but you have to use the reload() method.

这意味着应该这样做:

<template>
<agile ref="slider" ... />
</template>

...

methods: {
toggleItem: function () {
this.show = !this.show;
this.$nextTick(() => this.$refs.slider.reload());
}
...
}

一个工作示例 here .


注意:用 v-if 替换 v-show 是一个昂贵的解决方案,因为这意味着您的轮播要从 DOM 中添加和删除每次情况发生变化。每次它都会自行重建并重新加载 slider 图像。这比 v-show + window.resize 解决方案更糟糕。

注意:您可能想看看 vue wrapper for Swiper ,因为(可以说)Swiper 比 Slick 好。

关于javascript - 如何正确使用 v-show 渲染我的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62161952/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com