mirror of https://github.com/ElemeFE/element
Merge pull request #2204 from Leopoldthecoder/messagebox
MessageBox: add beforeClosepull/2419/head^2
commit
402aebcd83
|
@ -64,7 +64,21 @@
|
||||||
message: 'This is a message',
|
message: 'This is a message',
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: 'OK',
|
||||||
cancelButtonText: 'Cancel'
|
cancelButtonText: 'Cancel',
|
||||||
|
beforeClose: (action, instance, done) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
instance.confirmButtonLoading = true;
|
||||||
|
instance.confirmButtonText = 'Loading...';
|
||||||
|
setTimeout(() => {
|
||||||
|
done();
|
||||||
|
setTimeout(() => {
|
||||||
|
instance.confirmButtonLoading = false;
|
||||||
|
}, 300);
|
||||||
|
}, 3000);
|
||||||
|
} else {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
}).then(action => {
|
}).then(action => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$message({
|
this.$message({
|
||||||
|
@ -194,7 +208,7 @@ Prompt is used when user input is required.
|
||||||
|
|
||||||
Can be customized to show various content.
|
Can be customized to show various content.
|
||||||
|
|
||||||
:::demo The three methods mentioned above are repackagings of the `$msgbox` method. This example calls `$msgbox` method directly using the `showCancelButton` attribute, which is used to indicate if a cancel button is displayed. Besides we can use `cancelButtonClass` to add a custom style and `cancelButtonText` to customize the button text. The confirm button also has these fields. A complete list of fields can be found at the end of this documentation.
|
:::demo The three methods mentioned above are repackagings of the `$msgbox` method. This example calls `$msgbox` method directly using the `showCancelButton` attribute, which is used to indicate if a cancel button is displayed. Besides we can use `cancelButtonClass` to add a custom style and `cancelButtonText` to customize the button text (the confirm button also has these fields, and a complete list of fields can be found at the end of this documentation). This example also uses the `beforeClose` attribute. It is a method and will be triggered when the MessageBox instance will be closed, and its execution will stop the instance from closing. It has three parameters: `action`, `instance` and `done`. Using it enables you to manipulate the instance before it closes, e.g. activating `loading` for confirm button; you can invoke the `done` method to close the MessageBox instance (if `done` is not called inside `beforeClose`, the instance will not be closed).
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<template>
|
<template>
|
||||||
|
@ -210,7 +224,21 @@ Can be customized to show various content.
|
||||||
message: 'This is a message',
|
message: 'This is a message',
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: 'OK',
|
||||||
cancelButtonText: 'Cancel'
|
cancelButtonText: 'Cancel',
|
||||||
|
beforeClose: (action, instance, done) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
instance.confirmButtonLoading = true;
|
||||||
|
instance.confirmButtonText = 'Loading...';
|
||||||
|
setTimeout(() => {
|
||||||
|
done();
|
||||||
|
setTimeout(() => {
|
||||||
|
instance.confirmButtonLoading = false;
|
||||||
|
}, 300);
|
||||||
|
}, 3000);
|
||||||
|
} else {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
}).then(action => {
|
}).then(action => {
|
||||||
this.$message({
|
this.$message({
|
||||||
type: 'info',
|
type: 'info',
|
||||||
|
@ -246,7 +274,8 @@ The corresponding methods are: `MessageBox`, `MessageBox.alert`, `MessageBox.con
|
||||||
| message | content of the MessageBox | string | — | — |
|
| message | content of the MessageBox | string | — | — |
|
||||||
| type | message type, used for icon display | string | success/info/warning/error | — |
|
| type | message type, used for icon display | string | success/info/warning/error | — |
|
||||||
| customClass | custom class name for MessageBox | string | — | — |
|
| customClass | custom class name for MessageBox | string | — | — |
|
||||||
| callback | MessageBox closing callback if you don't prefer Promise | function(action), where action can be 'confirm' or 'cancel' | — | — |
|
| callback | MessageBox closing callback if you don't prefer Promise | function(action), where action can be 'confirm' or 'cancel', and `instance` is the MessageBox instance. You can access to that instance's attributes and methods | — | — |
|
||||||
|
| beforeClose | callback before MessageBox closes, and it will prevent MessageBox from closing | function(action, instance, done), where `action` can be 'confirm' or 'cancel'; `instance` is the MessageBox instance, and you can access to that instance's attributes and methods; `done` is for closing the instance | — | — |
|
||||||
| lockScroll | whether to lock body scroll when MessageBox prompts | boolean | — | true |
|
| lockScroll | whether to lock body scroll when MessageBox prompts | boolean | — | true |
|
||||||
| showCancelButton | whether to show a cancel button | boolean | — | false (true when called with confirm and prompt) |
|
| showCancelButton | whether to show a cancel button | boolean | — | false (true when called with confirm and prompt) |
|
||||||
| showConfirmButton | whether to show a confirm button | boolean | — | true |
|
| showConfirmButton | whether to show a confirm button | boolean | — | true |
|
||||||
|
|
|
@ -65,7 +65,21 @@
|
||||||
message: '这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容',
|
message: '这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容',
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消'
|
cancelButtonText: '取消',
|
||||||
|
beforeClose: (action, instance, done) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
instance.confirmButtonLoading = true;
|
||||||
|
instance.confirmButtonText = '执行中...';
|
||||||
|
setTimeout(() => {
|
||||||
|
done();
|
||||||
|
setTimeout(() => {
|
||||||
|
instance.confirmButtonLoading = false;
|
||||||
|
}, 300);
|
||||||
|
}, 3000);
|
||||||
|
} else {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
}).then(action => {
|
}).then(action => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$message({
|
this.$message({
|
||||||
|
@ -191,7 +205,7 @@
|
||||||
|
|
||||||
可自定义配置不同内容。
|
可自定义配置不同内容。
|
||||||
|
|
||||||
:::demo 以上三个方法都是对`$msgbox`方法的再包装。本例直接调用`$msgbox`方法,使用了`showCancelButton`字段,用于显示取消按钮。另外可使用`cancelButtonClass`为其添加自定义样式,使用`cancelButtonText`来自定义按钮文本。Confirm 按钮也具有相同的字段,在文末的字段说明中有完整的字段列表。
|
:::demo 以上三个方法都是对`$msgbox`方法的再包装。本例直接调用`$msgbox`方法,使用了`showCancelButton`字段,用于显示取消按钮。另外可使用`cancelButtonClass`为其添加自定义样式,使用`cancelButtonText`来自定义按钮文本(Confirm 按钮也具有相同的字段,在文末的字段说明中有完整的字段列表)。此例还使用了`beforeClose`属性,它的值是一个方法,会在 MessageBox 的实例关闭前被调用,同时暂停实例的关闭。它有三个参数:`action`、实例本身和`done`方法。使用它能够在关闭前对实例进行一些操作,比如为确定按钮添加`loading`状态等;此时若需要关闭实例,可以调用`done`方法(若在`beforeClose`中没有调用`done`,则实例不会关闭)。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<template>
|
<template>
|
||||||
|
@ -207,7 +221,21 @@
|
||||||
message: '这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容',
|
message: '这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容, 这是一段内容',
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消'
|
cancelButtonText: '取消',
|
||||||
|
beforeClose: (action, instance, done) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
instance.confirmButtonLoading = true;
|
||||||
|
instance.confirmButtonText = '执行中...';
|
||||||
|
setTimeout(() => {
|
||||||
|
done();
|
||||||
|
setTimeout(() => {
|
||||||
|
instance.confirmButtonLoading = false;
|
||||||
|
}, 300);
|
||||||
|
}, 3000);
|
||||||
|
} else {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
}).then(action => {
|
}).then(action => {
|
||||||
this.$message({
|
this.$message({
|
||||||
type: 'info',
|
type: 'info',
|
||||||
|
@ -243,7 +271,8 @@ import { MessageBox } from 'element-ui';
|
||||||
| message | MessageBox 消息正文内容 | string | — | — |
|
| message | MessageBox 消息正文内容 | string | — | — |
|
||||||
| type | 消息类型,用于显示图标 | string | success/info/warning/error | — |
|
| type | 消息类型,用于显示图标 | string | success/info/warning/error | — |
|
||||||
| customClass | MessageBox 的自定义类名 | string | — | — |
|
| customClass | MessageBox 的自定义类名 | string | — | — |
|
||||||
| callback | 若不使用 Promise,可以使用此参数指定 MessageBox 关闭后的回调 | function(action),action 的值为'confirm'或'cancel' | — | — |
|
| callback | 若不使用 Promise,可以使用此参数指定 MessageBox 关闭后的回调 | function(action, instance),action 的值为'confirm'或'cancel', instance 为 MessageBox 实例,可以通过它访问实例上的属性和方法 | — | — |
|
||||||
|
| beforeClose | MessageBox 关闭前的回调,会暂停实例的关闭 | function(action, instance, done),action 的值为'confirm'或'cancel';instance 为 MessageBox 实例,可以通过它访问实例上的属性和方法;done 用于关闭 MessageBox 实例 | — | — |
|
||||||
| lockScroll | 是否在 MessageBox 出现时将 body 滚动锁定 | boolean | — | true |
|
| lockScroll | 是否在 MessageBox 出现时将 body 滚动锁定 | boolean | — | true |
|
||||||
| showCancelButton | 是否显示取消按钮 | boolean | — | false(以 confirm 和 prompt 方式调用时为 true) |
|
| showCancelButton | 是否显示取消按钮 | boolean | — | false(以 confirm 和 prompt 方式调用时为 true) |
|
||||||
| showConfirmButton | 是否显示确定按钮 | boolean | — | true |
|
| showConfirmButton | 是否显示确定按钮 | boolean | — | true |
|
||||||
|
|
|
@ -20,7 +20,8 @@ const defaults = {
|
||||||
confirmButtonText: '',
|
confirmButtonText: '',
|
||||||
cancelButtonText: '',
|
cancelButtonText: '',
|
||||||
confirmButtonClass: '',
|
confirmButtonClass: '',
|
||||||
cancelButtonClass: ''
|
cancelButtonClass: '',
|
||||||
|
beforeClose: null
|
||||||
};
|
};
|
||||||
|
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
|
@ -15,8 +15,21 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="el-message-box__btns">
|
<div class="el-message-box__btns">
|
||||||
<el-button :class="[ cancelButtonClasses ]" v-show="showCancelButton" @click.native="handleAction('cancel')">{{ cancelButtonText || t('el.messagebox.cancel') }}</el-button>
|
<el-button
|
||||||
<el-button ref="confirm" :class="[ confirmButtonClasses ]" v-show="showConfirmButton" @click.native="handleAction('confirm')">{{ confirmButtonText || t('el.messagebox.confirm') }}</el-button>
|
:loading="cancelButtonLoading"
|
||||||
|
:class="[ cancelButtonClasses ]"
|
||||||
|
v-show="showCancelButton"
|
||||||
|
@click.native="handleAction('cancel')">
|
||||||
|
{{ cancelButtonText || t('el.messagebox.cancel') }}
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
:loading="confirmButtonLoading"
|
||||||
|
ref="confirm"
|
||||||
|
:class="[ confirmButtonClasses ]"
|
||||||
|
v-show="showConfirmButton"
|
||||||
|
@click.native="handleAction('confirm')">
|
||||||
|
{{ confirmButtonText || t('el.messagebox.confirm') }}
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -79,7 +92,16 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
getSafeClose() {
|
||||||
|
const currentId = this.uid;
|
||||||
|
return () => {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (currentId === this.uid) this.doClose();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},
|
||||||
doClose() {
|
doClose() {
|
||||||
|
if (!this.value) return;
|
||||||
this.value = false;
|
this.value = false;
|
||||||
this._closing = true;
|
this._closing = true;
|
||||||
|
|
||||||
|
@ -100,11 +122,13 @@
|
||||||
if (!this.transition) {
|
if (!this.transition) {
|
||||||
this.doAfterClose();
|
this.doAfterClose();
|
||||||
}
|
}
|
||||||
|
if (this.action) this.callback(this.action, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
handleWrapperClick() {
|
handleWrapperClick() {
|
||||||
if (this.closeOnClickModal) {
|
if (this.closeOnClickModal) {
|
||||||
this.close();
|
this.action = '';
|
||||||
|
this.doClose();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -112,9 +136,13 @@
|
||||||
if (this.$type === 'prompt' && action === 'confirm' && !this.validate()) {
|
if (this.$type === 'prompt' && action === 'confirm' && !this.validate()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var callback = this.callback;
|
this.action = action;
|
||||||
this.value = false;
|
if (typeof this.beforeClose === 'function') {
|
||||||
callback(action);
|
this.close = this.getSafeClose();
|
||||||
|
this.beforeClose(action, this, this.close);
|
||||||
|
} else {
|
||||||
|
this.doClose();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
validate() {
|
validate() {
|
||||||
|
@ -153,6 +181,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
value(val) {
|
value(val) {
|
||||||
|
if (val) this.uid++;
|
||||||
if (this.$type === 'alert' || this.$type === 'confirm') {
|
if (this.$type === 'alert' || this.$type === 'confirm') {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.confirm.$el.focus();
|
this.$refs.confirm.$el.focus();
|
||||||
|
@ -174,6 +203,7 @@
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
uid: 1,
|
||||||
title: undefined,
|
title: undefined,
|
||||||
message: '',
|
message: '',
|
||||||
type: '',
|
type: '',
|
||||||
|
@ -186,8 +216,11 @@
|
||||||
inputErrorMessage: '',
|
inputErrorMessage: '',
|
||||||
showConfirmButton: true,
|
showConfirmButton: true,
|
||||||
showCancelButton: false,
|
showCancelButton: false,
|
||||||
|
action: '',
|
||||||
confirmButtonText: '',
|
confirmButtonText: '',
|
||||||
cancelButtonText: '',
|
cancelButtonText: '',
|
||||||
|
confirmButtonLoading: false,
|
||||||
|
cancelButtonLoading: false,
|
||||||
confirmButtonClass: '',
|
confirmButtonClass: '',
|
||||||
confirmButtonDisabled: false,
|
confirmButtonDisabled: false,
|
||||||
cancelButtonClass: '',
|
cancelButtonClass: '',
|
||||||
|
|
|
@ -142,16 +142,38 @@ describe('MessageBox', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('callback', done => {
|
it('callback', done => {
|
||||||
|
let msgAction = '';
|
||||||
MessageBox({
|
MessageBox({
|
||||||
title: '消息',
|
title: '消息',
|
||||||
message: '这是一段内容'
|
message: '这是一段内容'
|
||||||
}, action => {
|
}, action => {
|
||||||
expect(action).to.equal('cancel');
|
msgAction = action;
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.querySelector('.el-message-box__close').click();
|
document.querySelector('.el-message-box__close').click();
|
||||||
}, 300);
|
expect(msgAction).to.equal('cancel');
|
||||||
|
done();
|
||||||
|
}, 50);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('beforeClose', done => {
|
||||||
|
let msgAction = '';
|
||||||
|
MessageBox({
|
||||||
|
title: '消息',
|
||||||
|
message: '这是一段内容',
|
||||||
|
beforeClose: (action, instance) => {
|
||||||
|
instance.close();
|
||||||
|
}
|
||||||
|
}, action => {
|
||||||
|
msgAction = action;
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
document.querySelector('.el-message-box__wrapper .el-button--primary').click();
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(msgAction).to.equal('confirm');
|
||||||
|
done();
|
||||||
|
}, 10);
|
||||||
|
}, 10);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('promise', () => {
|
describe('promise', () => {
|
||||||
|
@ -162,9 +184,8 @@ describe('MessageBox', () => {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.querySelector('.el-message-box__wrapper')
|
document.querySelector('.el-message-box__wrapper .el-button--primary').click();
|
||||||
.querySelector('.el-button--primary').click();
|
}, 50);
|
||||||
}, 300);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('reject', done => {
|
it('reject', done => {
|
||||||
|
@ -174,9 +195,8 @@ describe('MessageBox', () => {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.querySelector('.el-message-box__wrapper')
|
document.querySelector('.el-message-box__wrapper .el-button').click();
|
||||||
.querySelector('.el-button').click();
|
}, 50);
|
||||||
}, 300);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue