我有一个轮播,仅在用户打开我的手风琴菜单时显示。
我正在使用v-show隐藏轮播,直到其打开为止。但是,除非我调整浏览器窗口的大小,否则它无法正确呈现轮播,第一张幻灯片会显示,但单击其他幻灯片不会显示出来。
网络检查会在加载时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
打开手风琴时显示。
<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>
编辑我最初是在注入一些手风琴,并且重构了手风琴和我的代码,因为我怀疑注入可能没有反应,但仍然存在相同的问题。这个问题的代码是我当前的代码。
<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>
答案 0 :(得分:2)
注意:将答案的这一部分保留下来,因为它可能对遇到类似问题的任何人有用。但是,当问题未指定滑块库时添加了它。要阅读实际答案,请跳到分隔符后。
v-show
表示轮播使用display: none
渲染init
版中设置幻灯片的大小,并在window.resize
上更新这意味着您的转盘正在init
上,高度为0
。而且,无论您的window.resize
元素的display
属性如何更改,它都只会在v-show
上重新调整。
一个快速而肮脏的解决方法是在控制window.resize
的属性发生更改时触发v-show
。即:
toggleItem: function () {
this.show = !this.show;
window.dispatchEvent(new Event('resize'));
},
但是 它很脏 ,并且它可能也很昂贵,具体取决于正在听resize
的其他组件/库。
更好的解决方案是在条件update
发生变化时调用轮播库公开的任何v-show
方法。
如果您不知道该怎么做,建议您在问题中添加轮播库(带有版本)。
另一个潜在的问题是轮播的容器是否具有动画效果(即:您在其上使用了某种过渡类型)。在这种情况下,当容器具有正确的大小时,您需要在动画结束时触发window.resize
/ carousel.update
。这就是为什么提供minmal reproducible example的理想选择。
一个快速而又肮脏的解决方案是在动画元素上添加一个transitionend
侦听器,并在该回调中分派window.resize
,在这种情况下,您不再需要其他任何东西。另外,我实际上会检查v-show
条件,仅在window.resize
时才分派true
。但是,同样,它不是真的很干净,并且可能会有副作用。
编辑:由于您使用的是vue-agile
,因此您的问题已回答in documentation:
也可以使用
v-show
,但是必须使用reload()
方法。
这意味着应该这样做:
<template>
<agile ref="slider" ... />
</template>
...
methods: {
toggleItem: function () {
this.show = !this.show;
this.$nextTick(() => this.$refs.slider.reload());
}
...
}
一个有效的示例here。
注意:用v-show
替换v-if
是一种昂贵的解决方案,因为这意味着您的轮播会在条件每次发生变化时都从DOM中添加和删除。每次它将重建自身并重新加载滑块图像。这比v-show
+ window.resize
解决方案还差。
注意:您可能想看看vue wrapper for Swiper,因为(可以说)Swiper比Slick更好。