Summarize the practical skills of vue knowledge system

Keywords: Vue Attribute Mobile Webpack

As one of the three front-end frameworks, vue is a necessary skill for front-end developers. So how to learn and master vue systematically? For this reason, I have made a simple summary of the knowledge system. Please forgive and correct the shortcomings. If you like, you can give me a little praise! This paper mainly describes some practical skills in the development of vue.

 

 

 

Related recommendations

Summarize the foundation of vue knowledge system

Summarize the use skills of several Vue router

Build a mobile H5 development template of Vue cli

Listening component life cycle

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

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

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

In addition, there is a very simple way. The child component does not need any processing. It only needs to listen through @ hook when the parent component references. The code is as follows:

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

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

Initial immediate execution of watch

Observe and respond to data changes on Vue instances. Similar to some data listening callbacks, callbacks are executed for subsequent operations whenever the monitored data changes.

But when you watch a variable, it will not be executed during initialization. As the following example, you need to call it manually when you create it.

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

The above method can be used, but it's troublesome. We can add immediate attribute, which will trigger automatically during initialization (no need to write created to call again). Then the above code can be simplified as follows:

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

watch has three parameters

  • handler: its value is a callback function. That is, the function to be executed when monitoring changes
  • deep: its value is true or false; confirm whether to listen in depth.
  • immediate: if the value is true or false, confirm whether to execute the handler's function with the current initial value

Route parameter change component not updated

The route parameters change when the pages of the same path jump, but the components do not have corresponding updates.

Reason: the main reason is that the access parameter is written in the created or mounted route hook function. When the route parameter changes, the life cycle will not be re executed.

Solution 1: watch monitoring route

watch: {
 // Method 1 / / monitor whether the route changes
  '$route' (to, from) { 
   if(to.query.id !== from.query.id){
			this.id = to.query.id;
			this.init();//Reload data
		}
  }
}
//Method 2: set the processing function when the path changes
watch: {
'$route': {
    handler: 'init',
    immediate: true
  }
}
//Copy code

Solution 2: in order to achieve this effect, you can add a different key to router view, so that even the public component will be recreated as long as the url changes.

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

Route lazy load

In Vue project, there are three ways to implement route loading on demand (route lazy loading):

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

// 2. es6 proposal import()
  const Home = () => import('path Route')

// 3. require.ensure() provided by webpack
	{
		path: '/home',
		name: 'Home',
		component: r => require.ensure([],() =>  r(require('path Route')), 'demo')
	}
//Copy 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 the page needs to import multiple components, the original writing method is:

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

In this way, a lot of repetitive code is written, which can be written by 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 code

Recursive component

  • Recursive component: the component can call itself recursively in its template, as long as the name component is set for the component.
  • However, it should be noted that a condition must be given to limit the quantity, otherwise an error will be thrown: max stack size exceeded
  • Component recursion is used to develop some independent components with unknown hierarchical relationships. For example: link selector and tree control
<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 to be called recursively within a component
  name: 'tree',
  data(){
    return {}
  },
  // Receive external incoming values
  props: {
     item: {
      type:Array,
      default: ()=>[]
    }
  }
}
</script>
//Copy code

Clear timer or event monitor

Because some pages in the project will inevitably encounter the need for timer or event monitoring. But when leaving the current page, if the timer is not cleared timely and reasonably, it will cause business logic confusion or even application stuck. In this case, it is necessary to clear timer event monitoring, that is, in the life cycle function of page unloading (closing), clear the timer.

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

Custom path alias

We can also add our own path alias in the basic configuration file

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

Then when we import components, we can write as follows:

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

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

Dynamically changing the style of dom

Reason: because the styles we write in the. vue file will be appended with scoped. In this way, the styles in the template dom can take effect, but the final style after taking effect is not the style name we wrote, but the encoded style. For example:

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

vue translates the code as follows, so the dom structure style we spliced in js will not take effect.

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

Solution: write the style you want to change in the non scoped style label.

Long list performance optimization

We should all know that vue will hijack the data through object.defineProperty to realize the view response to data changes. However, sometimes our components are pure data display without any change, so we don't need vue to hijack our data. In the case of large amount of data display, this can significantly reduce the time of component initialization.

Therefore, we can freeze an object through 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: {
    // None of the operations here can change the value of list
  }
}
//Copy code

In addition, it should be noted that only the value of list is frozen here, and references will not be frozen. When we need reactive data, we can assign a new value to list.

Content distribution (slot)

Slot slot is also an HTML template of a component. The display of this template is determined by the parent component. In fact, two core problems of a slot are pointed out here, which are display not display and how to display.

Default slot

There is also a list of slots and anonymous slots. There is no specific name for such slots. A component can only have one such slot.

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

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

Named slot

Anonymous slot has no name attribute, so it is called anonymous slot. Then, when the name attribute is added to a slot, it becomes a named slot. The named slot can appear N times in a component, in different locations, just using different name attributes to distinguish.

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

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

Scope slot

The scope slot can be either the default slot or the named slot. The difference is that the scope slot can bind data for the slot label so that its parent component can get the data of the 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>

<!-- Sub components child.vue -->
<template>
  <div class="child">
    <h1>This is a subcomponent</h1>
    <slot :user="user"></slot>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        user: {
          name: 'Xiao Zhao'
        }
      }
    }
  }
</script>
//Copy code

Recommended articles

Build a web pack project from scratch

Summarize several methods of optimizing Web pack

Summarize the methods of front end performance optimization

Several common JS recursive algorithms

Encapsulate a toast and dialog component and publish it to npm

One document read all front-end routes, back-end routes, single page applications, multi page applications

On the anti shake and throttling of JavaScript


Author: lzg9527
Link: https://juejin.im/post/5e5f0ef8518825490b6489a2
Source: Nuggets
The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.

Published 145 original articles, praised 1558, visited 8 million+
His message board follow

Posted by DeFacto on Tue, 03 Mar 2020 23:24:48 -0800