确认框是elementui最常用的组件之一,如何定制它呢?

下面这个例子是客户提出要用左右箭头键来控制按钮的焦点,使用键盘操控达到的提高办公效率的目的。
要实现这个目标有2种方法
1.修改elementui的源代码
2.对elementui的代码进行包装,添加键盘控制的功能
第一种方法需要读懂源代码花时间,而且不支持源代码升级,所以采取第二种办法。
如果你完整引入了 Element,它会为 Vue.prototype 添加如下全局方法:$msgbox, $alert, $confirm 和 $prompt。
通常这样使用:this.$confirm(message, title, options)
所以只要替换全局方法$confirm就达到包装的目的
包装$confirm组件
- import Vue from 'vue'
-
- var cancelButtonClass
- var confirmButtonClass
- var beforeCloseOrigin
-
- function select(index) {
- var buttons = document.querySelectorAll('.el-message-box__wrapper .el-message-box__btns button')
-
- if (buttons.length !== 2) return
-
- if (cancelButtonClass == null) {
- cancelButtonClass = buttons[0].getAttribute('class')
- confirmButtonClass = buttons[1].getAttribute('class')
- }
-
- buttons[0].setAttribute('class', index === 0 ? confirmButtonClass : cancelButtonClass)
- buttons[1].setAttribute('class', index === 1 ? confirmButtonClass : cancelButtonClass)
- buttons[index].focus()
- }
- function keyDownHandler(e) {
- if (e.shiftKey && e.code === 'Tab' || e.code === 'ArrowLeft') {
- select(0)
- e.preventDefault()
- } else if (!e.shiftKey && e.code === 'Tab' || e.code === 'ArrowRight') {
- select(1)
- e.preventDefault()
- }
- }
- function beforeClose(action, instance, done) {
- document.removeEventListener('keydown', keyDownHandler, false)
- select(1)
- if (beforeCloseOrigin) {
- beforeCloseOrigin(action, instance, done)
- } else {
- done()
- }
- }
-
- function confirm(message, title, options) {
- cancelButtonClass = null
- confirmButtonClass = null
-
- var newTitle
- var newOptions
- if (typeof title !== 'string') {
- newTitle = ''
- newOptions = { ...title }
- } else {
- newTitle = title
- newOptions = { ...options }
- }
-
- beforeCloseOrigin = newOptions.beforeClose
-
- newOptions.beforeClose = beforeClose
-
- document.addEventListener('keydown', keyDownHandler, false)
- return Vue.prototype.$confirmOrigin.call(this, message, newTitle, newOptions)
- }
-
- export default function replaceConfirm() {
- Vue.prototype.$confirmOrigin = Vue.prototype.$confirm
- Vue.prototype.$confirm = confirm
- }
-
新组件的核心思想是通过document.querySelectorAll来找到dom,然后操作dom来达到定制的目的。确认框是动态生成的,有模式的,所以用document.querySelectorAll能找到唯一的dom。监听键盘事件就可以达到键盘操控的目的,关闭的时候需要注销监听。
main.js
- import Vue from 'vue'
- import Element from 'element-ui'
- ...
-
- // 引入confirm新组件
- import replaceConfirm from '@/components/confirm'
-
-
- ...
-
-
- // 替换confirm组件
- replaceConfirm()
-
- new Vue({
- el: '#app',
- router,
- store,
- render: h => h(App)
- })
在main.js中导入新组件,本来可以直接import '@/components/confirm',但是this.$confirm是异步完成的,直接调用发现this.$confirm还没有初始化,所以改成2步替换,目的就是等待this.$confirm完成初始化。