Selaa lähdekoodia

Notification: supports VNode, #1885

qingwei.li 8 vuotta sitten
vanhempi
commit
2719667fed

+ 9 - 5
examples/docs/en-US/notification.md

@@ -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 | — | — |

+ 8 - 4
examples/docs/zh-CN/notification.md

@@ -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 | — | — |

+ 1 - 1
packages/message-box/src/main.vue

@@ -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>

+ 7 - 1
packages/notification/src/main.js

@@ -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
       };

+ 2 - 2
packages/notification/src/main.vue

@@ -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>

+ 13 - 11
packages/theme-default/src/notification.css

@@ -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 - 0
src/utils/vdom.js

@@ -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');
+};

+ 27 - 2
test/unit/specs/notification.spec.js

@@ -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');