Vue JS Practices – Vue 实战心得

By | 2018 年 6 月 25 日

For the recent project, used Vue as the frontend framework. Collected some useful information here for record.

Application Architect

It’s a good practice to follow the practice of decouple web site into components in Vue.

Vue has a principle of design that data flows in one way direction from parent component to children components. This is very helpful to build the clean app without complicated data flows. In code, the parent assign (using v-bind or : shorthand) lower level piece of data into child components.

But this widely spread data pieces caused another difficulty when data changes. It’s hard to track the changes among plenty of components. So, in my practice, I used a central place to hold the data and only allow mutations from there.

Vuex is a good plugin that serves this purpose very well. In my project, Vuex store holds all the data. The very top level component, acquired the top level data reference from Vuex store using the Vuex getters. Then for the child components, parent component assign (v-bind) lower level data pieces to them. So in that components tree, data flows from top level to lower levels in one way direction.

For mutations, each component can acquire the ability to modify the piece of data it holds, not directly, but by Vuex mutations / actions. Btw, Vuex actions are a-synchronized processes, and Vuex mutations are synchronized processes.

In this way, the modifications of data centralized in one place (Vuex store). Vuex also has a strict mode that will detect any changes from other than mutations. It’s very useful during the develop process that can make sure dev follows this clear pattern.

So, the Vuex store holds the data that used in multiple components. For the other data that only used in one or adjacent components (parent/child), I prefer to keep them local, either in the component it is used or in the parent node and assign to child component. e.g. some switches / status variables, like visible, extended, … etc.

Data flow

From parent component to child, the best way is using the props.

e.g.

Vue.component('blog-post', {
  // camelCase in JavaScript
  props: ['postTitle'],
  template: '<h3>{{ postTitle }}</h3>'
})
// in parent component
<blog-post post-title="hello!"></blog-post>

From child node to parent

one method is custom events

// in child node
this.$emit('myEvent')
// in parent
<my-component v-on:my-event="doSomething"></my-component>

With Vuex store

Another way is modifying the data from Vuex store in child node with Vuex mutations/actions. Because the parent node holds data references from data in Vuex store. The modification of that piece of data will then reflect automatically to the parent node.

passing callback function in prop

Also, we can pass callback function in prop to child node. So child node can call that callback function to notify parent node something happens. It is similar to custom events but better for wrapping some code directly instead of declare callback function in parent.

// in parent node
<child-component :someParams="someParams">

initiateChildComponent: function() {
  let that = this
  this.someParams = {
    aCallBack: function() {
      that.doSomething() // use that to capture the parent instance in the callback.
    }
  }
}
// in child node
whenNeedNotifyParent: function () {
  this.someParams.aCallBack()
}

Instance life cycle

Vue provides call backs for those in red boxes, with the exact functions names.

For example, when component created, if you have the following callback declared in the component, it will be triggered then:

created: function() { doSomething }

If you want execute some code after component has been rendered on page, sometime mounted is a good callback to use.

Some Vue

@ is shorthand for v-on:. e.g. @click is the same as v-on:click

: is shorthand for v-bind:. e.g. :someProp is the same as v-bind:someProp

Some JS

string.includes(substring) to check if a string has substring, this is useful for checking the className of a document element. Because a doc element may have several class, e.g. <div class="A B"> will has the className of value A B.

document.getElementById() or jQuery('#someid') or $('#someid') to capture a document node.

event.srcElement can get the element of event, in click or other system events.

delete Employee.firstname deletes key from JS object.

Object.assign(targetObj, sourceObj1, ... , sourceObjn) to merge sources into target object. It will return a new merged object and targetObj will also changed in this process. The new attributes will be added to targetObj and existing key will get value override.

{...obj1, ...obj2} returns a merged object from obj1 and obj2, and obj2 will override values of obj1.

array.splice(index, deletingCount, addingElements) to modify array, insert, delete, replace etc.

array.push, array.pop to manipulate array from the end.

var t=x[cur];x[cur]=x[cur-1];x[cur-1]=t; to swap elements in array efficiently.

array.indexOf(element) to get index of an element. -1 for not found.

[...array1, ...array2] to return merged array of both array1 and array2.

array1.concat(arrary2, ...., arrayn) to merge arrays into array1.

=== checks type and value, == checks value.

typeof(some_variable) !== "undefined" to check if something is undefined

`string text ${expression} string text` string interpolate.

throw "Parameter is not a number!" to throw exceptions in JS.

References

Vue official guide

QS – lib for format form payload for requests

发表评论

电子邮件地址不会被公开。 必填项已用*标注