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
tiddlersarray indata - Clear the properties
tempTextandtempTagsthat 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.