$Modal support SSR

This commit is contained in:
Aresn 2017-06-01 12:32:00 +08:00
parent 24c8f4eaba
commit 77cf1cd573
3 changed files with 148 additions and 55 deletions

View file

@ -1,33 +1,45 @@
<template> <template>
<div> <div>
<Button type="primary" @click="modal1 = true">显示对话框</Button> <Button @click="confirm">标准</Button>
<Button @click="custom">自定义按钮文字</Button>
<Modal <Button @click="async">异步关闭</Button>
v-model="modal1"
:title="title"
@on-ok="ok"
:mask-closable="false"
@on-cancel="cancel">
<p><Button type="ghost" @click="title = '这是标题'">设置标题</Button> {{title}}</p>
<p>对话框内容</p>
<p>对话框内容</p>
</Modal>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data () {
return {
modal1: true,
title:''
}
},
methods: { methods: {
ok () { confirm () {
this.$Message.info('点击了确定'); this.$Modal.confirm({
title: '确认对话框标题',
content: '<p>一些对话框内容</p><p>一些对话框内容</p>',
onOk: () => {
this.$Message.info('点击了确定');
},
onCancel: () => {
this.$Message.info('点击了取消');
}
});
}, },
cancel () { custom () {
this.$Message.info('点击了取消'); this.$Modal.confirm({
title: '确认对话框标题',
content: '<p>一些对话框内容</p><p>一些对话框内容</p>',
okText: 'OK',
cancelText: 'Cancel'
});
},
async () {
this.$Modal.confirm({
title: '确认对话框标题',
content: '<p>对话框将在 2秒 后关闭</p>',
loading: true,
onOk: () => {
setTimeout(() => {
this.$Modal.remove();
this.$Message.info('异步关闭了对话框');
}, 2000);
}
});
} }
} }
} }

View file

@ -1,8 +1,6 @@
import Vue from 'vue'; import Vue from 'vue';
import Modal from './modal.vue'; import Modal from './modal.vue';
import Icon from '../icon/icon.vue'; import Button from '../button/button.vue';
import iButton from '../button/button.vue';
import { camelcaseToHyphen } from '../../utils/assist';
import Locale from '../../mixins/locale'; import Locale from '../../mixins/locale';
const prefixCls = 'ivu-modal-confirm'; const prefixCls = 'ivu-modal-confirm';
@ -10,36 +8,34 @@ const prefixCls = 'ivu-modal-confirm';
Modal.newInstance = properties => { Modal.newInstance = properties => {
const _props = properties || {}; const _props = properties || {};
let props = ''; // let props = '';
Object.keys(_props).forEach(prop => { // Object.keys(_props).forEach(prop => {
props += ' :' + camelcaseToHyphen(prop) + '=' + prop; // props += ' :' + camelcaseToHyphen(prop) + '=' + prop;
}); // });
//
// const div = document.createElement('div');
// div.innerHTML = `
// <Modal${props} v-model="visible" :width="width" :scrollable="scrollable">
// <div class="${prefixCls}">
// <div class="${prefixCls}-head">
// <div class="${prefixCls}-head-title" v-html="title"></div>
// </div>
// <div class="${prefixCls}-body">
// <div :class="iconTypeCls"><i :class="iconNameCls"></i></div>
// <div v-html="body"></div>
// </div>
// <div class="${prefixCls}-footer">
// <i-button type="text" size="large" v-if="showCancel" @click.native="cancel">{{ localeCancelText }}</i-button>
// <i-button type="primary" size="large" :loading="buttonLoading" @click.native="ok">{{ localeOkText }}</i-button>
// </div>
// </div>
// </Modal>
// `;
// document.body.appendChild(div);
const div = document.createElement('div'); const Instance = new Vue({
div.innerHTML = `
<Modal${props} v-model="visible" :width="width" :scrollable="scrollable">
<div class="${prefixCls}">
<div class="${prefixCls}-head">
<div class="${prefixCls}-head-title" v-html="title"></div>
</div>
<div class="${prefixCls}-body">
<div :class="iconTypeCls"><i :class="iconNameCls"></i></div>
<div v-html="body"></div>
</div>
<div class="${prefixCls}-footer">
<i-button type="text" size="large" v-if="showCancel" @click.native="cancel">{{ localeCancelText }}</i-button>
<i-button type="primary" size="large" :loading="buttonLoading" @click.native="ok">{{ localeOkText }}</i-button>
</div>
</div>
</Modal>
`;
document.body.appendChild(div);
const modal = new Vue({
el: div,
mixins: [ Locale ], mixins: [ Locale ],
components: { Modal, iButton, Icon }, data: Object.assign({}, _props, {
data: Object.assign(_props, {
visible: false, visible: false,
width: 416, width: 416,
title: '', title: '',
@ -53,6 +49,87 @@ Modal.newInstance = properties => {
buttonLoading: false, buttonLoading: false,
scrollable: false scrollable: false
}), }),
render (h) {
let footerVNodes = [];
if (this.showCancel) {
footerVNodes.push(h(Button, {
props: {
type: 'text',
size: 'large'
},
on: {
click: this.cancel
}
}, this.localeCancelText));
}
footerVNodes.push(h(Button, {
props: {
type: 'primary',
size: 'large',
loading: this.buttonLoading
},
on: {
click: this.ok
}
}, this.localeOkText));
return h(Modal, {
props: Object.assign({}, _props, {
width: this.width,
scrollable: this.scrollable
}),
domProps: {
value: this.visible
},
on: {
input: (status) => {
this.visible = status;
}
}
}, [
h('div', {
attrs: {
class: prefixCls
}
}, [
h('div', {
attrs: {
class: `${prefixCls}-head`
}
}, h('div', {
attrs: {
class: `${prefixCls}-head-title`
},
domProps: {
innerHTML: this.title
}
})),
h('div', {
attrs: {
class: `${prefixCls}-body`
}
}, [
h('div', {
class: this.iconTypeCls
}, [
h('i', {
class: this.iconNameCls
})
]),
h('div', {
domProps: {
innerHTML: this.body
}
})
]),
h('div', {
attrs: {
class: `${prefixCls}-footer`
}
}, footerVNodes)
])
]);
},
computed: { computed: {
iconTypeCls () { iconTypeCls () {
return [ return [
@ -111,7 +188,11 @@ Modal.newInstance = properties => {
onCancel () {}, onCancel () {},
onRemove () {} onRemove () {}
} }
}).$children[0]; });
const component = Instance.$mount();
document.body.appendChild(component.$el);
const modal = Instance.$children[0];
return { return {
show (props) { show (props) {

View file

@ -1,5 +1,5 @@
<template> <template>
<div v-transfer-dom> <div>
<transition :name="transitionNames[1]"> <transition :name="transitionNames[1]">
<div :class="maskClasses" v-show="visible" @click="mask"></div> <div :class="maskClasses" v-show="visible" @click="mask"></div>
</transition> </transition>