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

问题描述 投票:1回答:1

我有一个旋转木马,只有当用户打开我的手风琴菜单时才会显示。

我使用v-show来隐藏旋转木马,直到它被打开。然而,除非我调整浏览器窗口的大小,否则它不会正确地显示旋转木马,第一张幻灯片会显示,但点击其他幻灯片不会显示。

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

我认为这与v-show和它在DOM中的渲染方式有关,我曾见过有人在使用 .$nextTick.$watch 来解决类似的问题,但我对它们的理解不够,无法将它们应用到我的代码中。

有没有办法让我使用v-show与 .nextTick().watch()?

<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>
javascript vue.js dom vuejs2
1个回答
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'));
},

但是... 脏兮兮 而且它也可能很贵,这取决于其他组件libraries正在听取 resize.

一个更好的解决方案是,不管是什么 update 的时候,你的旋转木马库会暴露出的方法。v-show 条件变化。如果你想不出如何做到这一点,我建议在问题中加入转盘库(带版本)。

另一个潜在的问题是,如果旋转木马的容器是动画的(即:你在它身上使用了某种类型的过渡)。在这种情况下,你需要触发 window.resizecarousel.update 在动画结束时,当容器有了正确的尺寸时,就会出现。这就是为什么如果能在动画结束时提供一个叫做 迷你型可复制范例. 对于这个问题,另一个快速和肮脏的解决方案是增加一个 transitionend 监听器,并在动画元素上调度 window.resize 的回调,这样的话,你就不再需要其他东西了。另外,实际上我还会在 v-show 只派 window.resize 当它 true. 但是,它又不是真的干净,它可能有副作用。


编辑:因为你用的是 vue-agile你的问题得到了回答 在文件中:

也可以使用 v-show,但你必须使用 reload() 方法。

这意味着这应该做到这一点。

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

...

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

一个工作实例 此处.


: 替换 v-showv-if 是一个昂贵的解决方案,因为这意味着每次条件改变时,你的旋转木马都会从DOM中添加和移除。每次它都会重建自己并重新加载滑块图像。这比 v-show + window.resize 解决办法。

:你可能想看一看。Swiper的vue包装器,因为(可以说)Swiper比Slick更好。

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