200

maybe this is a trivial question.

so, when I run my vuejs application on browser with enables throttling download speed (sets to low connection). I got unfinished vue syntax output in browser.

Vue js syntax appear in browser

I know we can trick this out with showing loading image before entire page has loaded, but it's there any best solution to fix this?

Mridang Agarwalla
45.4k74 gold badges238 silver badges400 bronze badges
asked Mar 23, 2016 at 19:15

12 Answers 12

300

You can use the v-cloak directive, which will hide the Vue instance until the compilation finishes, if you combine it with the right CSS.

HTML:

<div v-cloak>{{ message }}</div>

CSS:

[v-cloak] { display: none; }
tony19
140k24 gold badges281 silver badges354 bronze badges
answered Mar 23, 2016 at 20:02
Sign up to request clarification or add additional context in comments.

8 Comments

in api says : [v-cloak] { display: none; } <div v-cloak> {{ message }} </div> it means, I should add v-cloak attribute in every element that I I wish to hide ?
Just to the main App div should be fine
This works but man it's clunky. I was really hoping for something more elegant. +1 though
Seems like v-cloak should be the default and that if someone really wanted to show the {{ }} they should use something like v-uncloak.
display:none on existing HTML, is a bad flag for SEO. I think it may be better to use some kind of overlay till page loads.
|
47

I attached the following codepen. You can see the difference with and without v-cloak.

<div id="js-app">
[regular]Hold it... <span>{{test}}</span><br/>
[cloak]Hold it... <span v-cloak>{{test}}</span>
</div>

http://codepen.io/gurghet/pen/PNLQwy

answered May 11, 2016 at 14:44

3 Comments

yeah I got it... thanks, your codepen would be help for the new comers.
you still get the first {{test}} whilst vuejs is loading so its not a perfect answer
@twigg That's the point. The first one shows regular tag and the second shows cloaked tag using the v-cloak attribute.
41

As suggested by others using v-cloak is proper solution. However as @ DelightedD0D mentioned it IS clunky. Simple solution is to add some CSS in the pseudo selector ::before of v-cloak directive.

In your sass/less file something along the lines of

[v-cloak] > * { display:none; }
[v-cloak]::before {
 content: " ";
 display: block;
 position: absolute;
 width: 80px;
 height: 80px;
 background-image: url(/images/svg/loader.svg);
 background-size: cover;
 left: 50%;
 top: 50%;
}

Of course you'd need to provide a valid and accessible path to loader image. It will render something like.

enter image description here

Hope it helps.

tony19
140k24 gold badges281 silver badges354 bronze badges
answered Jan 18, 2018 at 9:05

Comments

10

Using v-cloak directive you can hide un-compiled mustache bindings until vue instance is done compiling. You must use the CSS block to hide it until compiled.

HTML:

<div v-cloak>
 {{ vueVariable }}
</div>

CSS:

[v-cloak] {
 display: none;
}

This <div> will not be visible until the compilation is completed.

You can see this link Hide elements during loading using v-cloak for better understating.

answered Jun 25, 2018 at 15:30

Comments

8

Don't include any vuejs syntax in the HTML file:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8">
 <meta name="viewport" content="width=device-width,initial-scale=1.0">
 <title>My Super app</title>
 </head>
 <body>
 <div id="app"></div>
 <script src="/app.js"></script>
 </body>
</html>

In your main JavaScript, you can:

import Vue from 'vue'
import App from './App'
new Vue({
 el: '#app',
 components: { App },
 template: '<App/>'
})

See the vuetify webpack template for reference.

Another solution is to use:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8">
 <meta name="viewport" content="width=device-width,initial-scale=1.0">
 <title>My Super app</title>
 </head>
 <body>
 <div id="app" is="App"></div>
 <script src="/app.js"></script>
 </body>
</html>

With:

import Vue from 'vue'
import App from './App'
Vue.component("App", App);
const app = new Vue({});
window.addEventListener("load", async () => { 
 app.$mount("#app")
})
answered Aug 12, 2018 at 23:55

Comments

7

Putting everything inside a <template> worked well for me.

The content is hidden until rendered by Vue.

<!-- index.html -->
<div id="app">
 <template>
 <span class="name">{{ name.first }} {{ name.last }}</span>
 </template>
</div>
/* index.js */
new Vue({
 el: '#app',
 data: {
 name: { first: 'David', last: 'Davidovich'}
 }
});
answered Dec 29, 2020 at 9:37

Comments

6
**html**
<div v-cloak>{{ message }}</div>
**css**
[v-cloak] { display: none; }
answered Aug 2, 2018 at 11:02

Comments

5

Use <v-cloak> to hide your Vue code before binding data to relevant places. It's actually located in a place on Vue documentation that anyone might miss it unless you search for it or read thoroughly.

answered Apr 7, 2018 at 10:56

Comments

3

You could move any rendering to a simple wrapper component. The VueJS initialisation e.g. new Vue(....) shouldn’t contain any HTML apart from that single wrapper component.

Depending on setup you could even have <app>Loading...</app> where app is the wrapper component with any loading HTML or text in between which is then replaced on load.

tony19
140k24 gold badges281 silver badges354 bronze badges
answered Jan 8, 2018 at 6:54

Comments

2

Yep, you can use v-cloak, I like use spinkit, is a great library with only CSS, check a simple example:

var vm = null;
 setTimeout(function() {
 	vm = new Vue({
 el: '#app',
 data: {
 msg: 'Is great, using: ',
 url: 'http://tobiasahlin.com/spinkit/'
 }
 });
 }, 3000);
#app .sk-rotating-plane,
[v-cloak] > * { display:none }
body{
	background: #42b983;
	color: #35495e;
}
#app[v-cloak] .sk-rotating-plane {
	display:block;
	background-color: #35495e;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.rawgit.com/tobiasahlin/SpinKit/master/css/spinkit.css">
<div id="app" v-cloak>
 <div class="sk-rotating-plane"></div>
 <h1>Vue with c-cloak</h1>
 <p>
 {{ msg }}
 <a :href='url'>{{ url }}</a>
 <p>
</div>

Link: - http://tobiasahlin.com/spinkit/

answered Jun 5, 2018 at 18:25

Comments

0

For those who use v-cloak in a view with multiple Laravel Blade files and it's not working, try to use the v-cloak on the parent blade file rather than in any child blade file.

answered Aug 24, 2018 at 6:01

Comments

0

I prefer using v-if with a computed property that checks if my data is ready, like this:

<template>
 <div v-if="shouldDisplay">
 {{ variableName }}
 </div>
 <div v-else>
 Here you can insert a loader
 </div>
</template>
<script>
export default {
 name: 'Test',
 data() {
 return {
 variableName: null,
 };
 },
 computed() {
 shouldDisplay() {
 return this.variableName !== null;
 }
 },
 mounted() {
 this.variableName = 'yes';
 },
};
</script>

In this way it's easier to show a loader only if the data is not ready (using v-else).

In this particular case v-if="variableName" would work as well, but there can be more complicated scenarios.

answered Aug 13, 2019 at 9:18

1 Comment

That works for after the page script is loaded and vue is mounted. This is also a pre-compiled component. The OP was referring to a page that is compiled at runtime, which the browser loads the page first. And if your script is slow to load, then for a brief moment you see the vue syntax.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.