Vue作为最近最炙手可热的前端框架,其简单的入门方式和功能强大的API是其优点。而同时因为其API的多样性和丰富性,所以他的很多开发方式就和一切基于组件的React不同,如果没有对Vue的API(有一些甚至文档都没提到)有一个全面的了解,那么在开发和设计一个组件的时候有可能就会绕一个大圈子,所以我非常推荐各位在学习Vue的时候先要对Vue核心的所有API都有一个了解。这篇文章我会从实践出发,遇到一些知识点会顺带总结一下。文章很长,一次看不完可以先收藏,如果你刚入门vue,那么相信这篇文章对你以后的提升绝对有帮助
进入正题,我相信不论什么项目几乎都会有一个必不可少的功能,就是用户操作反馈、或者提醒.像这样(简单的一个demo)
其实在vue的中大型项目中,这些类似的小功能会更加丰富以及严谨,而在以Vue作为核心框架的前端项目中,因为Vue本身是一个组件化和虚拟Dom的框架,要实现一个通知组件的展示当然是非常简单的。但因为通知组件的使用特性,直接在模板当中书写组件并通过v-show或者props控制通知组件的显示显然是非常不方便的并且这样意味着你的代码结构要变,当各种各样的弹层变多的时候,我们都将其挂载到APP或者一个组件下显然不太合理,而且如果要在action或者其他非组件场景中要用到通知,那么纯组件模式的用法也无法实现。那么有没有办法即用到Vue组件化特性方便得实现一个通知组件的展现,那么我们可否用一个方法来控制弹层组件的显示和隐藏呢?
目标一
实现一个简单的反馈通知,可以通过方法在组件内直接调用。比如Vue.$confirm({...obj})
首先,我们来实现通知组件,相信这个大部分人都能写出来一个像模像样的组件,不啰嗦,直接上代码
<template> <div :class="type"> <i :class="iconClass"/> <span>{{ msg }}</span> <!-- <span @click="close"></span> --> </div> </template> <script> export default { name: 'Notification', props: { type: { type: String, default: '' }, msg: { type: String, default: '' } }, computed: { iconClass() { switch (this.type) { case 'success': return 'eqf-info-f' case 'fail': return 'eqf-no-f' case 'info': return 'eqf-info-f' case 'warn': return 'eqf-alert-f' } } }, mounted() { setTimeout(() => this.close(), 4000) }, methods: { close() { } } } </script> <style lang="scss"> .eqc-notifier { position: fixed; top: 68px; left: 50%; height: 36px; padding-right: 10px; line-height: 36px; box-shadow: 0 0 16px 0 rgba(0, 0, 0, 0.16); border-radius: 3px; background: #fff; z-index: 100; // 层级最高 transform: translateX(-50%); animation: fade-in 0.3s; .icon { margin: 10px; font-size: 16px; } .close { margin: 8px; font-size: 20px; color: #666; transition: all 0.3s; cursor: pointer; &:hover { color: #ff296a; } } &.success { color: #1bc7b1; } &.fail { color: #ff296a; } &.info { color: #1593ff; } &.warn { color: #f89300; } &.close { animation: fade-out 0.3s; } } </style>
在这里需要注意,我们定义了一个close方法,但内容是空的,虽然在模板上有用到,但是似乎没什么意义,在后面我们要扩展组件的时候我会讲到为什么要这么做。
创建完这个组件之后,我们就可以在模板中使用了<notification type="xxx" msg="xxx" />
实现通过方法调用该通知组件
其实在实现通过方法调用之前,我们需要扩展一下这个组件,因为仅仅这些属性,并不够我们使用。在使用方法调用的时候,我们需要考虑一下几个问题:
显示反馈的定位
组件的出现和自动消失控制
连续多次调用通知方法,如何排版多个通知
在这个前提下,我们需要扩展该组件,但是扩展的这些属性不能直接放在原组件内,因为这些可能会影响组件在模板内的使用,那怎么办呢?这时候我们就要用到Vue里面非常好用的一个API,extend,通过他去继承原组件的属性并扩展他。
来看代码
import Notifier from './Notifier.vue' function install(Vue) { Vue.notifier = Vue.prototype.notifier = { success, fail, info, warn } } function open(type, msg) { let UiNotifier = Vue.extend(Notifier) let vm = new UiNotifier({ propsData: { type, msg }, methods: { close: function () { let dialog = this.$el dialog.addEventListener('animationend', () => { document.body.removeChild(dialog) this.$destroy() }) dialog.className = `${this.type} eqc-notifier close` dialog = null } } }).$mount() document.body.appendChild(vm.$el) } function success(msg) { open('success', msg) } function fail(msg) { open('fail', msg) } function info(msg) { open('info', msg) } function warn(msg) { open('warn', msg) } Vue.use(install) export default install