2

I'm using Vue.js, and I want to hide the elements until after the call to the Vue constructor because otherwise, a bunch of curly braces get flashed to the user. I have the following:

HTML:

<div class="main hide-me" id="my-vue-element">
    <!-- stuff -->
</div>

CSS:

.hide-me {
    display: none !important;
}

JavaScript:

var myVueElement = document.getElementById("my-vue-element");

if (myVueElement) {
    var myApp = new Vue({
        el: myVueElement
      , data: {
            /* stuff */
        }
      , methods: {
            /* stuff */
        }
    });

    console.log(myVueElement);
    console.log(myVueElement.classList);
    myVueElement.classList.remove("hide-me");
    console.log(myVueElement.classList);
    console.log(myVueElement.getAttribute("class"));

The console output is:

DOMTokenList [ "main", "hide-me" ]
DOMTokenList [ "main" ]
main

However, the element does not appear, and using the DOM inspectors in Firefox and in Chrome shows the hide-me class is still there. I've tried to reproduce this using a simplified example but am unable to do so. I do have jQuery in this same project, and I found that using $("#my-vue-element").removeClass("hide-me"); (or even adding it after the above code) causes the class to be removed from the DOM. Any ideas? Thanks!

Becca Dee
  • 1,530
  • 1
  • 24
  • 51
  • 1
    Don't do that. Instead, use data-binding to add the class conditionally. – SLaks Jan 18 '19 at 18:30
  • 1
    honestly you probably want this: [v-cloak](https://vuejs.org/v2/api/#v-cloak). "this [v-cloak] directive can be used to hide un-compiled mustache bindings until the Vue instance is ready" – birdspider Jan 18 '19 at 18:54
  • @birdspider, would you mind making your comment an answer? – Becca Dee Jan 18 '19 at 19:35

2 Answers2

2

Direct DOM manipulation should be avoided in Vue. Instead, you should let Vue do it (it's quite good at it). So use

<your-element
  :class="['always-present', {'optional':expression}]"
/>

Where optional will be added/removed based on data-bound expression.

Additionally, you could use v-if, v-show or v-hide (i.e.: v-if="expression"), if all you want is to show/hide the element.


For a list of cases where direct DOM manipulation makes sense in Vue and each case's downside or potential pitfall, read Handling Edge Cases.

tony19
  • 125,647
  • 18
  • 229
  • 307
tao
  • 82,996
  • 16
  • 114
  • 150
0

If you utilize Vue views/components and their internal template code, the elements won't be rendered until Vue is ready.

Meaning inside of app.vue nothing shows up until the router loads the view

<template>
  <div id="app">
    <router-view/>
  </div>
</template>
Bryce Howitson
  • 7,339
  • 18
  • 40