As the hottest front-end framework recently, Vue's simple way of getting started and powerful APIs are its advantages. At the same time, because of the diversity and richness of its APIs, many of its development methods are different from all component-based React. If you do not have a comprehensive understanding of Vue's API (some of which are not even mentioned in the documentation), you may go around a big circle when developing and designing a component. So I highly recommend that you first have an understanding of all the APIs in Vue when learning Vue.
For example, notification component notification is basically a standard configuration for modern web development and can be used in many places. In the front-end project with Vue as the core framework, since Vue itself is a componentized and virtual Dom framework, it is of course very simple to implement the display of a notification component. However, due to the usage characteristics of notification components, it is obviously inconvenient to write components directly in the template and control the display of notification components through v-show or props. Moreover, if notifications are to be used in action or other non-component scenarios, the usage of pure component mode cannot be achieved. So is there a way to use the Vue componentization feature to facilitate the display of a notification component, and to display notifications through a simple method call? This article is about this implementation method.
Target
Implement a Vue notification component that can be called directly within the component
Calling the notification component through method calls, such as Vue.$notify({...options})
Combining the above two methods, reuse the code
Implement notification components
This step is very simple. I believe that students who have done some Vue development can write a decent notification component. I won't go into details here, just add the code.
<template> <transition name="fade" @after-leave="afterLeave" @after-enter="setHeight"> <div v-show="visible" :class="['notification']" :style="style" @mouseenter="clearTimer" @mouseleave="createTimer" > <span class="content">{{content}}</span> <a class="btn" @click="handleClose">{{btn || 'closure'}}</a> </div> </transition> </template> <script> export default { name: 'Notification', props: { content: { type: String, default: '' }, btn: { type: String, default: '' } }, data () { return { visible: true } }, computed: { style () { return {} } }, methods: { handleClose (e) { () () }, doClose () { = false this.$emit('close') }, afterLeave () { this.$emit('closed') }, clearTimer () {}, createTimer () {}, setHeight () {} } } </script>
<style lang="stylus" scoped> .notification display: flex background-color #303030 color rgba(255, 255, 255, 1) align-items center padding 20px position fixed min-width 280px box-shadow 0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 18px 0px rgba(0, 0, 0, 0.12) flex-wrap wrap transition all .3s .content padding 0 .btn color #ff4081 padding-left 24px margin-left auto cursor pointer </style>
It should be noted here that we have defined a computed property called style, three methods, clearTimer, createTimer, and setHeight, but their content is all empty. Although it is useful on the template, it seems meaningless. When we want to extend the component later, I will talk about why we do this.
After creating this component, we can use <notification btn="xxx" content="xxx" /> in the template
Implement the notification component by calling the method
Inheriting components
Before implementing method calls, we need to extend this component, because these properties alone are not enough for us to use. When using method calls, we need to consider several issues:
- Display notification positioning
- Control of the occurrence and automatic disappearance of components
- How to type multiple notifications in succession
Under this premise, we need to extend the component, but these properties of the extension cannot be placed directly in the original component, because these may affect the use of the component in the template. What should we do? At this time, we need to use a very useful API in Vue, extend, and use it to inherit the properties of the original component and extend it.
Let’s look at the code first and create a file called, with the following content:
import Notification from './' export default { extends: Notification, computed: { style () { return { position: 'fixed', right: '20px', bottom: `${ + 20}px` } } }, data () { return { verticalOffset: 0, visible: false, height: 0, autoClose: 3000 } }, mounted () { () }, methods: { createTimer () { if () { = setTimeout(() => { () }, ) } }, clearTimer () { if () { clearTimeout() } }, setHeight () { = this.$ } } }
We can see that several methods that were previously implemented were implemented here, so why should we add the definition of those methods on the original component? Because it needs to be bound on the template, and the template cannot be extended, it can only be overwritten. If you want to overwrite and re-implement, the significance of the extension is not very big. Of course, students can make their own choices.
Pay attention to the following two points when using extend:
- Methods and attribute definitions are directly overridden
- The life cycle method is similar to Yumixin, and will be merged, that is, the original component and the inherited component will be called, and the original component will be called first.
Call this component through a method
Finally, what we need to do is to call this inherited component through the method. Let’s first look at the implementation of the source code:
// import Vue from 'vue' import Component from './fun-component' const NotificationConstructor = (Component) const instances = [] let seed = 1 const removeInstance = (instance) => { const len = if (!instance) return const index = (inst => === ) (index, 1) if (len <= 1) return const removedHeight = for (let i = index; i < len - 1; i++) { instances[i].verticalOffset = parseInt(instances[i].verticalOffset) - removedHeight - 16 } } const notify = function (options) { const { onClose, ...rest } = options if (.$isServer) return options = options || {} const id = `notification_${seed++}` const instance = new NotificationConstructor({ propsData: { ...rest } }) = id = instance.$mount() (.$el) = true let verticalOffset = 0 (item => { verticalOffset += item.$ + 16 }) verticalOffset += 16 = verticalOffset (instance) .$on('closed', () => { if (typeof onClose === 'function') { onClose(instance) } removeInstance(instance) .$destroy() }) return } export default notify
First, through const NotificationConstructor = (Component), we get a subclass similar to Vue, and we can create an instance of Vue through new NotificationConstructor({...options}). At the same time, the instances created through this method have all the properties in the component definition.
After creating an instance, you can manually mount the component to the DOM through instance.$mount(), so that we can output DOM fragments without relying on the Vue component tree, achieving the effect of freely displaying notifications.
The implementation in the middle is mainly to maintain a notification array, push it in when it is created, and delete it when it disappears. This process does not stipulate that it must be implemented in this way. I will not elaborate on it, so as not to limit everyone's ideas. You can implement it according to your own ideas.
Use this method
To use this notification method, we can directly import the file, for example:
import notify from './' notify({ content: 'xxx', btn: 'xxx' })
Of course, many of our scenarios are called internally in the component. In order to facilitate use within the component, we do not need to import each time. We can wrap this method into a Vue plug-in. We create one with the following content:
import Notification from './' import notify from './function' export default (Vue) => { (, Notification) .$notify = notify = notify }
Then within the project, we can use:
import notify from '/path/to/notification/module' (notify)
In this way, you can call notifications directly in the component through this.$notify({...options}), and you can also call them in other environments through ({...options}). You can try it in your own project.
Summarize
At this point, it's almost done about how to implement the content of calling a Vue component through a method. The Vue technical points we are involved here are as follows:
- Extend components through extend configuration
- Create a Vue subclass to create a Vue instance dynamically
- Actively mount component content to DOM through Vue instance
Vue has a lot of APIs. If you have not systematically learned the core knowledge and APIs of Vue before using Vue, you may not know that there is such an implementation method at all. Therefore, if you want to learn Vue well, the system must learn the core of Vue.
The above is the Vue technique that the editor introduces to you that you don’t know - to develop a component that can be explained and integrated through method calls. I hope it will be helpful to everyone. If you have any questions, please leave me a message and the editor will reply to everyone in time. Thank you very much for your support for my website!