Commit 77cf1cd5738221778b0a6b180ddb787c66429740

Authored by Aresn
1 parent 24c8f4ea

$Modal support SSR

examples/routers/modal.vue
1 <template> 1 <template>
2 <div> 2 <div>
3 - <Button type="primary" @click="modal1 = true">显示对话框</Button>  
4 -  
5 - <Modal  
6 - v-model="modal1"  
7 - :title="title"  
8 - @on-ok="ok"  
9 - :mask-closable="false"  
10 - @on-cancel="cancel">  
11 - <p><Button type="ghost" @click="title = '这是标题'">设置标题</Button> {{title}}</p>  
12 - <p>对话框内容</p>  
13 - <p>对话框内容</p>  
14 - </Modal> 3 + <Button @click="confirm">标准</Button>
  4 + <Button @click="custom">自定义按钮文字</Button>
  5 + <Button @click="async">异步关闭</Button>
15 </div> 6 </div>
16 </template> 7 </template>
17 <script> 8 <script>
18 export default { 9 export default {
19 - data () {  
20 - return {  
21 - modal1: true,  
22 - title:''  
23 - }  
24 - },  
25 methods: { 10 methods: {
26 - ok () {  
27 - this.$Message.info('点击了确定'); 11 + confirm () {
  12 + this.$Modal.confirm({
  13 + title: '确认对话框标题',
  14 + content: '<p>一些对话框内容</p><p>一些对话框内容</p>',
  15 + onOk: () => {
  16 + this.$Message.info('点击了确定');
  17 + },
  18 + onCancel: () => {
  19 + this.$Message.info('点击了取消');
  20 + }
  21 + });
  22 + },
  23 + custom () {
  24 + this.$Modal.confirm({
  25 + title: '确认对话框标题',
  26 + content: '<p>一些对话框内容</p><p>一些对话框内容</p>',
  27 + okText: 'OK',
  28 + cancelText: 'Cancel'
  29 + });
28 }, 30 },
29 - cancel () {  
30 - this.$Message.info('点击了取消'); 31 + async () {
  32 + this.$Modal.confirm({
  33 + title: '确认对话框标题',
  34 + content: '<p>对话框将在 2秒 后关闭</p>',
  35 + loading: true,
  36 + onOk: () => {
  37 + setTimeout(() => {
  38 + this.$Modal.remove();
  39 + this.$Message.info('异步关闭了对话框');
  40 + }, 2000);
  41 + }
  42 + });
31 } 43 }
32 } 44 }
33 } 45 }
src/components/modal/confirm.js
1 import Vue from 'vue'; 1 import Vue from 'vue';
2 import Modal from './modal.vue'; 2 import Modal from './modal.vue';
3 -import Icon from '../icon/icon.vue';  
4 -import iButton from '../button/button.vue';  
5 -import { camelcaseToHyphen } from '../../utils/assist'; 3 +import Button from '../button/button.vue';
6 import Locale from '../../mixins/locale'; 4 import Locale from '../../mixins/locale';
7 5
8 const prefixCls = 'ivu-modal-confirm'; 6 const prefixCls = 'ivu-modal-confirm';
@@ -10,36 +8,34 @@ const prefixCls = &#39;ivu-modal-confirm&#39;; @@ -10,36 +8,34 @@ const prefixCls = &#39;ivu-modal-confirm&#39;;
10 Modal.newInstance = properties => { 8 Modal.newInstance = properties => {
11 const _props = properties || {}; 9 const _props = properties || {};
12 10
13 - let props = '';  
14 - Object.keys(_props).forEach(prop => {  
15 - props += ' :' + camelcaseToHyphen(prop) + '=' + prop;  
16 - }); 11 + // let props = '';
  12 + // Object.keys(_props).forEach(prop => {
  13 + // props += ' :' + camelcaseToHyphen(prop) + '=' + prop;
  14 + // });
  15 + //
  16 + // const div = document.createElement('div');
  17 + // div.innerHTML = `
  18 + // <Modal${props} v-model="visible" :width="width" :scrollable="scrollable">
  19 + // <div class="${prefixCls}">
  20 + // <div class="${prefixCls}-head">
  21 + // <div class="${prefixCls}-head-title" v-html="title"></div>
  22 + // </div>
  23 + // <div class="${prefixCls}-body">
  24 + // <div :class="iconTypeCls"><i :class="iconNameCls"></i></div>
  25 + // <div v-html="body"></div>
  26 + // </div>
  27 + // <div class="${prefixCls}-footer">
  28 + // <i-button type="text" size="large" v-if="showCancel" @click.native="cancel">{{ localeCancelText }}</i-button>
  29 + // <i-button type="primary" size="large" :loading="buttonLoading" @click.native="ok">{{ localeOkText }}</i-button>
  30 + // </div>
  31 + // </div>
  32 + // </Modal>
  33 + // `;
  34 + // document.body.appendChild(div);
17 35
18 - const div = document.createElement('div');  
19 - div.innerHTML = `  
20 - <Modal${props} v-model="visible" :width="width" :scrollable="scrollable">  
21 - <div class="${prefixCls}">  
22 - <div class="${prefixCls}-head">  
23 - <div class="${prefixCls}-head-title" v-html="title"></div>  
24 - </div>  
25 - <div class="${prefixCls}-body">  
26 - <div :class="iconTypeCls"><i :class="iconNameCls"></i></div>  
27 - <div v-html="body"></div>  
28 - </div>  
29 - <div class="${prefixCls}-footer">  
30 - <i-button type="text" size="large" v-if="showCancel" @click.native="cancel">{{ localeCancelText }}</i-button>  
31 - <i-button type="primary" size="large" :loading="buttonLoading" @click.native="ok">{{ localeOkText }}</i-button>  
32 - </div>  
33 - </div>  
34 - </Modal>  
35 - `;  
36 - document.body.appendChild(div);  
37 -  
38 - const modal = new Vue({  
39 - el: div, 36 + const Instance = new Vue({
40 mixins: [ Locale ], 37 mixins: [ Locale ],
41 - components: { Modal, iButton, Icon },  
42 - data: Object.assign(_props, { 38 + data: Object.assign({}, _props, {
43 visible: false, 39 visible: false,
44 width: 416, 40 width: 416,
45 title: '', 41 title: '',
@@ -53,6 +49,87 @@ Modal.newInstance = properties =&gt; { @@ -53,6 +49,87 @@ Modal.newInstance = properties =&gt; {
53 buttonLoading: false, 49 buttonLoading: false,
54 scrollable: false 50 scrollable: false
55 }), 51 }),
  52 + render (h) {
  53 + let footerVNodes = [];
  54 + if (this.showCancel) {
  55 + footerVNodes.push(h(Button, {
  56 + props: {
  57 + type: 'text',
  58 + size: 'large'
  59 + },
  60 + on: {
  61 + click: this.cancel
  62 + }
  63 + }, this.localeCancelText));
  64 + }
  65 + footerVNodes.push(h(Button, {
  66 + props: {
  67 + type: 'primary',
  68 + size: 'large',
  69 + loading: this.buttonLoading
  70 + },
  71 + on: {
  72 + click: this.ok
  73 + }
  74 + }, this.localeOkText));
  75 +
  76 + return h(Modal, {
  77 + props: Object.assign({}, _props, {
  78 + width: this.width,
  79 + scrollable: this.scrollable
  80 + }),
  81 + domProps: {
  82 + value: this.visible
  83 + },
  84 + on: {
  85 + input: (status) => {
  86 + this.visible = status;
  87 + }
  88 + }
  89 + }, [
  90 + h('div', {
  91 + attrs: {
  92 + class: prefixCls
  93 + }
  94 + }, [
  95 + h('div', {
  96 + attrs: {
  97 + class: `${prefixCls}-head`
  98 + }
  99 + }, h('div', {
  100 + attrs: {
  101 + class: `${prefixCls}-head-title`
  102 + },
  103 + domProps: {
  104 + innerHTML: this.title
  105 + }
  106 + })),
  107 + h('div', {
  108 + attrs: {
  109 + class: `${prefixCls}-body`
  110 + }
  111 + }, [
  112 + h('div', {
  113 + class: this.iconTypeCls
  114 + }, [
  115 + h('i', {
  116 + class: this.iconNameCls
  117 + })
  118 + ]),
  119 + h('div', {
  120 + domProps: {
  121 + innerHTML: this.body
  122 + }
  123 + })
  124 + ]),
  125 + h('div', {
  126 + attrs: {
  127 + class: `${prefixCls}-footer`
  128 + }
  129 + }, footerVNodes)
  130 + ])
  131 + ]);
  132 + },
56 computed: { 133 computed: {
57 iconTypeCls () { 134 iconTypeCls () {
58 return [ 135 return [
@@ -111,7 +188,11 @@ Modal.newInstance = properties =&gt; { @@ -111,7 +188,11 @@ Modal.newInstance = properties =&gt; {
111 onCancel () {}, 188 onCancel () {},
112 onRemove () {} 189 onRemove () {}
113 } 190 }
114 - }).$children[0]; 191 + });
  192 +
  193 + const component = Instance.$mount();
  194 + document.body.appendChild(component.$el);
  195 + const modal = Instance.$children[0];
115 196
116 return { 197 return {
117 show (props) { 198 show (props) {
src/components/modal/modal.vue
1 <template> 1 <template>
2 - <div v-transfer-dom> 2 + <div>
3 <transition :name="transitionNames[1]"> 3 <transition :name="transitionNames[1]">
4 <div :class="maskClasses" v-show="visible" @click="mask"></div> 4 <div :class="maskClasses" v-show="visible" @click="mask"></div>
5 </transition> 5 </transition>