Vue.js Best Practices (five strokes to make you a vue.js master)

Source: Internet
Author: User
Tags emit event listener

For most people, having mastered Vue.js's basic API has been able to develop the front-end site normally. But if you want to use Vue more efficiently to develop and become master Vue.js, then the five strokes that I'm going to teach you must study hard.

The first trick: the Watchers of Simplicity

Scene Restore:

created(){    this.fetchPostList()},watch: {    searchInputValue(){        this.fetchPostList()    }}

When a component is created, we get a list and listen to the input box, and retrieve the filtered list whenever something changes. Is it common to have a way to optimize it?

Analysis of the moves:
First, in watchers, you can directly use the literal name of the function, and second, declare immediate:true to represent the component when it is created immediately.

watch: {    searchInputValue:{        handler: ‘fetchPostList‘,        immediate: true    }}
Second trick: Once and for all component registration

Scene Restore:

import BaseButton from ‘./baseButton‘import BaseIcon from ‘./baseIcon‘import BaseInput from ‘./baseInput‘export default {  components: {    BaseButton,    BaseIcon,    BaseInput  }}
<BaseInput  v-model="searchText"  @keydown.enter="search"/><BaseButton @click="search">  <BaseIcon name="search"/></BaseButton>

We wrote a bunch of basic UI components and then every time we needed to use them, we had to import them and declare the components, it's tedious! Uphold the principle of laziness to lazy, we have to find ways to optimize!

Analysis of the moves:
We need to use artifact Webpack to require.context() create our own (module) context using a method to implement an automatic dynamic require component. This method requires 3 parameters: The folder directory to be searched, whether it should also search its subdirectories, and a regular expression that matches the file.

We add a file called Global.js in the Components folder, and in this file we will pack all the necessary basic components with Webpack dynamics.

  import Vue  from  ' vue '   function  capitalizefirstletter (  string) { &NBSP  return  String.charat ( 0). toUpperCase () +  String.slice ( 1)}  const Requirecomponent =  Require.context (   '. ',  false, /\.vue$/  // Locate the files named. Vue under the Components folder Requirecomponent.keys (). ForEach (  fileName = = {   const Componentconfig = Requirecomponent (fileName)    Const COMPONENTNAME = capitalizefirstletter (    Filename.replace (/^\.\//,  "). Replace (/\.\w+$/, ")     //because the filename format you get is: './basebutton.vue ', so here we go to turn and tail, just keep the real filename  )  vue.component (componentname, Componentconfig.default | | Componentconfig)})               

Finally we are in the Main.js import ‘components/global.js‘ , and then we can use these basic components anywhere, without manual introduction.

The third trick: Drastic's router key

Scene Restore:
The following scenario really hurts a lot of programmers ' hearts ... First, the default is to use Vue-router to achieve the control of the route.
Suppose we are writing a blog site where the demand is from/post-page/a, jump to/post-page/b. Then we amazing found that the page after the data has not been updated?! The reason is that Vue-router "intelligently" discovers that this is the same component, and then it decides to reuse the component, so the method you write in the created function is not executed at all. The usual solution is to listen $route for changes to initialize the data, as follows:

data() {  return {    loading: false,    error: null,    post: null  }}, watch: {  ‘$route‘: {    handler: ‘resetData‘,    immediate: true  }},methods: {  resetData() {    this.loading = false    this.error = null    this.post = null    this.getPost(this.$route.params.id)  },  getPost(id){  }}

The bug is solved, but it's too elegant to write every time. With the principle of being lazy and lazy, we want the code to write:

data() {  return {    loading: false,    error: null,    post: null  }},created () {  this.getPost(this.$route.params.id)},methods () {  getPost(postId) {    // ...  }}

Analysis of the moves:

How to achieve this effect, the answer is to add a unique key to Router-view, so that even the common components, as long as the URL changes, it will be re-created this component. (The loss of a lost performance, but avoid the infinite bug). Also, note that I set the key directly to the full path of the route, double benefit.

<router-view :key="$route.fullpath"></router-view>
Four strokes: the Omnipotent render function

Scene Restore:
Vue requires that each component can have only one root element, and Vue will give you an error when you have multiple root elements.

<template>  <li    v-for="route in routes"    :key="route.name"  >    <router-link :to="route">      {{ route.title }}    </router-link>  </li></template> ERROR - Component template should contain exactly one root element.    If you are using v-if on multiple elements, use v-else-if    to chain them instead.

Analysis of the moves:
There is no way to resolve it, the answer is yes, only this time we need to use the render () function to create HTML, not template. In fact, the advantage of using JS to generate HTML is extremely flexible and powerful, and you do not need to learn the use of the Vue features of the limited command API, such as V-for, V-if. (Reactjs completely discarded the template)

true,render(h, { props }) {  return props.routes.map(route =>    <li key={route.name}>      <router-link to={route}>        {route.title}      </router-link>    </li>  )}
The high-level component of recruit without recruit

Key points: This is a powerful trick, be sure to master
When we write components, we usually need to pass a series of props to subcomponents from the parent component, while the parent component listens to a series of events emit the child component. Example:

//父组件<BaseInput     :value="value"    label="密码"     placeholder="请填写密码"    @input="handleInput"    @focus="handleFocus></BaseInput>//子组件<template>  <label>    {{ label }}    <input      :value="value"      :placeholder="placeholder"      @focus=$emit(‘focus‘, $event)"      @input="$emit(‘input‘, $event.target.value)"    >  </label></template>

There are several optimization points:

1. Every props that passes from a parent component to a subassembly, we have to explicitly declare it in the props of the subcomponent. In this way, our subcomponents each need to declare a lot of props, and similar to the placeholer of this dom native property we can actually directly from the parent to the child, no need to declare. Here's how:

    <input      :value="value"      v-bind="$attrs"      @input="$emit(‘input‘, $event.target.value)"    >   

$attrsContains attribute bindings (except class and style) that are not recognized (and obtained) in the parent scope as prop. When a component does not declare any prop, it contains bindings for all parent scopes and can be passed in to internal components through v-bind= "$attrs"--useful when creating higher-level components.

2. Notice that the sub-component @focus=$emit(‘focus‘, $event)" actually did nothing, just pass the event back to the parent component, which is actually similar to the above, I have absolutely no need to explicitly declare:

<input    :value="value"    v-bind="$attrs"    v-on="listeners">computed: {  listeners() {    return {      ...this.$listeners,      input: event =>        this.$emit(‘input‘, event.target.value)    }  }}

$listenersContains the V-on event listener in the parent scope (excluding the. Native decorator). It can be passed in to internal components via v-on= "$listeners"-useful when creating higher-level components.

3. It is important to note that since our input is not baseinput the root node of this component, the attribute bindings that are not considered props by default on the parent scope are "rolled back" and are applied as normal HTML attributes on the child component's root element. So we need to set inheritAttrs:false , these default behavior will be removed, the above two points of optimization to succeed.

Vue.js Best Practices (five strokes to make you a vue.js master)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.