I’ve recently been playing around with Vue. One of the things that I typically do when I’m learning some kind of front-end technology, is to work out how I might write a game in that technology – that usually tests the boundaries of what you can do. If you’re interested, this is a car game that I created in React.
Let’s start by having a look at what a bog standard “Hello World” app looks like in Vue:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Testing Vue</title> </head> <body> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> <div id="app"> <h1>{{ title }}</h1> </div> <script> new Vue({ el: '#app', data: { title: 'Hello World' } }); </script> </body> </html>
Another way that you can write that, would be like this:
<p v-text="testdata"></p>
This kind of synthax actually lets you bind any property, for example:
<h1 v-bind:title="testdata"></h1>
That’s pretty much the bit that I was looking for; if you can bind the title, then you can bind the style; for example:
<div v-bind:style="location">test</div>
Inside the data section, I can expose a location; for example:
new Vue({ el: '#app', data: { testdata: 'some data', location: 'width: 500px; height: 100px; left: 20px;border: 1px solid #000; position: absolute;' },
Okay, so now we’re binding the style to a piece of data, so can we now do something like this:
data: { testdata: 'some data', posx: 100, location: 'width: 500px; height: 100px; left:' + this.posx + 'px; border: 1px solid #000; position: absolute;' },
Unfortunately (or perhaps fortunately, I haven’t decided yet) not. Anything that changes needs to be in a separate section, called computed:
data: { testdata: 'some data', posx: 100 }, computed: { location: function() { return 'width:500px; height:100px; left:' + this.posx + 'px; border:1px solid #000; position: absolute;'; } },
We’re actually nearly there now; all that’s missing is the thing that actually updates the variable, and therefore moves the div across the screen. The next thing we come across is the mounted method – this is a lifecycle event for each component, so we’ll need that to initialise our timer; now we can do this:
methods: { init() { setInterval(this.moveObject, 10); }, moveObject() { this.posx += 1; } }, mounted() { this.init(); }
It’s not hugely exciting, I’ll grant you, but moving an object around a screen is the basis for any game. For completeness, here’s the full code:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Testing Vue</title> </head> <body> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> <div id="app"> <h1>{{ testdata }}</h1> <p v-text="testdata"></p> <div v-bind:style="location">test</div> </div> <script> new Vue({ el: '#app', data: { testdata: 'some data', posx: 100 }, computed: { location: function() { return 'width:500px;height:100px; left:' + this.posx + 'px;border:1px solid #000; position: absolute;'; } }, methods: { init() { setInterval(this.moveObject, 10); }, moveObject() { this.posx += 1; } }, mounted() { this.init(); } }); </script> </body> </html>
References
Vue.js Tutorial From Scratch – e01 – Introduction, Installation & Outputting Data