在渲染之前隐藏 vue.js 模板
Posted
技术标签:
【中文标题】在渲染之前隐藏 vue.js 模板【英文标题】:Hiding vue.js template before it is rendered 【发布时间】:2017-07-04 20:37:24 【问题描述】:我试图在完全呈现之前隐藏 vue.js 模板的内容。考虑以下模板:
<div class="loader">
<table class="hidden">
<tr v-for="log in logs">
<td>log.timestamp</td>
<td>log.event</td>
</tr>
</table>
</div>
当我在服务器上渲染此模板时,用户会在渲染之前看到<tr>
元素的内容。出于这个原因,我使用 hidden
类在它完全渲染之前隐藏它。
在渲染之前,我展示了一个带有动画进度条的加载器元素。
渲染完成后,我只需在 jQuery 中调用 element.show()
并同时隐藏进度条。我的问题是:可以混合使用 jQuery 和 vue.js 来实现这一点吗?
var vueLogs = new Vue(
el: "#checkInLogsHolder",
data: logs: []
);
var holder = $("#checkInLogsHolder");
function response(payload)
// hiding the loader animation
holder.find(".loader").remove();
// showing the rendered table
holder.find("table").show();
vueLogs.logs.unshift(payload);
有更好的方法吗?
【问题讨论】:
How do I hide the VueJS syntax while the page is loading?的可能重复 混合使用 jQuery 和 vue.js 并没有什么“错误”,尽管对于这是否是一个好主意,你会得到很多不同的意见。我这样做了,但因为我已经将它用于引导程序。 【参考方案1】:Vue已经内置了v-cloak
指令,你只需要添加相关的css类:
[v-cloak]
display: none;
然后像这样将它应用到你的元素:
<div v-cloak>
message
</div>
这是 JSFiddle:https://jsfiddle.net/2jbe82hq/
如果您在该小提琴中删除v-cloak
,您将在实例挂载之前看到带有胡子的message
。
如果您想在从服务器检索数据时显示loader
,那么您可以将布尔标志与v-if
结合起来以显示和隐藏加载程序:
var vm = new Vue(
el: "#app",
created()
this.$http.get('url').then(response =>
// set loader to false
this.loading = false;
);
,
data:
message: 'Hello Vue!',
loading: true
);
你可以这样做:
<div v-if="loading">
Loading...
</div>
<div v-else>
message
</div>
这是 JSFiddle:https://jsfiddle.net/fa70phLz/
也可以使用loading
类,然后使用v-bind:class
根据标志应用和删除类,如果你想用loader
覆盖整个页面,这很有用。
<div :class="'loading': loading"></div>
【讨论】:
【参考方案2】:我只是添加了 v-cloak 的一个有用的东西在渲染完整的 html 文件之前添加一个 spinner 并感谢 Adam 的 Gist - https://gist.github.com/adamwathan/3584d1904e4f4c36096f
在如果您想在加载页面之前添加微调器,可以阅读此内容 -
#app
中添加v-cloak
。
制作一个 div v-cloak--inline
,我们希望在呈现 HTML 页面之前显示它。
另一个 Div 将包含带有v-cloak--hidden
的整页。
必须添加此处给出的 css。
让我们编写代码 - 在母版页中,
<div id="app">
<div v-cloak>
<div class="v-cloak--inline"> <!-- Parts that will be visible before compiled your HTML -->
<i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i>
<span class="sr-only">Loading...</span>
</div>
<div class="v-cloak--hidden"> <!-- Parts that will be visible After compiled your HTML -->
<!-- Rest of the contents -->
@yield('content')
</div>
</div>
</div>
为 v-cloak 添加这些额外的 CSS。
[v-cloak] .v-cloak--block
display: block;
[v-cloak] .v-cloak--inline
display: inline;
[v-cloak] .v-cloak--inlineBlock
display: inline-block;
[v-cloak] .v-cloak--hidden
display: none;
[v-cloak] .v-cloak--invisible
visibility: hidden;
.v-cloak--block,
.v-cloak--inline,
.v-cloak--inlineBlock
display: none;
然后在编译 HTML 文件之前,将渲染一个微调器。编译后,微调器将隐藏。您可以在母版页中使用它。因此,每次加载新页面时,都会看到效果。
查看要点 - https://gist.github.com/adamwathan/3584d1904e4f4c36096f
【讨论】:
据我了解 v-cloak div 在这里除了隐藏[v-cloak] .v-cloak--invisible
的css规则之外没有任何作用这是因为一旦应用程序被主应用程序div的内容简单地替换为vue加载。基本上你可以做<div id="app">Loading...</div>
,它会有同样的效果。 v-cloak
在已经加载 vue 的组件中很有用【参考方案3】:
通过将 v-cloak 添加到整个页面根 div 将起作用
<div id="app">
<div v-cloak>
Hello name
</div>
</div>
<style>
[v-cloak]
display: none;
</style>
Hide elements during loading using "v-cloak"
【讨论】:
【参考方案4】:我不愿意在 Vue.js 代码中混合使用 jQuery,因为 Vue.js 提供了一套工具,通常可以消除对 jQuery 的需求。
由于您正在加载页面并显示进度条,因此您可以利用 Vue.js 生命周期挂钩:[created、mounted、beforeUpdate、updated 等]。
我要做的是创建一个包含进度条的小 div,然后创建一个包含实际内容的相邻元素以在加载后显示。在组件实例上设置数据,然后使用生命周期挂钩来切换显示。
<div v-if='loading'>
<div class='progress-bar'>
<!-- Loading bar markup here -->
</div>
</div>
<div v-else class='content'>
<table>
<!-- Content -->
<tr v-for="log in logs">
<td>log.timestamp</td>
<td>log.event</td>
</tr>
</table>
</div>
然后在模板的脚本部分:
export default
data()
return:
loading: true,
logs: [],
message: ''
;
,
methods:
fetchLogs()
// using vue-resource / ajax library like axios
this.$http.get('/api/logs').then((logs) =>
if (logs)
this.logs = logs;
setTimeout(() =>
this.loading = false;
, 1000);
else
this.message = 'No logs to display';
this.loading = false;
);
,
mounted()
this.fetchLogs();
;
使用此方法,您还可以将类绑定到元素以创建平滑的 CSS 过渡。
【讨论】:
【参考方案5】:我创建了一个纯 CSS 解决方案,基于 @Maniruzzaman Akask 解决方案。 (我的模板中没有安装很棒的字体,结果很酷;-)
步骤
1) 将 v-cloak 标签放在您的#app div 中(如上述答案中所建议的那样)
<div id="app">
<div v-cloak>
<div class="v-cloak--inline"> <!-- Parts that will be visible before compiled your HTML -->
<div class="spinner"></div> <!-- this is a cool spinner taken from spinKit -->
</div>
<div class="v-cloak--hidden">
<!-- Parts that will be visible After compiled your HTML -->
</div>
<footer>Content</footer> <!-- my footer is static, so I show it from the beginning -->
</div>
2) 使用来自https://tobiasahlin.com/spinkit/
3) 添加两个元素的 CSS
微调器的 CSS
.spinner
width: 40px;
height: 40px;
background-color: red;
margin: 400px auto;
-webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
animation: sk-rotateplane 1.2s infinite ease-in-out;
@-webkit-keyframes sk-rotateplane
0% -webkit-transform: perspective(120px)
50% -webkit-transform: perspective(120px) rotateY(180deg)
100% -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg)
@keyframes sk-rotateplane
0%
transform: perspective(120px) rotateX(0deg) rotateY(0deg);
-webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)
50%
transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
-webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)
100%
transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
-webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
v-cloak 的 CSS
[v-cloak] .v-cloak--block
display: block;
[v-cloak] .v-cloak--inline
display: inline;
[v-cloak] .v-cloak--inlineBlock
display: inline-block;
[v-cloak] .v-cloak--hidden
display: none;
[v-cloak] .v-cloak--invisible
visibility: hidden;
.v-cloak--block,
.v-cloak--inline,
.v-cloak--inlineBlock
display: none;
【讨论】:
【参考方案6】:v-cloak
除外。
您也可以使用v-text
属性。所以你不必在 CSS 中处理它。
【讨论】:
以上是关于在渲染之前隐藏 vue.js 模板的主要内容,如果未能解决你的问题,请参考以下文章