Seven useful Vue development techniques

Posted by The Eagle on Thu, 29 Aug 2019 17:11:29 +0200

1 state sharing

With the refinement of components, we will encounter the situation of multi-component state sharing. Vuex can certainly solve these problems, but as the official document of Vuex says, if the application is not large enough, in order to avoid code redundancy, it is better not to use it. Today we introduce the new addition of vue.js 2.6. Observable API By using this api, we can deal with some simple situations of data state sharing across components.

In the following example, we will create a store outside the component, and then use store and mutation methods provided by store.js in the App.vue component. Similarly, other components can also use this method, so that multiple components can share data state.

First, create a store.js, which contains a store and a mutations to point to data and processing methods, respectively.

import Vue from "vue";export const store = Vue.observable({ count: 0 });export const mutations = {
  setCount(count) {
    store.count = count;
  }
};

//Copy code

Then it introduces the store.js in App.vue and uses the introduced data and methods in the components.

<template>
  <div id="app">
    <img width="25%" src="./assets/logo.png">
    <p>count:{{count}}</p>
    <button @click="setCount(count+1)">+1</button>
    <button @click="setCount(count-1)">-1</button>
  </div></template><script>import { store, mutations } from "./store";export default {  name: "App",  computed: {
    count() {      return store.count;
    }
  },  methods: {    setCount: mutations.setCount
  }
};</script><style>Copy code

You can click Online DEMO View the final results

2-long list performance optimization

We should all know that vue hijacks data through object.defineProperty to achieve changes in view response to data. However, sometimes our components are pure data display, without any changes, we do not need vue to hijack our data. In the case of large amounts of data display, this can be done. It's obvious to reduce the time of component initialization, so how to prevent vue from hijacking our data? An object can be frozen through the object.freeze method, and once frozen, the object can no longer be modified.

export default {  data: () => ({    users: {}
  }),  async created() {    const users = await axios.get("/api/users");    this.users = Object.freeze(users);
  }
};
//Copy code

What's more, we just freeze the user's value here. References will not be frozen. When we need reactive data, we can reassign users.

export default {  data: () => ({    users: []
  }),  async created() {    const users = await axios.get("/api/users");    this.users = Object.freeze(users);
  },  methods:{    //Changed values do not trigger view responses
    this.users[0] = newValue    //Changing references still triggers view responses
    this.users = newArray
  }
};
//Copy code

3 Remove redundant patterns

With the project getting bigger and bigger, the writing is not careful, unnatural will produce some redundant css, small project is also good, once the project is bigger, the redundant CSS will be more and more, leading to the package growing, thus affecting the project performance, so it is necessary to remove these redundant CSS in the formal environment, recommended here. A Library purgecss Support CLI, Javascript Api, Webpack and other ways of using, through this library, we can easily remove the redundant css.

I did a test. Online DEMO

<h1>Hello Vanilla!</h1><div>
  We use Parcel to bundle this sandbox, you can find more info about Parcel  <a href="https://parceljs.org "target="_blank "rel="noopener noreferrer "> here </a>. </div> duplicate code
body {
  font-family: sans-serif;
}
a {
  color: red;
}
ul {
  li {    list-style: none;
  }
}
//Copy code
import Purgecss from "purgecss";const purgecss = new Purgecss({  content: ["**/*.html"],  css: ["**/*.css"]
});const purgec***esult = purgecss.purge();
//Copy code

The resulting purgec *** result is as follows, and you can see that the redundant a and ul tags are gone.

image.png

4 scope slot

It is interesting to make good use of scoping slots, such as defining a basic layout component A, which is only responsible for layout, regardless of data logic, and then defining another component B which is responsible for data processing. When layout component A needs data, it will go to B to fetch it. Assuming that one day our layout changes, we just need to modify Component A instead of Component B, so that we can fully reuse the data processing logic of Component B. Here See.

One of the most important points involved here is that the parent component is going to get the data in the child component, which used slot-scope to provide better API alternatives to support slot and slot-scope features since vue 2.6.0.

For example, we designate a component called current-user:

<span>
  <slot>{{ user.lastName }}</slot></span>Copy code

The parent component refers to the component of current-user, but wants to use a name instead of a name (the first word of a foreigner's name is a name, and the last word is a surname):

<current-user>
  {{ user.firstName }}</current-user>Copy code

This method will not work because user objects are the data of the child components, which we can not get in the parent components, at this time we can achieve through v-slot.

First, in the sub-component, the user is bound as a < slot > element feature:

<span>
  <slot v-bind:user="user">
    {{ user.lastName }}  </slot></span>Copy code

Later, we can define the name of the slot prop we provide by giving v-slot a value when the parent component references:

<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}  </template></current-user>Copy code

This method also has abbreviation grammar, you can see Abbreviation grammar for exclusive default slots In the end, we quote as follows:

<current-user v-slot="slotProps">
  {{ slotProps.user.firstName }}</current-user>Copy code

The slot-scope code is clearer and better understood than before.

5 Attribute Event Passing

Children's shoes that have written high-level components may encounter the situation of downward transmission of processed attributes. If they encounter more attributes, they need to transfer one by one, which is very unfriendly and time-consuming. Is there any one-time transmission (such as {... this.props} in react)? The answer is v-bind and v-on.

For example, if there is a basic component, BaseList, which only has the basic list display function, now we want to add sorting function on this basis, then we can create a higher-order component, SortList.

<!-- SortList  --><template>
  <BaseList v-bind="$props" v-on="$listeners"> <!-- ... --> </BaseList></template><script>
  import BaseList from "./BaseList";  //Including basic attribute definitions
  import BaseListMixin from "./BaseListMixin";  //Encapsulating the logic of sorting
  import sort from "./sort.js";  export default {    props: BaseListMixin.props,    components: {
      BaseList
    }
  };</script>Copy code

You can see the convenience of passing properties and events without passing them one by one.

6 Functional Components

Functional components, which are stateless, can not be instantiated, have no life cycle processing method inside, and are very lightweight. Therefore, they have high rendering performance. They are especially suitable for components that only depend on external data transfer.

Written as follows:

  1. Mark function in the template tag

  2. Accept only props values

  3. No script tag required

<!-- App.vue --><template>
  <div id="app">
    <List
      :items="['Wonderwoman', 'Ironman']"
      :item-click="item => (clicked = item)"
    />
    <p>Clicked hero: {{ clicked }}</p>
  </div></template><script>import List from "./List";export default {  name: "App",  data: () => ({ clicked: "" }),  components: { List }
};</script>Copy code
<!-- List.vue Functional components --><template functional>
  <div>
    <p v-for="item in props.items" @click="props.itemClick(item);">
      {{ item }}    </p>
  </div></template>Copy code

7 Monitoring Component Life Cycle

For example, there are Parent component and Child component. If the Parent component listens to mounted Child component, it will do some logical processing. The normal writing may be as follows:

// Parent.vue<Child @mounted="doSomething"/>// Child.vuemounted() {  this.$emit("mounted");
}
Copy code

This provides a particularly simple way for a child component to listen through @hook when the parent component references, without any processing. The code is rewritten as follows:

<Child@hook:mounted="doSomething"/>duplicate code

Of course, it is not only possible to monitor mounted events, but also other life cycle events, such as created, updated, etc. Is it particularly convenient?~


Topics: Javascript Vue axios Attribute