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
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 hearddeep
: 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