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

  1. Create the new object with properties from data
  2. Push the new object onto the tiddlers array in data
  3. Clear the properties tempText and tempTags 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.