Vue项目中封装组件的简单步骤记录

前言

随着业务的发展 功能性开发 已经无法满足我们对于前端的需求,这一篇主要带大家体验一下如何开发一套属于自己的组件库

使用场景:公司内部组件库的开发,个人组件库的开发,与项目解耦,多项目中使用同一组件,只需维护一套组件库

如何封装一个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)

总结

到此这篇关于Vue项目中封装组件的文章就介绍到这了,更多相关Vue项目封装组件内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

以上是 Vue项目中封装组件的简单步骤记录 的全部内容, 来源链接: utcz.com/p/239835.html

回到顶部