A small Vue.js app
Creating an object from stored data properties
My app can now store user input in its data
object, in the form of a text string (tempText
) and an array of strings representing tags (tempTags
).
Goal
I want to use the “Submit” button to store the tempText
and tempTags
properties into an object, and clear the UI to accept new input. Each object will be called a “tiddler,” which is intuitive if you’re a TiddlyWiki user, but can just as easily be thought of as a note or a todo item.
Groundwork
To prepare, I’ll add an empty tiddlers
array to data
, and attach a @click
listener/handler to the “Submit” button in the template
:
data: {
appTitle: 'List tiddlers by their `text` properties for now.',
tiddlers: [],
tempText: 'Texty text text. Semper ubi sub ubi',
tempTags: ['onetag', 'twotag', 'threetag', 'four']
},
<button id="submit-tiddler" @click="submitTiddler">Submit</button>
Now I have to write the submitTiddler()
method that the click handler invokes:
Breakdown
- Create the new object with properties from
data
- Push the new object onto the
tiddlers
array indata
- Clear the properties
tempText
andtempTags
that the UI displays in the text and tag entry elements
Once submitTiddler()
is written, I’ll edit the template
to display a list of all tiddlers in the tiddlers
array.
1. Create the object from tempText
and tempTags
data
properties
submitTiddler() {
var newTiddler = {
text: this.tempText,
tags: this.tempTags
}
}
I’ve given the newTiddler
object a text
property and a tags
property, and assigned them each a value from the Vue instance’s data
object.
2. Push the created object onto the tiddlers
array
submitTiddler() {
var newTiddler = {
text: this.tempText,
tags: this.tempTags
}
this.tiddlers.push(newTiddler)
}
3. Empty the tempText
and tempTags
properties
Now I want the UI cleared until the user types into the text or tag entry elements (or, in the future, loads a stored tiddler). On submitting a newTiddler
object, tempText
becomes an empty string, and tempTags
becomes an empty array:
submitTiddler() {
var newTiddler = {
text: this.tempText,
tags: this.tempTags
}
this.tiddlers.push(newTiddler)
this.tempText = ''
this.tempTags = []
}
Vue’s reactivity system then empties all UI elements that are bound to tempText
or items in tempTags
.
Tell the template to display a list of tiddlers
I can list the tiddlers in much the same way that I listed the tags in Displaying a list of tags from an array, using a v-for
loop. I’ll create the list items as buttons here too, because later I plan to use them to allow the user to select a tiddler.
In the case of tags in an array, it is fine to use the tag itself as the key
as I iterate over its items, because (a) it is a unique identifier, since I never want the same tag twice in the array, and (b) it is a primitive value.
The tiddler
objects themselves contain key-value pairs (not just values), so if I try v-bind:key="tiddler"
, Vue complains (in the browser console):
[Vue warn]: Avoid using non-primitive value as key, use string/number value instead.
This can be solved by referring to the value of some property of the tiddler
object, rather than the entire object. For now, I choose the tiddler
's text
property:
<div class="tiddler-buttons" v-for="tiddler in tiddlers" v-bind:key="tiddler.text">
<button class="button-tiddler-select">{{tiddler.text}}</button>
</div>
In the long run, I wouldn’t like to assume tiddler.text
is going to be a unique identifier, but since I haven’t added timestamps yet, I will use it for now.
Enter and submit a few random tiddlers to see them appear in the “Tiddler list”. They are removed on page reload.