Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities.
👉 Faith will move mountains. Book of the Later Han · Biography of King Jing of Guangling by Fan Ye
preface
With the development of business, functional development has been unable to meet our front-end needs. This chapter mainly takes you to experience how to develop a set of components library that belongs to your own
Usage scenario: the development of internal component library of the company, the development of individual component library, decoupled with the project, the use of the same component in multiple projects, only need to maintain a set of component library
How to encapsulate a Toast component
Component Description:
Realize prompt function.
Effect display:
Functions achieved:
-
- According to a judgment condition or click a button, pop-up box;
-
- You can configure location, type, style name, etc
Use case
1. Easy to use
vm.$toast('Network exception! ')
Copy the code
2. Set options
* message message content * duration Duration, in milliseconds * position Display position: Top, Middle, bottom * className Style name vm.$toast({message: 'Network exception! '.duration: 2000.position: 'middle'.className: 'big'
})
Copy the code
3. Error message
vm.$toast({
message: 'Verification code error! '.duration: 2000.type: 'error'
})
Copy the code
The specific implementation
The first toast. Vue
<template>
<transition name="toast-pop">
<div v-show="visible" class="toast" :class="customClass" @click="handleClose">
<span class="text">{{message}}</span>
</div>
</transition>
</template>
<script>
export default {
name: 'Toast'.props: {
message: String.// Prompt content
className: { / / the style name
type: String.default: ' '
},
position: { // Position: top, middle, bottom
type: String.default: 'middle'
},
type: { // The warning type can be Normal or error
type: String.defalut: 'normal'
}
},
data () {
return {
// Whether to display
visible: false}},computed: {
// Get the style
customClass () {
let classes = []
classes.push('toast-' + this.type)
switch (this.positon) {
case 'top':
classes.push('is-placetop')
break
case 'bottom':
classes.push('is-placebottom')
break
default:
classes.push('is-placemiddle')}this.className && classes.push(this.className)
return classes
}
},
methods: {
handleClose () {
this.$emit('close')}}}</script>
<style lang="scss" scoped px2rem="false">
.toast {
position: fixed;
box-sizing: border-box;
min-width: 200px;
max-width: 50%;
max-height: 85%;
margin-top: 0;
padding: 18px 30px;
border-radius: 10px;
background: rgba(0.0.0.0.7);
color: #fff;
text-align: center;
overflow-y: auto;
z-index: 2000;
.text {
display: block;
font-size: 16px;
line-height: 1.5;
text-align: center;
word-wrap: break-word; }}.is-placetop {
top: 50px;
left: 50%;
transform: translate(-50%.0);
}
.is-placemiddle {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.is-placebottom {
bottom: 50px;
left: 50%;
transform: translate(-50%.0);
}
.is-placetop.toast-pop-enter-active..is-placetop.toast-pop-leave-active..is-placemiddle.toast-pop-enter-active..is-placemiddle.toast-pop-leave-active {
transition: opacity .3s linear, margin-top .3s ease;
}
.is-placetop.toast-pop-enter..is-placetop.toast-pop-leave-to..is-placemiddle.toast-pop-enter..is-placemiddle.toast-pop-leave-to {
margin-top: 30px;
opacity: 0;
}
.is-placebottom.toast-pop-enter-active..is-placebottom.toast-pop-leave-active {
transition: opacity .3s linear, margin-bottom .3s ease;
}
.is-placebottom.toast-pop-enter..is-placebottom.toast-pop-leave-to {
margin-bottom: -30px;
opacity: 0;
}
.toast-error {
background: rgba(255.102.104.9);
}
</style>
Copy the code
toastPlugin.js
import Vue from 'vue'
import Toast from './toast.vue'
// toast constructor
const ToastConstructor = Vue.extend({
extends: Toast
})
// Toast instance pool
let toastPool = []
/** Get a toast instance */
let getInstance = () = > {
// console.log('toastPool:', toastPool)
if (toastPool.length > 0) {
return toastPool.shift()
}
return new ToastConstructor({
el: document.createElement('div')})}/** return the instance to the instance pool */
let returnInstance = instance= > {
if (instance) {
toastPool.push(instance)
// console.log(' Return instance :', instance, toastPool)}}/** Remove the toast DOM node */ from the document
function removeDom (event) {
if (event.target.parentNode) {
event.target.parentNode.removeChild(event.target)
}
}
/ / close
ToastConstructor.prototype.close = function () {
this.visible = false / / not visible
this.closed = true // Closed state
this.$el.addEventListener('transitionend', removeDom) // Remove the DOM node after the animation is complete
returnInstance(this) // The instance object is returned to the instance pool and the instance can be reused
}
// Display a toast message
export default function (options = {}) {
// Display time, default 3 seconds
let duration = options.duration || 3000
let instance = getInstance()
// console.log('instance=', instance)
// Display type
instance.type = options.type || 'normal'
// Display the content
instance.message = typeof options === 'string' ? options : options.message
// Display position: top, middle, bottom
instance.position = options.position || 'middle'
instance.className = options.className || ' '
// Remove the animation completion event
instance.$el.removeEventListener('transitionend', removeDom)
instance.$on('close'.() = > {
instance.close()
})
// console.log('instance.$el=', instance.$el)
// Add nodes to the document
document.body.appendChild(instance.$el)
instance.visible = true
instance.closed = false
// Clear the timer
instance.timer && clearTimeout(instance.timer)
// Set timer to close toast
instance.timer = setTimeout(() = > {
// console.log(' off ', instance)! instance.closed && instance.close() instance.timer =null
}, duration)
}
Copy the code
main.js
import ToastPlugin from './plugins/toastPlugin.js'
// Toast prompt plugin
Vue.use(ToastPlugin)
Copy the code