This content originally appeared on Level Up Coding - Medium and was authored by Maxwell
1. Routing parameter decoupling
Generally using routing parameters within a component, most people would do the following.
export default {
methods: {
getParamsId() {
return this.$route.params.id
}
}
}
Using $route in a component results in a high degree of coupling with its corresponding routes, limiting the flexibility of the component by limiting it to certain URLs.
The correct approach is to decouple it via props
const router = new VueRouter({
routes: [{
path: /user/:id ,
component: User,
props: true
}]
})
After setting the props property of the route to true, the params parameter can be received within the component via props.
export default {
props: [ id ],
methods: {
getParamsId() {
return this.id
}
}
}
You can also return props via function mode.
const router = new VueRouter({
routes: [{
path: /user/:id ,
component: User,
props: (route) => ({
id: route.query.id
})
}]
})
2. Functional Component
Functional component is stateless, it cannot be instantiated and does not have any lifecycle or methods. Creating functional components is also simple, just add functional declarations to the template. It is generally suitable for components that depend only on changes in external data, and rendering performance is improved due to its light weight.
Everything the component needs is passed through the context parameter. It is a context object, see the documentation for the specific properties. Here props is an object that contains all the bound properties.
<template functional>
<div class="list">
<div class="item" v-for="item in props.list" :key="item.id" @click="props.itemClick(item)">
<p>{{item.title}}</p>
<p>{{item.content}}</p>
</div>
</div>
</template>
The parent component uses
<template>
<div>
<List :list="list" :itemClick="item => (currentItem = item)" />
</div>
</template>
import List from @/components/List.vue
export default {
components: {
List
},
data() {
return {
list: [{
title: title ,
content: content
}],
currentItem:
}
}
}
3. Style scoped
It is common to modify third-party component styles in development, but due to the style isolation of the scoped attribute, it may be necessary to remove the scoped or start another style. These practices have side effects (component style pollution, lack of elegance) and style penetration is used in the css preprocessor to take effect.
We can use >>> or /deep/ to solve this problem:
<style scoped>
Outer layer >>> .el-checkbox {
display: block;
font-size: 26px;
.el-checkbox__label {
font-size: 16px;
}
}
</style>
<style scoped>
/deep/ .el-checkbox {
display: block;
font-size: 26px;
.el-checkbox__label {
font-size: 16px;
}
}
</style>
4. Advanced use of watch
watch is triggered when the listener property changes, sometimes we want watch to be executed immediately after the component is created.
The way that might come to mind is to call it once in the create life cycle, but that’s not an elegant way to write it, so maybe we could use something like this.
export default {
data() {
return {
name: Joe
}
},
watch: {
name: {
handler: sayName ,
immediate: true
}
},
methods: {
sayName() {
console.log(this.name)
}
}
}
Deep Listening
When listening to an object, the watch cannot be triggered when the properties inside the object are changed, so we can set deep listening for it
export default {
data: {
studen: {
name: Joe ,
skill: {
run: {
speed: fast
}
}
}
},
watch: {
studen: {
handler: sayName ,
deep: true
}
},
methods: {
sayName() {
console.log(this.studen)
}
}
}
Triggering a listener to execute multiple methods
Using arrays you can set multiple, forms including strings, functions, objects.
export default {
data: {
name: Joe
},
watch: {
name: [
sayName1 ,
function(newVal, oldVal) {
this.sayName2()
},
{
handler: sayName3 ,
immaediate: true
}
]
},
methods: {
sayName1() {
console.log( sayName1==> , this.name)
},
sayName2() {
console.log( sayName2==> , this.name)
},
sayName3() {
console.log( sayName3==> , this.name)
}
}
}
5. watch listens to multiple variables
watch itself cannot listen to multiple variables. However, we can “listen to multiple variables” by returning an object with computed properties and then listening to that object.
export default {
data() {
return {
msg1: apple ,
msg2: banana
}
},
compouted: {
msgObj() {
const { msg1, msg2 } = this
return {
msg1,
msg2
}
}
},
watch: {
msgObj: {
handler(newVal, oldVal) {
if (newVal.msg1 != oldVal.msg1) {
console.log( msg1 is change )
}
if (newVal.msg2 != oldVal.msg2) {
console.log( msg2 is change )
}
},
deep: true
}
}
}
6. Event parameter $event
$event is a special variable of the event object, which in some scenarios gives us more available parameters to implement complex functions.
Native Events: behaves the same as the default event object in native events.
<template>
<div>
<input type="text" @input="inputHandler( hello , $event)" />
</div>
</template>
export default {
methods: {
inputHandler(msg, e) {
console.log(e.target.value)
}
}
}
Custom Events: Represented in custom events as capturing the value thrown from a child component.
export default {
methods: {
customEvent() {
this.$emit( custom-event , some value )
}
}
}
<template>
<div>
<my-item v-for="(item, index) in list" @custom-event="customEvent(index, $event)">
</my-list>
</div>
</template>
export default {
methods: {
customEvent(index, e) {
console.log(e) // some value
}
}
}
7. Programmatic event listeners
For example, defining a timer when a page is mounted requires clearing the timer when the page is destroyed. This doesn’t seem like a problem. But on closer inspection the only purpose of this.timer is to be able to fetch the timer number within beforeDestroy, and is otherwise useless.
export default {
mounted() {
this.timer = setInterval(() => {
console.log(Date.now())
}, 1000)
},
beforeDestroy() {
clearInterval(this.timer)
}
}
It is better to have only lifecycle hooks accessible to it if possible. This is not a serious problem, but it can be considered as clutter.
We can solve this problem by listening for page lifecycle destruction with $on or $once: the
export default {
mounted() {
this.creatInterval( hello )
this.creatInterval( world )
},
creatInterval(msg) {
let timer = setInterval(() => {
console.log(msg)
}, 1000)
this.$once( hook:beforeDestroy , function() {
clearInterval(timer)
})
}
}
With this method, even if we create multiple timers at the same time, it does not affect the effect. This is because they will be programmatically cleared autonomously after the page is destroyed.
8. Listening to component lifecycle
Usually we use $emit to listen to the component lifecycle and the parent component receives events for notification.
Sub-components
export default {
mounted() {
this.$emit( listenMounted )
}
}
Parent Component
<template>
<div>
<List @listenMounted="listenMounted" />
</div>
</template>
In fact, there is a simple way to use @hook to listen to the component lifecycle without making any changes within the component. Similarly, created, updated, etc. can also use this method.
<template>
<List @hook:mounted="listenMounted" />
</template>
8 Awesome Vue Development Tips was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding - Medium and was authored by Maxwell
Maxwell | Sciencx (2022-12-08T03:51:38+00:00) 8 Awesome Vue Development Tips. Retrieved from https://www.scien.cx/2022/12/08/8-awesome-vue-development-tips/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.