This article is published on the public account “Front-end Full Stack Developer”. The first time you read the latest article, the new article will be published in two days. Concern after the private message reply: gift package, send a network high-quality video course network disk data, can save a lot of money for you!
Vue.js is now a popular framework for front-end development. There are many engineers who take advantage of the convenience and power of vue.js. However, some of the solutions we accomplished may not follow best practices. Well, let’s take a look at some of the essential Vue technologies.
1. Function components
Function components are stateless, have no lifecycle or methods, and therefore cannot be instantiated
Creating a function component is easy. All you need to do is add a functional: true attribute to the SFC, or add functional to the template. Because it is lightweight as a function and has no instance references, rendering performance is improved considerably.
Function components depend on the context and mutate with the data given in it.
<template functional>
<div class="book">
{{props.book.name}} {{props.book.price}}
</div>
</template>
<script>
Vue.component('book', {
functional: true.props: {
book: {
type: () = > ({}),
required: true}},render: function (createElement, context) {
return createElement(
'div',
{
attrs: {
class: 'book'
}
},
[context.props.book]
)
}
})
</script>
Copy the code
2. Deep selector
Sometimes you need to modify the CSS of third-party components that are scoped, and removing scope or opening a new style is not possible.
Now, the deep selector >>> /deep/ :: V-deep can help you.
<style scoped>
>>> .scoped-third-party-class {
color: gray;
}
</style>
<style scoped>
/deep/ .scoped-third-party-class {
color: gray;
}
</style>
<style scoped>::v-deep .scoped-third-party-class { color: gray; }</style>
Copy the code
3. The senior “watcher”
Executed immediately
Related reading: Advanced use of watch in vue.js
The Watch Handler is triggered when a monitored prop mutates. Sometimes, however, it appears after the component has been created.
Yes, there is a simple solution: call the handler in a created hook, but that doesn’t look elegant and adds complexity.
Alternatively, you can add the immediate attribute to the observer:
watch: {
value: {
handler: 'printValue'.immediate: true}},methods : {
printValue () {
console.log(this.value)
}
}
Copy the code
The depth of the listening
Sometimes, the watch property is an object, but its property mutation does not trigger the Wacher handler. In this case, adding deep:true to the observer makes mutations in its properties detectable.
Note that when objects have multiple layers, deepness can cause some serious performance problems. It is best to consider using a flatter data structure.
data () {
return {
value: {
one: {
two: {
three: 3}}}}},watch: {
value: {
handler: 'printValue'.deep: true}},methods : {
printValue () {
console.log(this.value)
}
}
Copy the code
Multiple handlers
In fact, watch can be set as an array, and the supported types are String, Function, and Object. When triggered, each of the registered Watch handlers will be called.
watch: {
value: [
'printValue'.function (val, oldVal) {
console.log(val)
},
{
handler: 'printValue'.deep: true}},methods : {
printValue () {
console.log(this.value)
}
}
Copy the code
Subscribe to multiple variable mutations
Watcher cannot listen to multiple variables, but we can group the targets together as a new computed and monitor this new “variable”.
computed: {
multipleValues () {
return {
value1: this.value1,
value2: this.value2,
}
}
},
watch: {
multipleValues (val, oldVal) {
console.log(val)
}
}
Copy the code
4. Event parameter: $event
$event is a special variable of the event object. It provides more optional parameters for complex functionality in some scenarios.
Native events
In native events, this value is the same as the default event (DOM event or window event).
<template>
<input type="text" @input="handleInput('hello', $event)" />
</template>
<script>
export default {
methods: {
handleInput (val, e) {
console.log(e.target.value) // hello}}}</script>
Copy the code
Custom event
In a custom event, the value is captured from a child component.
<! -- Child -->
<template>
<input type="text" @input="$emit('custom-event', 'hello')" />
</template>
<! -- Parent -->
<template>
<Child @custom-event="handleCustomevent" />
</template>
<script>
export default {
methods: {
handleCustomevent (value) {
console.log(value) // hello}}}</script>
Copy the code
5. Router parameter decoupling
I believe this is how most people handle router parameters in components:
export default {
methods: {
getRouteParamsId() {
return this.$route.params.id
}
}
}
Copy the code
Using $route within a component creates a strong coupling to a URL, which limits the flexibility of the component.
The correct solution is to add props to the router.
const router = new VueRouter({
routes: [{
path: '/:id'.component: Component,
props: true}]})Copy the code
This way, the component can get params directly from props.
export default {
props: ['id'].methods: {
getParamsId() {
return this.id
}
}
}
Copy the code
In addition, you can pass in functions to return custom props.
const router = new VueRouter({
routes: [{
path: '/:id'.component: Component,
props: router= > ({ id: route.query.id })
}]
})
Copy the code
6. Customize bidirectional binding of components
Allows custom components to customize props and events when using the V-Model. By default, v-Models on components use value as an attribute and Input as an event, but some Input types, such as check boxes and radio buttons, may want to use the value attribute for different purposes. In this case, use the Model option to avoid conflicts.
V-models are known as bidirectional bindings. Input is the default update event. This value can be updated via $emit. The only limitation is that the component requires the tag to bind to the Value property.
<my-checkbox v-model="val"></my-checkbox>
<template>
<input type="checkbox" :value="value" @input="handleInputChange(value)" />
</template>
<script>
export default {
props: {
value: {
type: Boolean.default: false}},methods: {
handleInputChange (val) {
console.log(val)
}
}
}
</script>
Copy the code
Another solution for bidirectional binding is the sync modifier. Unlike v-Model, it does not require your component to have an tag and bind values to it. It just fires update:
to mutate the property through the event system.
<custom-component :value.sync="value" />
Copy the code
7. Component lifecycle Hook
In general, you can listen for the life cycle of a child component like this (e.g. Mounted)
<! -- Child -->
<script>
export default {
mounted () {
this.$emit('onMounted')}}</script>
<! -- Parent -->
<template>
<Child @onMounted="handleOnMounted" />
</template>
Copy the code
There is another simple solution, and you can use @hook: Mount in Vue’s internal system instead.
<! -- Parent -->
<template>
<Child @hook:mounted="handleOnMounted" />
</template>
Copy the code
8. Event listening APIs
For example, add a timer when the page is mounted, but remove the timer when the page is destroyed. That looks good.
Frankly, it only makes sense to use this.timer in beforeDestroy to get the timer ID. Not mean, but the fewer variables, the better the performance.
export default {
data () {
return {
timer: null
}
},
mounted () {
this.timer = setInterval(() = > {
console.log(Date.now())
}, 1000)
},
beforeDestroy () {
clearInterval(this.timer)
}
}
Copy the code
Make it accessible only from within the lifecycle hook. Use $once to give away unnecessary things.
export default {
mounted () {
let timer = null
timer = setInterval(() = > {
console.log(Date.now())
}, 1000)
this.$once('hook:beforeDestroy'.() = > {
clearInterval(timer)
})
}
}
Copy the code
9. Mount components programmatically
In some cases, it is much more elegant to load components programmatically. For example, a popup or modal window can be opened with the global context $popup() or $modal.open().
import Vue from 'vue'
import Popup from './popup'
const PopupCtor = Vue.extend(Popup)
const PopupIns = new PopupCtr()
PopupIns.$mount()
document.body.append(PopupIns.$el)
Vue.prototype.$popup = Vue.$popup = function () {
PopupIns.open()
}
Copy the code
The Element UI implements a well-structured pattern component that allows the use of custom apis to control the lifecycle of an instance. The theory is almost identical to what I demonstrated above.
Here are 9 techniques for Vue 2.x, and hopefully in this article you’ll have a better understanding of how to use the framework. If you think this article is great, please share it on other social networks.
Recommended reading
- 12 Vue.js development tips and Tricks for 2020
- 6 tips for writing better V-for loops in vue.js
- Advanced use of watch in vue.js
- How to replace Vue Mixins with Vue3 Composition API
- Extract and reuse logic in the Vue3 Composition API
- How do I build the same components in Vue2 and Vue3
- Vue 3 Tutorial (for Vue 2 users)
- Preliminary study on Vue Router in Vue3
- Vue skills | set elements in Vue3 fade when scrolling the view
- 10+ cool vue. js components, templates and demo examples
- Thought Experiment: How to make localStorage responsive in Vue?