【问题标题】:Vue.js [v-cloak] does not use CSS transitionVue.js [v-cloak] 不使用 CSS 过渡
【发布时间】:2018-11-24 08:39:15
【问题描述】:

我的意图:

使用 Vue.js (v2) 属性 [v-cloak],我希望在准备好之前隐藏“应用程序”。当 [v-cloak] 被移除时,我希望“应用程序”淡入。使用 CSS 不透明度和过渡来实现淡入。

问题:

当 [v-cloak] 从我的“应用程序”中删除时,没有我期望的过渡。它只是立即从隐藏变为可见。似乎忽略了 CSS。

示例:

我用 Vue.js 和一个 JavaScript 模拟版本做了一个夸张的例子来展示它们的行为。

https://codepen.io/freemagee/pen/wXqrRM

查看此示例时,您将看到“Plain old JavaScript”红色框在 5 秒内逐渐消失。但是 Vue 控制的版本只是出现没有褪色。它们共享相同的 CSS 进行过渡,因此理论上应该以相同的方式工作。

有人有效地使用 [v-cloak] 来实现平滑过渡吗?

Codepen 代码

HTML

<div id="app" v-cloak>
  <div class="red-box"></div>
  <p>Vue.js {{ message }}</p>
</div>

<div id="app2" v-cloak>
  <div class="red-box"></div>
  <p>Plain old JavaScript</p>
</div>

CSS

html,
body {
  margin: 0;
  height: 100%;
  min-height: 100%;
}

[v-cloak] .red-box {
  opacity: 0;
  visibility: hidden;
  transition: visibility 0s 5s, opacity 5s linear;  
}

#app,
#app2{
  padding-top: 50px;
}

.red-box {
  margin: 0 auto;
  width: 100px;
  height: 100px;
  background: red;
  opacity: 1;
  visibility: visible;
  transition: opacity 5s linear;
}

p {
  text-align: center;
}

JS

new Vue({
  el: "#app",
  data: {
    message: "Hello world"
  }
});

window.setTimeout(function() {
  document.getElementById("app2").removeAttribute("v-cloak");
}, 500);

【问题讨论】:

  • v-cloak 是一个 vue 指令,生成的标记上应该没有它的迹象
  • 嗨@Vivick,到目前为止,我的经验是,如果我不手动将 v-cloak 添加到应用程序元素中,那么当 Vue 执行此操作时,您会看到类似内容的“车把”。我已经看到 Vue 使用 Chrome 网络检查器成功删除了 v-cloak 指令。但这不会触发 CSS 过渡淡入。我真的希望它会。我相信我的做法与文档 vuejs.org/v2/api/#v-cloak 相同
  • 也许这会有所帮助? jsfiddle.net/claudchan/u7x6vx1q

标签: javascript html css vue.js


【解决方案1】:

这行不通,因为在 Vue 应用实例初始化后,#app div 实际上被移除、重新渲染并变成了不同的 div,即使它看起来相同。这可能是由于 Vue 的虚拟 DOM 机制。

#app2 元素在 document.getElementById("app2").removeAttribute("v-cloak"); 之后仍然是同一个 DOM:https://codepen.io/jacobgoh101/pen/PaKQwV

#app 元素是 new Vue(...) 之后的不同 DOM:https://codepen.io/jacobgoh101/pen/ERvojx?editors=0010

对于 Vue 应用程序,带有v-cloak 的元素被删除,另一个没有v-cloak 的元素被添加回来。 没有元素可以从“有v-cloak”过渡到“没有v-cloak”。这就是CSS 过渡不起作用的原因。希望这已经足够清楚了。

(如果你还不知道这个,)你可以使用Transition Component

【讨论】:

  • 嗨@Jacob Goh,感谢您的回答。我一直在我的真实应用程序的其他部分中使用 元素,但就像你说的那样,也许我需要将所有内容包装在更高级别的 中。关于 v-cloak,我认为在底层发生了一些事情,因为 CSS 的基本规则没有按预期工作。很高兴知道我不会生气!
【解决方案2】:

如上所述,[v-cloak] 无法进行转换,因为没有 v-cloak 的 DOM 元素是一个新元素。

我想出了一个简单的解决方法,使用 mounted 方法及其钩子 vm.$nextTick(),在这种情况下,不再需要使用 v-cloak。

Mounted 是在原来的 app 元素被 Vue 生成的新元素替换后调用的,但这并不一定意味着每个子元素都已经渲染完毕。当每个子元素都已在应用视图中呈现时调用 nextTick。

首先,我已经像这样设置了我的 HTML 应用程序元素:

<div id="main-view" :class="{ready: isPageReady}">...</div>

在我的 vue 应用中:

new Vue({
    el: "#main-view",
    data: {
        isPageReady: false, 
    [...]
    mounted: function() {
        this.$nextTick(function () {
            this.isPageReady = true;
        });
    }
});

最后在 CSS 中,我尝试了一个使用 opacity 的简单淡入淡出:

#main-view {
    opacity: 0;
}
#main-view.ready {
    opacity: 1;
    transition: opacity 300ms ease-in-out;
}

注意:如果您打开了浏览器的检查器/调试器,过渡并不总是显示。

【讨论】:

  • 这与我所做的类似。我在主应用程序元素上有一个“isLoading”类(显示一个微调器)。然后,当应用程序像您一样安装时,我会更新 isLoading “值”(我的是计算值)。伟大的思想!
猜你喜欢
  • 2016-04-24
  • 2016-09-28
  • 2016-11-21
  • 1970-01-01
  • 2018-06-08
  • 2015-06-22
  • 2018-02-28
  • 2018-03-22
  • 2023-03-20
相关资源
最近更新 更多