Vue项目封装组件
青莲使者 人气:0前言
随着业务的发展 功能性开发 已经无法满足我们对于前端的需求,这一篇主要带大家体验一下如何开发一套属于自己的组件库
使用场景:公司内部组件库的开发,个人组件库的开发,与项目解耦,多项目中使用同一组件,只需维护一套组件库
如何封装一个Toast组件
组件说明:
实现提示功能。
效果展示:
实现的功能:
- 根据某个判断条件或者点击某个按钮,弹出弹框;
- 可配置位置,类型,样式名等
使用案例
1. 简单使用
vm.$toast('网络异常!')
2. 使用options参数
* message 提示信息内容 * duration 停留时间,单位为毫秒 * position 显示位置:top、middle、bottom * className 样式名称 vm.$toast({ message: '网络异常!', duration: 2000, position: 'middle', className: 'big' })
3. 错误提示
vm.$toast({ message: '验证码错误!', duration: 2000, type: 'error' })
具体实现
首先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, // 提示信息内容 className: { // 样式名 type: String, default: '' }, position: { // 位置:top、middle、bottom type: String, default: 'middle' }, type: { // 提示类型:normal、error type: String, defalut: 'normal' } }, data () { return { // 是否显示 visible: false } }, computed: { // 获取样式 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>
toastPlugin.js
import Vue from 'vue' import Toast from './toast.vue' // toast构造函数 const ToastConstructor = Vue.extend({ extends: Toast }) // toast实例池 let toastPool = [] /** 获取toast实例(实例池中有从池中取,没有则新建) */ let getInstance = () => { // console.log('toastPool:', toastPool) if (toastPool.length > 0) { return toastPool.shift() } return new ToastConstructor({ el: document.createElement('div') }) } /** 归还实例到实例池 */ let returnInstance = instance => { if (instance) { toastPool.push(instance) // console.log('归还实例:', instance, toastPool) } } /** 文档中移除toast的DOM节点 */ function removeDom (event) { if (event.target.parentNode) { event.target.parentNode.removeChild(event.target) } } // 关闭 ToastConstructor.prototype.close = function () { this.visible = false // 不可见 this.closed = true // 关闭状态 this.$el.addEventListener('transitionend', removeDom) // 动画完成后移除DOM节点 returnInstance(this) // 实例对象归还到实例池,实例可以重复利用 } // 显示toast提示信息 export default function (options = {}) { // 显示时间,默认3秒 let duration = options.duration || 3000 let instance = getInstance() // console.log('instance=', instance) // 显示类型 instance.type = options.type || 'normal' // 显示内容 instance.message = typeof options === 'string' ? options : options.message // 显示位置:top、middle、bottom instance.position = options.position || 'middle' instance.className = options.className || '' // 移除动画完成事件 instance.$el.removeEventListener('transitionend', removeDom) instance.$on('close', () => { instance.close() }) // console.log('instance.$el=', instance.$el) // 将节点添加到文档 document.body.appendChild(instance.$el) instance.visible = true instance.closed = false // 清除定时器 instance.timer && clearTimeout(instance.timer) // 设置定时器,关闭toast instance.timer = setTimeout(() => { // console.log('关闭', instance) !instance.closed && instance.close() instance.timer = null }, duration) }
main.js
import ToastPlugin from './plugins/toastPlugin.js' // toast提示信息插件 Vue.use(ToastPlugin)
总结
加载全部内容