没有setTimeout的VueJS过渡不起作用

时间:2018-10-24 17:05:34

标签: javascript css3 vue.js css-transitions

我有一些代码可以滑出有效的菜单:

      Vue.set(this.filterStyles, filterIndex, {
        display: "block",
        height: "auto",
      });

      let filterValuesElHeight;
      Vue.nextTick().then(() => {
        let filterValuesEl = document.getElementById('parent-filter-values-' + filterIndex);
        filterValuesElHeight = filterValuesEl.clientHeight;

        Vue.set(this.filterStyles, filterIndex, {
          height: 0,
          display: "block"
        });

        return Vue.nextTick();
      }).then(() => {
        setTimeout(() => {
          Vue.set(this.filterStyles, filterIndex, {
            height: filterValuesElHeight + "px",
            display: "block"
          });
        }, 10);
      });

最初,菜单设置符合以下规则:

display: none;
height: 0;
transition: all 500ms;

第一个Vue.set将高度设置为自动,因此可以使用filterValuesEl.clientHeight来获取准确的高度

在下一个刻度上,高度返回到0,最后在最后一个刻度上,将其设置为自然高度。

但是,尽管我发现添加一个非常小的超时似乎可以完成工作,但Vue.nextTick()似乎还不够。这可行,但感觉很混乱。我希望有人可能有更好的解决方案?

1 个答案:

答案 0 :(得分:0)

我猜您正在模板中使用filterStyles,例如::style="filterStyles"。如果是这样,那么

Vue.set(this.filterStyles, filterIndex, {
    display: "block",
    height: "auto",
});

实际上不会立即将高度设置为auto。相反,它将更新组件的数据,并且该更新将在nextTick()之后反映在DOM中。因此,实际上,您的代码关闭了一个刻度。

一个接一个的堆叠一系列nextTick调用可能是一个坏习惯。例如,如果在序列化过程中删除了该组件,则会留下悬挂的参考。

您可以通过直接设置样式以测量其自然高度来避免所有这些问题。例如,如果元素具有ref="filter"属性,则类似于:

this.$refs.filter.style.height = "auto";
filterValuesElHeight = this.$refs.filter.clientHeight;
this.$refs.filter.style.height = "0";

您可能需要弄清楚模板与内联JavaScript之间的冲突(我不知道是因为您没有显示模板。),但这应该可以帮助您入门。