element-ui按需引入踩的坑(Vue)

一、按需引入的步骤

1. 下载

npm i element-ui -S

2. 配置bable.config.js文件

{
/* "presets" 使用脚手架中自带的配置即可" */
"presets": [["es2015", { "modules": false }]],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}

3. 在main.js中导入需要的组件

例:引入Button组件

import { Button } from 'element-ui'; Vue.use(Button);

坑1:想要使用某个组件,有可能需要引入多个组件

import { Carousel } from 'element-ui'; Vue.use(Carousel); Vue.use(CarouselItem);

坑2:使用Vue.use()可能会出现bug,比如使用MessageBox组件时,使用Vue.use()会导致页面一刷新就弹框,此时应该用Vue.component()替代

import { MessageBox } from 'element-ui'; Vue.component(MessageBox.name, MessageBox)

二、MessageBox的简单使用

1. 建议使用前在main.js中先放入Vue的原型对象(如果是全局引入则已经自动完成这一步)

import { MessageBox } from 'element-ui';
Vue.component(MessageBox.name, MessageBox);
/* 这样就可以使用跟官网案例一样的变量名 */
Vue.prototype.$msgbox = MessageBox;
Vue.prototype.$alert = MessageBox.alert;
Vue.prototype.$confirm = MessageBox.confirm;
Vue.prototype.$prompt = MessageBox.prompt;

2. 官网案例 ”消息提示“

open() {
  this.$alert('这是一段内容', '标题名称', {
    confirmButtonText: '确定',
    /* 关闭弹窗后的回调,弹出用户选择结果(confirm | cancel等)的提示信息 */
    callback: action => {
      /* this.$message用的另一个组件Message,需要导入(必须使用Vue.component())才能使用 */
      this.$message({
        type: 'info',
        message: `action: ${ action }`
       });
     }
  });
}

3. 官网案例 "自定义"

(我代码中的)坑:点击触发事件的按钮后,弹框中的确认按钮不能自动获取焦点,焦点一直停留在触发事件的按钮上,导致按回车键时,效果不是关闭弹窗,而是不停的触发事件以致于一按回车就弹出一个框。

解决思路两个:1. 让触发事件的按钮禁用enter 2. 弹窗后更换焦点到框中确认按钮上

让触发事件的按钮禁用enter

<button @*click*="register" *onkeydown*="if(event.keyCode==13){return false;}">点击注册</button>

弹窗后更换焦点到框中确认按钮上,尝试在beforeClose回调中获取该按钮,再.focus,行不通,估计涉及到vue中dom操作被覆盖的问题。所以confirmButtonClass: 'mybtn'自定义了类名,然后获取该确认按钮对象,所以考虑放在Vue.nextTick()回调函数中的执行,即当数据更新了,在dom中渲染后,自动执行该函数中的.focus。因此想到用setTimeout来执行,因为是异步,会等主程序执行完毕后执行,故在这个全是同步操作的函数register中,会将所有主程序中的执行完了再.focus,这样有可能会避免操作被覆盖的情况,尝试后确实可以完成需求。

const h = this.$createElement;
        this.$msgbox({
          title: '提示信息',
          message:  h('p', {style: 'font-size: 16px;'},'验证码错误!'),
          confirmButtonText: '确定',
          closeOnClickModal: false,
          confirmButtonClass: 'mybtn',
          beforeClose: (action, instance, done) => {
            /* 下面注释的这条代码让确认按钮获取焦点 */
            // instance.$refs['confirm'].$el.focus;
            if (action === 'confirm') {
              // 注释掉的代码用于禁用enter确认(还没有发现是焦点的问题前,以为是enter导致的多次弹窗)
              /* instance.$refs['confirm'].$el.onclick = function(e) {
                 e = e || window.event;
                 // 如果不是键盘触发的事件(这里禁止enter进行确认)
                 if (e.detail !== 0) {
                   done();
                 }
                }(); */
              console.log('已经确认');
              done();
            } else {
              done();
            }
          }
        })
        setTimeout(() => {
          document.getElementsByClassName('mybtn')[0].focus();
        });

4.MessageBox相对完整的使用方式

this.$alert('请先登录', '提示', {
  confirmButtonText: '确定',
  showClose: false,
  type: 'warning'
}).catch(cancelMsg => {console.log(cancelMsg)}).then((confirmMsg) => {console.log(cancelMsg)});