Notification: supports VNode, #1885

This commit is contained in:
qingwei.li 2017-01-04 15:52:35 +08:00
parent 661dc09002
commit 2719667fed
8 changed files with 73 additions and 26 deletions

View File

@ -2,9 +2,11 @@
module.exports = {
methods: {
open() {
const h = this.$createElement;
this.$notify({
title: 'Title',
message: 'This is a reminder'
message: h('p', { style: 'color: red' }, 'This is a reminder')
});
},
@ -61,14 +63,14 @@
};
</script>
## Notification
## Notification
Displays a global notification message at the upper right corner of the page.
### Basic usage
::: demo Element has registered the `$notify` method and it receives an object as its parameter. In the simplest case, you can set the `title` field and the` message` field for the title and body of the notification. By default, the notification automatically closes after 4500ms, but by setting `duration` you can control its duration. Specifically, if set to `0`, it will not close automatically. Note that `duration` receives a `Number` in milliseconds.
```html
<template>
<el-button
@ -87,9 +89,11 @@ Displays a global notification message at the upper right corner of the page.
export default {
methods: {
open() {
const h = this.$createElement;
this.$notify({
title: 'Title',
message: 'This is a reminder'
message: h('p', { style: 'color: red' }, 'This is a reminder')
});
},
@ -220,7 +224,7 @@ In this case you should call `Notification(options)`. We have also registered me
| Attribute | Description | Type | Accepted Values | Default |
|---------- |-------------- |---------- |-------------------------------- |-------- |
| title | title | string | — | — |
| message | description text | string | — | — |
| message | description text | string/Vue.VNode | — | — |
| type | notification type | string | success/warning/info/error | — |
| iconClass | custom icon's class. It will be overridden by `type` | string | — | — |
| customClass | custom class name for Notification | string | — | — |

View File

@ -2,9 +2,11 @@
module.exports = {
methods: {
open() {
const h = this.$createElement;
this.$notify({
title: '标题名称',
message: '这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案'
message: h('p', { style: 'color: red'}, '这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案')
});
},
@ -45,7 +47,7 @@
message: '这是一条错误的提示消息'
});
},
open7() {
this.$notify.success({
title: '成功',
@ -88,9 +90,11 @@
export default {
methods: {
open() {
const h = this.$createElement;
this.$notify({
title: '标题名称',
message: '这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案'
message: h('p', { style: 'color: red'}, '这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案这是提示文案')
});
},
@ -222,7 +226,7 @@ import { Notification } from 'element-ui';
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------------- |---------- |-------------------------------- |-------- |
| title | 标题 | string | — | — |
| message | 说明文字 | string | — | — |
| message | 说明文字 | string/Vue.VNode | — | — |
| type | 主题样式,如果不在可选值内将被忽略 | string | success/warning/info/error | — |
| iconClass | 自定义图标的类名。若设置了 `type`,则 `iconClass` 会被覆盖 | string | — | — |
| customClass | 自定义类名 | string | — | — |

View File

@ -8,7 +8,7 @@
</div>
<div class="el-message-box__content" v-if="message !== ''">
<div class="el-message-box__status" :class="[ typeClass ]"></div>
<div class="el-message-box__message" :style="{ 'margin-left': typeClass ? '50px' : '0' }"><p>{{ message }}</p></div>
<div class="el-message-box__message" :style="{ 'margin-left': typeClass ? '50px' : '0' }">{{ message }}</div>
<div class="el-message-box__input" v-show="showInput">
<el-input v-model="inputValue" :placeholder="inputPlaceholder" ref="input"></el-input>
<div class="el-message-box__errormsg" :style="{ visibility: !!editorErrorMessage ? 'visible' : 'hidden' }">{{ editorErrorMessage }}</div>

View File

@ -1,5 +1,6 @@
import Vue from 'vue';
import { PopupManager } from 'element-ui/src/utils/popup';
import { isVNode } from 'element-ui/src/utils/vdom';
let NotificationConstructor = Vue.extend(require('./main.vue'));
let instance;
@ -19,6 +20,11 @@ var Notification = function(options) {
instance = new NotificationConstructor({
data: options
});
if (isVNode(options.message)) {
instance.$slots.default = [options.message];
options.message = '';
}
instance.id = id;
instance.vm = instance.$mount();
document.body.appendChild(instance.vm.$el);
@ -39,7 +45,7 @@ var Notification = function(options) {
['success', 'warning', 'info', 'error'].forEach(type => {
Notification[type] = options => {
if (typeof options === 'string') {
if (typeof options === 'string' || isVNode(options)) {
options = {
message: options
};

View File

@ -13,8 +13,8 @@
v-if="type || iconClass">
</i>
<div class="el-notification__group" :class="{ 'is-with-icon': typeClass || iconClass }">
<span>{{ title }}</span>
<p>{{ message }}</p>
<h2 class="el-notification__title" v-text="title"></h2>
<div class="el-notification__content"><slot>{{ message }}</slot></div>
<div class="el-notification__closeBtn el-icon-close" @click="close"></div>
</div>
</div>

View File

@ -20,18 +20,20 @@
@when with-icon {
margin-left: 55px;
}
& span {
font-size: var(--notification-title-font-size);
color: var(--notification-title-color);
}
}
& p {
font-size: var(--notification-font-size);
line-height: 21px;
margin: 10px 0 0 0;
color: var(--notification-color);
text-align: justify;
}
@e title {
font-weight: normal;
font-size: var(--notification-title-font-size);
color: var(--notification-title-color);
}
@e content {
font-size: var(--notification-font-size);
line-height: 21px;
margin: 10px 0 0 0;
color: var(--notification-color);
text-align: justify;
}
@e icon {

6
src/utils/vdom.js Normal file
View File

@ -0,0 +1,6 @@
import Vue from 'vue';
export function isVNode(node) {
if (!node || typeof node !== 'object') return false;
return Vue.util.hasOwn(node, 'tag') && Vue.util.hasOwn(node, 'componentOptions');
};

View File

@ -1,3 +1,4 @@
import Vue from 'vue';
import { triggerEvent } from '../util';
import Notification from 'packages/notification';
@ -45,13 +46,37 @@ describe('Notification', () => {
duration: 0
});
const group = document.querySelector('.el-notification__group');
const title = group.querySelector('span');
const message = group.querySelector('p');
const title = group.querySelector('.el-notification__title');
const message = group.querySelector('.el-notification__content');
expect(document.querySelector('.el-notification')).to.exist;
expect(title.textContent).to.equal('狮子');
expect(message.textContent).to.equal('狮鹫');
});
it('create by vnode', () => {
const fakeVM = new Vue();
const h = fakeVM.$createElement;
Notification({
message: h('p', { style: { color: 'red' } }, '大美兴,川普王')
});
const group = document.querySelector('.el-notification__group');
const message = group.querySelector('.el-notification__content');
expect(message.innerHTML).to.equal('<p style="color: red;">大美兴,川普王</p>');
});
it('alias by vnode', () => {
const fakeVM = new Vue();
const h = fakeVM.$createElement;
Notification.error(h('p', { style: { color: 'green' } }, '+1s'));
const group = document.querySelector('.el-notification__group');
const message = group.querySelector('.el-notification__content');
expect(message.innerHTML).to.equal('<p style="color: green;">+1s</p>');
});
it('invoke with type', () => {
Notification.success('太阳之子');
expect(document.querySelector('.el-notification').__vue__.type).to.equal('success');