This article mainly talks about how to modify the default properties of ElementUI's Dialog and MessageBox. Mainly include the following aspects:
- Introduction to Dialog and MessageBox;
- Modify the default properties of a single call;
- Modify the default properties globally:
3.1 Dialog modify the default properties globally;
3.2 MessageBox modify the default properties globally.
The following example takes the modification of close-on-click-modal
attribute as an example to explain. The default value of this property is true
, that is, the pop-up box is closed when the mask is clicked. In actual projects, we generally don't want this default behavior, so take this attribute as an example.
Introduction to Dialog and MessageBox
Dialog is a component Component .
Although the name MessageBox looks like a component name at first glance, it is a method name .
I tried to guess why the MessageBox was not made into a component. According to the introduction on the official website:
A set of modal boxes simulating system message box, mainly for alerting information, confirm operations and prompting messages.
MessageBox is mainly to imitate the native bullet frame of the system, and the API of the native bullet frame of the system is window.alert
, window.confirm
and window.prompt
, these are all methods. Therefore, it may be in order to maintain a consistent usage method with the native API, so MessageBox has been made into corresponding methods: MessageBox.alert, MessageBox.confirm and MessageBox.prompt. ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? In addition, there is a basic MessageBox method that can also be called. These four methods are also mounted on the Vue prototype, which are $alert, $confirm, $prompt and $msgbox:
Native API | MessageBox method name | Vue instance method name |
---|---|---|
- | MessageBox | $msgbox |
window.alert | MessageBox.alert | $alert |
window.confirm | MessageBox.confirm | $confirm |
window.prompt | MessageBox.prompt | $prompt |
Just because Dialog and MessageBox are different in nature, the way to modify the default properties is also different. The two types will be explained separately below.
Modify the default properties of a single call
It is relatively simple to modify the default attributes of a single call. The Dialog component is modified by attributes: close-on-click-modal
<el-dialog
...
:close-on-click-modal="false">
...
</el-dialog>
MessageBox is modified by passing parameters:
// $alert, $confirm, $prompt方法与下面类似
this.$msgbox({
...
closeOnClickModal: false
})
Modify the default properties globally
Here, let me first talk about my ideas for solving this problem:
- Direct search, you can find solutions for most problems;
- If you can't find it or the method of others is not applicable, check the source code.
I have a habit. If the development time is still ample, even if I find a ready-made solution, I will still compare the source code to explore why this solution is feasible. The following solutions have been verified against the source code, so I will directly compare the source code to the solution and the location of the corresponding source code.
The source code involved in this article takes the v2.15.1 version as an example.
Dialog modify the default properties globally
Dialog Component Source is located /packages/dialog
folder below GitHub address .
Checking the /packages/dialog/component.vue file will find that closeOnClickModal
is a props:
props: {
// ...
closeOnClickModal: {
type: Boolean,
default: true // 默认值是true
},
// ...
}
The global modification method is as follows:
import Element from 'element-ui'
Element.Dialog.props.closeOnClickModal.default = false
MessageBox modify the default properties globally
First look at the code related to MessageBox in the /src/index.js
// ...
import MessageBox from '../packages/message-box/index.js';
// ...
const install = function(Vue, opts = {}) {
// ...
Vue.prototype.$msgbox = MessageBox; // 对应于上面表格中的对应关系:MessageBox => $msgbox
Vue.prototype.$alert = MessageBox.alert; // 对应于上面表格中的对应关系:MessageBox.alert => $alert
Vue.prototype.$confirm = MessageBox.confirm; // 对应于上面表格中的对应关系:Message.confirm => $confirm
Vue.prototype.$prompt = MessageBox.prompt; // 对应于上面表格中的对应关系:MessageBox.prompt => $prompt
// ...
}
export default {
// ...
MessageBox,
// ...
}
Next, look at the definition file /packages/message-box/src/main.js of MessageBox. MessageBox accepts two parameters: options
and callback
. The literal meaning should be the configuration object and the callback function:
const MessageBox = function(options, callback) {
// ...
};
I used $msgbox
, so my first thought was to modify the $msgbox
method and add custom parameters when calling MessageBox:
import Element from 'element-ui'
import Vue from 'vue'
Vue.prototype.$msgbox = function (options, ...args) {
options = Object.assign({
closeOnClickModal: false
}, options)
Element.MessageBox(options, ...args)
}
I tested it and there was no problem, but I looked at the source code carefully and found that options
is not necessarily an object, but can also be a string:
const MessageBox = function(options, callback) {
if (Vue.prototype.$isServer) return;
if (typeof options === 'string' || isVNode(options)) { // 第一个参数是字符串的时候,当作message
options = {
message: options
};
if (typeof arguments[1] === 'string') { // 第二个参数是字符串的时候,当作title
options.title = arguments[1];
}
} else if (options.callback && !callback) {
callback = options.callback;
}
// ...
}
There is no problem in my test, because when I call options
is used as an object. So this solution is a limited solution, not universal. The main problems are as follows:
options
must be in the form of an object;- If you use
$alert
,$confirm
,$prompt
and other methods, you need to do similar processing, the code is more verbose; - It can only be
$msgbox
. If you callMessageBox
directly, it will not apply, because I did not modifyMessageBox
.
Based on question 1, you can create an appropriate option like the analysis parameter in the MessageBox source code, and then pass it to the MessageBox. Based on question 3, no good solution has been thought of for the time being.
Considering that the project is the result of teamwork, in case a classmate calls $msgbox
when the first parameter is not an object, or MessageBox
, I am considering whether there is a better solution. Looking closely at the source code, I found a simpler API:
MessageBox.setDefaults = defaults => {
MessageBox.defaults = defaults;
};
Look again at the source code of the MessageBox function:
const MessageBox = function(options, callback) {
// ...
if (typeof Promise !== 'undefined') {
return new Promise((resolve, reject) => { // eslint-disable-line
msgQueue.push({
options: merge({}, defaults, MessageBox.defaults, options), // 注意这一行
callback: callback,
resolve: resolve,
reject: reject
});
showNextMsg();
});
} else {
msgQueue.push({
options: merge({}, defaults, MessageBox.defaults, options), // 注意这一行
callback: callback
});
showNextMsg();
}
};
Through options
parameters above, we can give the options a priority:
函数调用时传入的options > MessageBox.defaults > 组件默认值options
Therefore, modifying MessageBox.defaults
can achieve our purpose:
import Element from 'element-ui'
Element.MessageBox.setDefaults({
closeOnClickModal: false
})
Of course, this method is not perfect. The problems are as follows:
- The introduction of this API has not been found in the official documentation. This unofficial API heavily dependent on . The official should not guarantee the stability and correctness of this API in subsequent iterations;
- When MessageBox.alert calls Message, several default properties are overwritten by default. These properties
MessageBox.setDefaults
method. For example, set the closeOnClickModal of the alert box to true:
MessageBox.alert = (message, title, options) => {
// ...
return MessageBox(merge({
// ...
closeOnPressEscape: false,
closeOnClickModal: false // 调用MessageBox时传入的options会覆盖MessageBox.defaults
}, options));
};
After exploring here, for me, MessageBox.setDefaults
already considered a better solution, so I will not continue to explore.
If you have higher requirements, such as fixing problem 2, keep it simple, you can override this default method or explore a solution that is more suitable for you.
to sum up
I hope everyone can gain something. If there are any errors, please leave a message for discussion.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。