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
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.