As one of the top three front-end frameworks, VUE is an essential skill for front-end developers. So how to systematically learn and master VUE? To this end, I have made a simple summary of the knowledge system system, the shortcomings of the big guys please forgive and correct, if you like can point a small praise! This article focuses on some practical tips for vUE development.

Related to recommend

Summarize the basic introduction to vUE knowledge system
Summarize some tips for using vue-Router
Build a VUE-CLI mobile TERMINAL H5 development template

Listen for the life cycle of the component

If the Parent component listens to the mounted component, then the Parent component does some logical processing.

 // Parent.vue
<Child @mounted="doSomething"/>

// Child.vue
mounted() {
  this.$emit("mounted");
}
Copy the code

In addition, there is a very simple way, the child component does not need to do anything, just need to use @hook when the parent component refers to it, the code is as follows:

<Child @hook:mounted="doSomething" /> 
<Child @hook:updated="doSomething" />
Copy the code

Not only mounted can be monitored, but other lifecycle events, such as created and updated, can be monitored.

The initial execution of watch is immediate

Observe and respond to data changes on Vue instances. Similar to listening callbacks for some data, each time the listening data changes, the callback is executed for subsequent operations.

However, when watch is a variable, the initialization will not be performed. In the following example, you need to call it manually at created time.

created() {
  this.getList();
},
watch: {
  keyWord: 'getList',}Copy the code

This can be done, but it’s a bit cumbersome. We can add the immediate attribute, which is automatically triggered when created (instead of creating), and the code above can be simplified to:

watch: {
  keyWord: {
    handler: 'getList'.immediate: true}}Copy the code

Watch has three parameters

  • handler: the value is a callback function. That is, the function that should be executed when changes are heard
  • deep: the value is true or false; Make sure you’re listening in.
  • immediate: its value is true or false to verify that handler’s function is executed with the current initial value

Route parameter change component is not updated

Route parameters change when a page of the same path is redirected, but the component is not updated.

A created or Mounted hook function is used to obtain parameters. If route parameters change, the lifecycle is not reexecuted.

Solution 1: Watch listens for routes

watch: {
 // Method 1 // Listen for route changes
  '$route' (to, from) { 
   if(to.query.id ! = =from.query.id){
			this.id = to.query.id;
			this.init();// Reload the data}}}// Method 2 sets the handler for path changes
watch: {
'$route': {
    handler: 'init'.immediate: true}}Copy the code

Solution 2: To achieve this effect, add a different key to the router-view so that even if it is a common component, the component will be recreated whenever the URL changes.

<router-view :key="$route.fullpath"></router-view>
Copy the code

Route lazy loading

There are 3 ways to implement route loading on demand (lazy route loading) in Vue project:

// 1. Vue asynchronous component technology:
	{
		path: '/home'.name: 'Home'.component: resolve= > reqire(['the path path'], resolve)
  }

// 2. Es6 proposal import()
  const Home = () = > import('the path path')

// ensure()
	{
		path: '/home'.name: 'Home'.component: r= > require.ensure([],() = >  r(require('the path path')), 'demo')}Copy the code

require.context()

require.context(directory,useSubdirectories,regExp)

  • Directory: indicates the directory to be retrieved
  • UseSubdirectories: Whether to retrieve subdirectories
  • RegExp: A regular expression that matches a file, usually the file name

Scenario: If a page needs to import multiple components, the original writing is:

import titleCom from '@/components/home/titleCom'
import bannerCom from '@/components/home/bannerCom'
import cellCom from '@/components/home/cellCom'
components: {
  titleCom, bannerCom, cellCom
}
Copy the code

This is a lot of repetitive code, which can be written using require.context

const path = require('path')
const files = require.context('@/components/home'.false./\.vue$/)
const modules = {}
files.keys().forEach(key= > {
  const name = path.basename(key, '.vue')
  modules[name] = files(key).default || files(key)
})
components: modules
Copy the code

Recursive components

  • Recursive components: A component can recursively call itself within its template by setting the name component to the component.
  • Note, however, that you must give a condition to limit the number, otherwise an error will be raised: Max Stack Size exceeded
  • Component recursion is used to develop independent components that have an unknown hierarchy. Examples include cascading selectors and tree controls
<template>
  <div v-for="(item,index) in treeArr"> {{index}} <br/>
      <tree :item="item.arr" v-if="item.flag"></tree>
  </div>
</template>
<script>
export default {
  // Name must be defined for recursive calls within the component
  name: 'tree'.data(){
    return{}},// Receives the value passed in externally
  props: {
     item: {
      type:Array.default: () = >[]}}}</script>
Copy the code

Clear timer or event listener

Because some pages in the project will inevitably encounter the need for timers or event listeners. However, when leaving the current page, if the timer is not cleared reasonably in time, it will cause business logic chaos and even application stuck. At this time, it is necessary to clear the timer event listening, that is, in the page uninstall (closed) life cycle function, clear the timer.

methods:{
  resizeFun () {
    this.tableHeight = window.innerHeight - document.getElementById('table').offsetTop - 128
  },
  setTimer() {
    this.timer = setInterval(() = >{})},clearTimer() {// Clear the timer
		clearInterval(this.timer)
    this.timer = null}},mounted() {
  this.setTimer()
  window.addEventListener('resize'.this.resizeFun)
},
beforeDestroy() {
  window.removeEventListener('resize'.this.resizeFun)
  this.clearTimer()
}
Copy the code

Custom path alias

We can also add our own path alias to the base configuration file

resolve: {
    extensions: ['.js'.'.vue'.'.json'].alias: {
      'vue$': 'vue/dist/vue.esm.js'.The '@': resolve('src'),
      'assets': resolve('src/assets')}}Copy the code

Then when we import the component, we can write:

// import YourComponent from '/src/assets/YourComponent'
import YourComponent from 'assets/YourComponent'
Copy the code

This not only solves the problem of too long path, but also solves the problem of relative path.

Style the DOM dynamically

Reason: Because we append scoped to styles in.vue files. This works for styles in the template DOM, but the final style is not the style name we wrote, but the encoded one. Such as:

<template>
  <div class="box">dom</div>
</template>
<style lang="scss" scoped>
  .box {
    background: red;
  }
</style>
Copy the code

Vue translates the code as follows, so the DOM structure style we have in js concatenation does not take effect.

.box[data-v-11c6864c]{ background:red; }
<template>
  <div class="box" data-v-11c6864c>dom</div>
</template>
Copy the code

Solution: Write the style you want to change in a non-scoped style tag.

Long list performance optimization

We all know that Vue hijacks data via Object.defineProperty to make the view respond to data changes. However, sometimes our component is purely a data presentation and nothing changes. We don’t need vue to hijack our data. This can significantly reduce component initialization time.

So, we can freeze an object with the object.freeze method. Once the object is frozen, vue will not hijack the data.

export default {
  data: () = > ({
    list: []}),async created() {
    const list = await axios.get('xxxx')
    this.list = Object.freeze(list)
  },
  methods: {
    // Nothing done here can change the value of list}}Copy the code

The reference is not frozen. When we need reactive data, we can reassign values to the list.

Content Distribution (Slot)

Slots slots, also a component’s HTML template, are displayed or not, and how they are displayed is up to the parent component. In fact, the two core issues of a slot are highlighted here: whether to display and how to display.

The default slot

This type of slot does not have a specific name. A component can only have one such slot.

<! -- Parent component parent-vue -->
<template>
  <div class="parent">
    <h1>The parent container</h1>
    <child>
      <div class="tmpl">
        <span>1 the menu</span>
      </div>
    </child>
  </div>
</template>

<! -- Child.vue -->
<template>
  <div class="child">
    <h1>Child components</h1>
    <slot></slot>
  </div>
</template>
Copy the code

A named slot

An anonymous slot is called an anonymous slot because it does not have a name attribute. Then, the slot becomes a named slot by adding the name attribute. A named slot can appear N times in a component, in different locations, with different name attributes.

<! -- Parent component parent-vue -->
<template>
  <div class="parent">
    <h1>The parent container</h1>
    <child>
      <div class="tmpl" slot="up">
        <span>The menu up 1</span>
      </div>
      <div class="tmpl" slot="down">
        <span>The menu down - 1</span>
      </div>
      <div class="tmpl">
        <span>Menu - > 1</span>
      </div>
    </child>
  </div>
</template>

<! -- Child.vue -->
<template>
  <div class="child">
    <! -- named slot -->
    <slot name="up"></slot>
    <h3>Here are the child components</h3>
    <! -- named slot -->
    <slot name="down"></slot>
    <! -- Anonymous slot -->
    <slot></slot>
  </div>
</template>
Copy the code

Scope slot

A scoped slot can be either a default slot or a named slot. The difference is that a scoped slot can bind data to a slot label so that its parent component can get data from a child component.

<! -- parent.vue -->
<template>
  <div class="parent">
    <h1>This is the parent component</h1>
    <child
      >>
      <template slot="default" slot-scope="slotProps">
        {{ slotProps.user.name }}
      </template> </child
    >>
  </div>
</template>

<! -- Child.vue -->
<template>
  <div class="child">
    <h1>This is the child component</h1>
    <slot :user="user"></slot>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        user: {
          name: 'xiao zhao'}}}}</script>
Copy the code

Recommend the article

Build a WebPack project from scratch
Summary of several webpack optimization methods
Summarize the methods of front-end performance optimization
Several common JS recursive algorithms
Encapsulate a TOAST and Dialog component and publish it to NPM
This article covers front-end routing, back-end routing, single-page application, multi-page application
Discussion on JavaScript anti – shake and throttling