Vue.js Simple Tuts: Toggling

Tag: Vue.js 2.*

Toggling? Really?

I'm a database programmer whose "front-end" shift was to PHP. I'm glad to see the javascript community making so much forward progress these days - the reason there's a "Framework of the Month" has more to do with the dynamism of developers as they figure out the best way to move from jQuery to proper design patterns, in my opinion - but the fact is: I don't get this stuff very well yet. I need slow, clear steps. TODO apps are complicated. So yes - toggling.

Breaking the old jQuery DOM manipulation way of looking at things is hard to do. Where *is* the bloody `v-toggle` thingy? Let's back up.

<!-- index.html --> <div id="app"> <button>Open/Close</button> <span>Toggle info</span> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script> <script src='app.js'></script> <!-- app.js --> new Vue({ el: '#app' });

There's a simple starting point. By the way, I would make that `new Vue...` code into a snippet in your IDE - you'll be using that a lot. The Vue class is mounted to the div, but nothing else is set up. Obviously, what we are after is to make the span appear or disappear each time we click the button. There are actually two ways to do this. We can rely on CSS to change the display or we can actually add and remove the span element. Let's see those in action in Vue.js

<!-- change your index.html to this for a moment --> <span v-if="true">If true</span> <span v-if="false">If false</span> <span v-show="true">Show true</span> <span v-show="false">Show false</span>

Now, refresh your page and look at it in Firebug or your dev tools:

<span>If true</span> <span>If show</span> <span style="display: none;">If show</span>

You can see that the "if false" option *doesn't create the element*, whereas "show false" merely turns off the display. You can read more about the difference between `v-if` and `v-show` in the docs: v-if vs. v-show

Let's go back to the task at hand. We'll use the simpler `v-show` for the rest of this exercise. We saw above that setting `v-show` to true or false has the effect of using a `display:show/none`, so we can skip ahead a little bit. We just need to figure out how to trigger it on and off. Let's modify our index.html to this:

<button v-on:click='isOpen = !isOpen'>Open/Close</button> <span v-show="isOpen">Toggle info</span>

Now we're talking! This is easy! `isOpen` is just a variable that will be true or false. `v-on:click` is just new syntax for saying `onClick`. We click the button, it changes the boolean value, and ...nothing is happening. Hmmm...open our dev tools...

GOD, NO!!! IT'S SPITTING OUT RED OBFUSCATIONS ALL OVER THE PAGES!!!

'K, slow down. Read it. [Vue warn]: Property or method "isOpen" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.

That's simple. We just need a `var isOpen=false` somewhere, right? Or maybe a `data-is-open="false"`? Uhm...but how will I...

This is the bit I found hard to change in my thinking when I switched away from jQuery. To use an overly simplistic explanation that will probably get me in trouble with the real javascript programmers, think of the difference between jQuery and other js frameworks like this:

When the Button wants to talk to the Span, it doesn't shout, "Hey! Span! Open up!". Of course not. It talks to something else, which passes on the message. In jQuery, that's the DOM. Think of it as a container object built into your browser, if only to help us get through this analogy. In Vue.js (or React, Angular, etc) it must, instead, talk to the main Vue class you made.

That's it. That's the key to understanding Vue.js - we never, never shout. We always talk to the `Vue` class we instantiated.

"Yeah, but this is just a toggle. Spanny is right over..." No! We never, never shout. I know that is terribly simple, and a great deal of my problems in transitioning from jQuery came from my own "not being very quick off the mark", but I think if you drum that idea into your head, you can very quickly leave the jQuery mindset behind.

So, to make this work, let's add that `isOpen` variable. Right now, if our Button says, "Hey, Vue - could you go ask Spanny to change his 'isOpen' setting?" then Vue is going to answer, "Huh? isOpen? Huh?". Let's tell Vue what `isOpen` is:

new Vue({ el: '#app', data: { isOpen: false } });

There we go! No more error and the span toggles on and off. The last thing we could do is move that `isOpen = !isOpen` into a method.

<!-- in index.html --> <!-- I also switched v-on:click to the short form @click --> <button @click='toggle()'>Open/Close</button> <!-- in app.js --> new Vue({ el: '#app', data: { isOpen: false }, methods:{ toggle: function(){ this.isOpen = !this.isOpen } } });

Hope that helped!