组件是 Vue 的一个极其重要的概念。在移动端网页开发时,Toast 组件使用也是很是频繁的。本文便以 Toast 组件为例,来说解 Vue 组件的部分知识点。javascript
平常开发时,咱们项目文件夹一般都是使用 vue-cli 建立的,以 单文件组件 的方式来组织代码的。按照平日的开发流程,如今先建立一个 Toast.vue 文件。css
咱们开始关注实现 Toast 组件的一些要点:html
根据上文的分析,如今的代码以下。vue
<template>
<transition name="toast-bounce">
<div class="toast" v-show="visible">
<p class="toast-msg">{{ msg }}</p>
</div>
</transition>
</template>
<script> export default { name: 'Toast', props: { visible: { type: Boolean, required: true }, msg: { type: String, required: true } } } </script>
<style lang="scss" scoped> // 添加过渡效果 .toast-bounce-enter, .toast-bounce-leave { opacity: 0; } .toast { box-sizing: border-box; position: fixed; max-width: 80%; left: 50%; top: 50%; padding: 20px; z-index: 99; transition: all .3s ease; transform: translate(-50%, -50%); border-radius: 10px; background: rgba(0, 0, 0, 0.7); color: #fff; text-align: center; .toast-msg { text-align: center; } } </style>复制代码
在须要使用 Toast 组件的页面,引入该组件,注册以后就能使用了。java
以单文件组件引入,有几个不方便的地方。git
相似这样使用频率较高的组件,最便捷的方式是经过调用一个函数来完成组件的建立,挂载以及销毁。但而在开发项目过程当中,咱们把精力放在了组件的实现上,忽略了一些这些操做。接下来咱们将演示手动如何建立 Toast 组件,附加到 document.body 下,在显示一段时间后,销毁组件,再移除该元素。github
Vue 单文件的 script 标签仅仅是导出一个包含组件选项的对象。为了建立组件,先使用 Vue.extend 获得一个构造器,接下来经过 new 进行实例化。这里的构造函数有一个可选参数,类型是 Object,能够传入的属性有 el,propsData等。vue-cli
import ToastConfig from './Toast.vue'
// 构造器
const ToastConstructor = Vue.extend(ToastConfig)
// 经过 new 建立组件
const instance = new ToastConstructor()复制代码
Toast 组件在建立时,两个 prop: visible, msg 必需要传入。在 new 实例化时,配置 propsData 参数来设置组件所需的 prop。element-ui
const instance = new ToastConstructor({
propsData: {
msg: 'msg',
visible: false
}
})复制代码
组件建立与挂载是两个不一样的概念,组件建立时,挂载阶段还没开始,DOM 元素中不含该节点。在 挂载 了以后,才会被浏览器渲染。
在建立实例时,不但要设置 propsData属性,还要设置挂载点 el 属性,而且将组件附在 document.body 以后。api
const instance = new ToastConstructor({
el: document.createElement('div'),
propsData: {,
msg: 'msg',
visible: false
}
})
// 组件建立成功以后挂载
document.body.appendChild(instance.$el)复制代码
挂载以后,显示 toast 组件。再开启一个定时器,在 3s 以后隐藏组件。
Vue.nextTick(() => {
instance.visible = true
setTimeout(() => {
instance.close()
}, 3000)
})复制代码
Toast 组件隐藏的动画结束时,触发 transitionend 事件。instance.$el 返回组件的根元素,监听该元素的 transitionend 事件,在回调函数中 销毁 组件,同时从DOM树中移除。
// 在 ToastConstructor 上添加两个销毁组件与移除DOM元素的函数
// 隐藏组件
ToastConstructor.prototype.close = function () {
this.visible = false
this.$el.addEventListener('transitionend', this.destroyeInstance.bind(this))
}
// 销毁组件,移除DOM元素
ToastConstructor.prototype.destroyeInstance = function () {
this.$destroy(true)
this.$el.removeEventListener('transitionend', this.destroyeInstance)
this.$el.parentNode.removeChild(this.$el)
}复制代码
完整代码片断点击 这里。
若是在短期频繁调用 toast 函数,document.body 下面存在多个 toast 组件,后一个会覆盖前一个。考虑到移动端的特色,咱们但愿在同一个时间点上,不论 toast 函数调用有多频繁,document.body 只有会有一个 toast 组件。
接下来的调整思路大体以下:
代码须要进行一些的调整。
// 在函数以外,定义两个变量
// 组件销毁时,instance 也要置为 null
let instance = null
let timer = null
function toast (msg = '默认信息') {
// 判断 instance 是否存在
if (instance) {
instance.visible = true
instance.msg = msg
if (timer) {
clearInterval(timer)
}
instance.$el.removeEventListener('transitionend', instance.destroyeInstance)
} else {
//...
}
// ...
}复制代码
完整代码片断点击 这里。
固然咱们也能够再更进一步,把 toast 函数注册为 Vue 插件,在须要的地方经过 this.$toast
调用便可。element-ui 的 message,vux 的 Toast 都支持插件方式调用。
跟一些成熟的 Vue ui 库,例如:mint-ui 的 Toast 组件相比,如今的 Toast 组件不足之处不少。但经过编写一个极其简单的 Toast 组件,了解到 Vue 组件的部分概念,知道了到如何手动建立,销毁组件,如何结合 transition 制做一些简单的动画,有助于咱们更好的理解 Vue 组件的思想 ,并且之后在使用第三方库的一些组件时,能大体知晓其原理。