1、页面报错 Uncaught ReferenceError: _Dialog is not defined

image.png
原因:

2、 按需引入组件,提示 Uncaught ReferenceError: _MessageBox is not defined

原因:未知,为element-ui 内部 BUG
解决:

  1. import Vue from 'vue';
  2. import { MessageBox } from "element-ui";
  3. const msgBox = MessageBox;
  4. Vue.prototype.$confirm = msgBox.confirm;
  5. // const { confirm } = msgBox
  6. // Vue.prototype.$confirm = confirm;

注意:

引入 MessageBox 组件之后,不要 Vue.use( MessageBox );

3、在element的select组件上扩展beforeSelect方法

定义

  1. import { Select } from 'element-ui';
  2. // 修改el-select,添加beforeOptionSelect回调
  3. const handleOptionSelect = Select.methods.handleOptionSelect
  4. // 给select添加beforeOptionSelect属性
  5. Select.props.beforeOptionSelect = {
  6. type: Function,
  7. default: function() {
  8. return function() {}
  9. }
  10. };
  11. // 修改select的handleOptionSelect方法,插入自己的逻辑
  12. Select.methods.handleOptionSelect = function(...args) {
  13. // 调用beforeOptionSelect回调,如果不返回false,则继续往下
  14. // 这里处理了异步和非异步的情况,我用到的是异步的情况
  15. if (this.beforeOptionSelect.length === 3) { // 第三个参数是一个回调,说明这是一个异步的操作,不能立马返回
  16. const cb = (res) => {
  17. if (res !== false) {
  18. handleOptionSelect.apply(this, args)
  19. } else {
  20. this.visible = false
  21. }
  22. }
  23. this.beforeOptionSelect(args[0].value, args[0].label, cb)
  24. } else if (this.beforeOptionSelect(args[0].value, args[0].label) !== false) {
  25. handleOptionSelect.apply(this, args)
  26. } else {
  27. this.visible = false
  28. }
  29. }

使用

  1. <template>
  2. <el-select v-else :beforeOptionSelect="beforeOptionSelect" >
  3. <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
  4. </el-select>
  5. </template>

4、在Select 组件上扩展,滚动加载更多的功能

定义扩展

  1. export default {
  2. directives: {
  3. "loadmore": {
  4. bind(el, binding) {
  5. // 获取element-ui定义好的scroll盒子
  6. const SELECTWRAP_DOM = el.querySelector(
  7. ".el-select-dropdown .el-select-dropdown__wrap"
  8. );
  9. SELECTWRAP_DOM.addEventListener("scroll", function () {
  10. const condition =
  11. this.scrollHeight - this.scrollTop <= this.clientHeight;
  12. if (condition) {
  13. binding.value();
  14. }
  15. });
  16. },
  17. },
  18. },
  19. props:{},
  20. }

使用:

  1. <el-select v-if="isScroll" v-el-select-loadmore="load">
  2. <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
  3. <template #empty>
  4. <slot name="empty"></slot>
  5. </template>
  6. </el-select>

5、Element-ui换主题 得注意引用顺序

1、新建 element-variables.scss

  1. /* 改变主题色变量 */
  2. $--color-primary:#262DD9;
  3. /* 改变 icon 字体路径变量,必需 */
  4. $--font-path: '~element-ui/lib/theme-chalk/fonts';
  5. @import "~element-ui/packages/theme-chalk/src/index";

2、引用

  1. // 按需引入element-ui中的组件
  2. import element from './elementComponent';
  3. Vue.use(element);
  4. // 这里必须得先Use,再引入样式文件, 不然自定义的主题色会被默认的样式覆盖
  5. import '@/assets/style/element-variables.scss';

6、loading 按需加载,提示 loading.service is not function

7、v-for 渲染数组,结果只渲染数组的最后一项

场景:
封装 element-uitable 组件的 操作列,操作列的按钮需要循环生成,于是有了以下代码

  1. <template v-for="(item, index) in handleAttribute(rowHandle.custom, [])" slot-scope="scope">
  2. <el-button
  3. :key="index"
  4. v-if="handleRowHandleShow(item.show, scope.$index, scope.row) && handleAttribute(item.name,'') === 'el-button' "
  5. :disabled="handleRowHandleDisabled(item.disabled, scope.$index, scope.row)"
  6. v-bind="item"
  7. @click="$emit(item.emit, {index: scope.$index, row: scope.row})"
  8. >
  9. <template>
  10. {{ item.formatter ? item.formatter(scope.row, scope.column, item.text, scope.$index) : item.text }}
  11. </template>
  12. </el-button>
  13. <el-switch
  14. :key="index"
  15. v-if="handleRowHandleShow(item.show, scope.$index, scope.row) && handleAttribute(item.name,'') === 'el-switch' "
  16. :disabled="handleRowHandleDisabled(item.disabled, scope.$index, scope.row)"
  17. v-bind="item"
  18. @change="$emit(item.emit, {index: scope.$index, row: scope.row})"
  19. >
  20. {{item.text}}
  21. </el-switch>
  22. </template>
  23. <script>
  24. export default {
  25. data() {
  26. return {
  27. rowHandle: {
  28. align: "left",
  29. rowKey: "counterId",
  30. label: "操作",
  31. minWidth: this.screenWidth > 1500 ? '136' : '155',
  32. custom: [{
  33. name: 'el-button',
  34. class: "fun-btn",
  35. type: "text",
  36. text: "停用",
  37. show: () => {
  38. return this.hasCounterActiveRights;
  39. },
  40. formatter: (row, column, text) => {
  41. return row.activeStatus === 1 ? "停用" : "激活"
  42. },
  43. emit: 'toggleStatus',
  44. }, {
  45. name: 'el-button',
  46. class: "fun-btn",
  47. type: "text",
  48. text: "编辑",
  49. show: () => {
  50. return this.hasCounterMgrRights
  51. },
  52. disabled(index, row) {
  53. return row.type === 1 ||
  54. row.activeStatus == 1
  55. },
  56. emit: 'edit',
  57. }, {
  58. name: 'el-button',
  59. class: "fun-btn",
  60. type: "text",
  61. text: "删除",
  62. show: () => {
  63. return this.hasCounterMgrRights
  64. },
  65. disabled(index, row) {
  66. return row.type === 1 || row.activeStatus == 1
  67. },
  68. emit: 'delete',
  69. }, {
  70. name: 'el-button',
  71. class: "fun-btn",
  72. type: "text",
  73. text: "查询",
  74. show: () => {
  75. return this.hasCounterMgrRights || this.hasCounterActiveRights
  76. },
  77. disabled(index, row) {
  78. return row.activeStatus !== 1
  79. },
  80. emit: 'goPage',
  81. }]
  82. },
  83. }
  84. }
  85. }
  86. </script>

现象:
按钮只渲染了最后一项“查询”

排查:
由于循环内使用了 v-if 条件渲染,担心是这个影响,于是,先将 v-if 进行注释,发现数组内最开始的几项数据内的函数有没有渲染也没有调用。后来无奈只能一行行注释,看是哪一行代码影响了渲染,最后注释了 template 上的 slot-scope="scope" 之后,发现数组数量渲染正常。

解决:

  1. <template slot-scope="scope">
  2. <template v-for="(item, index) in handleAttribute(rowHandle.custom, [])">
  3. ......
  4. </template>
  5. </template>