36

I want to be able to hide a div with Vue, with as little impact on performance as possible, since it's a couple of divs on the website that will be treated this way. How do I do this?

Hide div > Display it when clicking on another div: (Example (without Vue))

With Vue (not working)

html

<div id="app" v-on:click="seen = !seen" class="control">
    <p>click app</p>
</div>

<div v-if="seen" id="hide">
<p>hide me </p>
</div>

JavaScript

new Vue({
    el:'#hide',
    data:{
        seen: false
    }
})
6
  • 3
    Vue can't change things outside your app root Commented Feb 2, 2018 at 8:38
  • @Ferrybig You are right... I forgot to include the important part... Commented Feb 2, 2018 at 8:44
  • Vue cannot toggle the show/hide status of the root element, as vue needs to have at least 1 root element Commented Feb 2, 2018 at 8:45
  • @Ferrybig Ok, I get it, it's only possible to hide the elements within a div, but not the div itself. Commented Feb 2, 2018 at 8:47
  • No, you did not get it. Commented Feb 2, 2018 at 8:49

4 Answers 4

34

As @Ferrybig stated, Vue only has control over the element it's bound to and all of those child elements. Your hide element is outside the element bound to Vue (app) so Vue cannot change it.

With a slight change, your code works fine:

new Vue({
el:'#wrapper',
data:{
    seen: true
}
});
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="wrapper">
  <div id="app" v-on:click="seen = !seen" class="control">
      <p>click app</p>
  </div>
        
  <div v-if="seen" id="hide">
      <p>hide me </p>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

1 Comment

this solution is abit dangerous. Because with "v-if" the div element does not being rendering in the DOM. May be v-show is better.
18

I recommend either use "v-show" or ":class" for hiding component efficiently. I've had some weird situations, the v-show may cause the ag-grid component into bad data table however no problem when using ":class".

The template code could be:

<div v-show="seen" id="hide">
   <p>hide me </p>
</div>

Or

<div :class="{ hide: !seen }" id="hide">
   <p>hide me </p>
</div>

with CSS

.hide {
    visibility: hidden !important;
}

2 Comments

Is that .hide style defined by vue.js or do I have to do that in my css?
@BitTickler .hide is a css defined in your css file or if you want to only work locally, you can define in the specific .vue file.
10

You can use v-if-else or v-show, they work in different ways. v-if, v-else will attach/detach your HTML element to its root element. On the other hand, v-show will work with style="display:none;",

example: v-if, v-else

<body>
    <div id = 'app'>
        <button @click="show = !show">Click</button>
        <p v-if="show"> 
            v-if value of show is: {{show}}
        </p>
        <p v-else> 
            v-else value of show is: {{show}}
        </p>
    </div>
    <script>
        const app = new Vue({
            el:'#app',
            data: function(){
                return{
                    show: true
                }
            }
        });
    </script>
</body>

example v-show

<body>
    <div id = 'app'>
        <button @click="show = !show">Click</button>
        <p v-show="show"> 
            v-show works with style="display:none;"
        </p>

    </div>
    <script>
        const app = new Vue({
            el:'#app',
            data: function(){
                return{
                    show: true
                }
            }
        });
    </script>
</body>

Comments

4

An vue instance has its own scope.Only in its scope, it can control the element.You need to focus on the element which be mounted.And one instance, one root element.

4 Comments

Can you elaborate? Multiple instances are okay and if you have, say 2 instances, you can invoke setters from one instance to the other: methods... toggleViewX: function () { viewX.$data.isShow = !viewX.$data.isShow } ...}
While Vue's $data property allows direct access to the data within a component instance, it is not widely recommended for extensive use in practical development. Using the $data property to access data can make the code harder to maintain and introduce potential issues. You may use $refs, lift the state, or invoke the setter using some functions that are passed to the children. These methods align better with Vue's design principles and help improve code maintainability and extensibility. @BitTickler
And how do you do that if you have multiple app instances, which was the topic of my comment above? The same topic arises, btw, if the completion function of an e.g.. XMLHttpRequest is executed in a null environment.
I'm not quite sure what you mean. I saw your comment above, this is actually what v-show does, it will do it by directly modifying the display property of the element's inline style to none to not display the element. Also, please check out the Vue's documentation.

Your Answer

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.