add Message component

add Message component
This commit is contained in:
梁灏 2016-09-19 14:50:32 +08:00
parent c1cfacb2d4
commit 7c15ac9e31
27 changed files with 653 additions and 38 deletions

View file

@ -0,0 +1,34 @@
import Notification from './notification.vue';
import Vue from 'vue';
import { camelcaseToHyphen } from '../../../utils/assist';
Notification.newInstance = properties => {
const _props = properties || {};
let props = '';
Object.keys(_props).forEach(prop => {
props += ' :' + camelcaseToHyphen(prop) + '=' + prop;
});
const div = document.createElement('div');
div.innerHTML = `<notification${props}></notification>`;
document.body.appendChild(div);
const notification = new Vue({
el: div,
data: _props,
components: { Notification }
}).$children[0];
return {
notice (noticeProps) {
notification.add(noticeProps);
},
component: notification,
destroy () {
document.body.removeChild(div);
}
}
};
export default Notification;

View file

@ -0,0 +1,92 @@
<template>
<div :class="classes" :style="style" transition="move-up">
<div :class="[`${baseClass}-content`]" v-el:content>{{{ content }}}</div>
<span v-if="closable">
<a :class="[`${baseClass}-close`]" @click="close">
<span :class="[`${baseClass}-close-x`]"></span>
</a>
</span>
</div>
</template>
<script>
export default {
props: {
prefixCls: {
type: String,
default: ''
},
duration: {
type: Number,
default: 1.5
},
content: {
type: String,
default: ''
},
style: {
type: Object,
default: function() {
return {
right: '50%'
}
}
},
closable: {
type: Boolean,
default: false
},
className: {
type: String
},
key: {
type: String,
required: true
},
onClose: {
type: Function
}
},
computed: {
baseClass () {
return `${this.prefixCls}-notice`;
},
classes () {
return [
this.baseClass,
{
[`${this.className}`]: !!this.className,
[`${this.baseClass}-closable`]: this.closable
}
]
},
contentClasses () {
return `${this.baseClass}-content`;
}
},
methods: {
clearCloseTimer () {
if (this.closeTimer) {
clearTimeout(this.closeTimer);
this.closeTimer = null;
}
},
close () {
this.clearCloseTimer();
this.onClose();
this.$parent.close(this.key);
}
},
compiled () {
this.clearCloseTimer();
if (this.duration !== 0) {
this.closeTimer = setTimeout(() => {
this.close();
}, this.duration * 1000)
}
},
beforeDestroy () {
this.clearCloseTimer();
}
}
</script>

View file

@ -0,0 +1,92 @@
<template>
<div :class="classes" :style="style">
<Notice v-for="notice in notices"
:prefix-cls="prefixCls"
:style="notice.style"
:content="notice.content"
:duration="notice.duration"
:closable="notice.closable"
:key="notice.key"
:on-close="notice.onClose">
</Notice>
</div>
</template>
<script>
import Notice from './notice.vue';
const prefixCls = 'ivu-notification';
let seed = 0;
const now = Date.now();
function getUuid () {
return 'ivuNotification_' + now + '_' + (seed++);
}
export default {
components: { Notice },
props: {
prefixCls: {
type: String,
default: prefixCls
},
style: {
type: Object,
default: function () {
return {
top: '65px',
left: '50%'
}
}
},
content: {
type: String
},
className: {
type: String
},
transitionName: String
},
data () {
return {
notices: []
}
},
computed: {
classes () {
return [
`${this.prefixCls}`,
{
[`${this.className}`]: !!this.className
}
]
}
},
methods: {
add (notice) {
const key = getUuid();
let _notice = Object.assign({
style: {
right: '50%'
},
content: '',
duration: 1.5,
closable: false,
key: key
}, notice);
this.notices.push(_notice);
},
close (key) {
const notices = this.notices;
for (let i = 0; i < notices.length; i++) {
if (notices[i].key === key) {
this.notices.splice(i, 1);
break;
}
}
}
}
}
</script>

View file

@ -0,0 +1,81 @@
import Notification from '../base/notification';
const prefixCls = 'ivu-message';
const iconPrefixCls = 'ivu-icon';
let defaultDuration = 1.5;
let top;
let messageInstance;
const iconTypes = {
'info': 'information-circled',
'success': 'checkmark-circled',
'warning': 'android-alert',
'error': 'close-circled',
'loading': 'load-c'
};
function getMessageInstance () {
messageInstance = messageInstance || Notification.newInstance({
prefixCls: prefixCls,
transitionName: 'slide',
style: {
top: `${top}px`
}
});
return messageInstance;
}
function notice (content, duration = defaultDuration, type, onClose) {
if (!onClose) {
onClose = function () {
}
}
let iconType = iconTypes[type];
// if loading
const loadCls = type === 'loading' ? ' ivu-load-loop' : '';
let instance = getMessageInstance();
instance.notice({
duration: duration,
style: {},
content: `
<div class="${prefixCls}-custom-content ${prefixCls}-${type}">
<i class="${iconPrefixCls} ${iconPrefixCls}-${iconType}${loadCls}"></i>
<span>${content}</span>
</div>
`,
onClose: onClose
});
}
export default {
info (content, duration, onClose) {
return notice(content, duration, 'info', onClose);
},
success (content, duration, onClose) {
return notice(content, duration, 'success', onClose);
},
warning (content, duration, onClose) {
return notice(content, duration, 'warning', onClose);
},
error (content, duration, onClose) {
return notice(content, duration, 'error', onClose);
},
loading (content, duration, onClose) {
return notice(content, duration, 'loading', onClose);
},
config (options) {
if (options.top) {
top = options.top;
}
if (options.duration) {
defaultDuration = options.duration;
}
}
}

View file