当前位置:   article > 正文

使用 ElementPlus 组件时,遇到的一些问题及解决方案_elementplustype "password" is not assignable to ty

elementplustype "password" is not assignable to type const state = torefs(re

目录

1. el-form 表单相关问题

1.1 使用 el-form 表单校验规则,无法对 number 类型输入框校验

1.2 隐藏后重新显示的 el-input 无法自动获得焦点(双击实现输入框编辑)

2. el-table 表格相关问题

2.1 解决 el-table 某列内容长度超过列宽,默认换行问题

2.2 el-table 滚动条导致的行对不齐问题

2.3 实现 el-table 隔行变色(ts 数据类型定义)

3. el-popover 组件内部添加注释导致的问题


1. el-form 表单相关问题

1.1 使用 el-form 表单校验规则,无法对 number 类型输入框校验

  1. <el-form :rules="rules" :model="scheduleFormLabel">
  2. <el-form-item label="活动人数:" required prop="peopleNum">
  3. <el-input
  4. type="number"
  5. placeholder="请输入活动人数"
  6. v-model="scheduleFormLabel.peopleNum"
  7. />
  8. <template #suffix>
  9. <span class="t-white t-f12"></span>
  10. </template>
  11. </el-input>
  12. </el-form-item>
  13. </el-form>
  1. rules: {
  2. peopleNum: [
  3. {
  4. required: true, message: '', trigger: 'blur',
  5. },
  6. {
  7. type: 'number',
  8. min: 1,
  9. max: 100000,
  10. message: '活动人数应该在1-100000之间',
  11. trigger: 'blur',
  12. },
  13. ],
  14. },

解决方案:给 v-model 加上 .number 即可

<el-input v-model.number="scheduleFormLabel.peopleNum"></el-input>

1.2 隐藏后重新显示的 el-input 无法自动获得焦点(双击实现输入框编辑)

需求:这有一个菜单树,双击菜单项文本后,编辑菜单项名称

实现逻辑:

  • 双击菜单文本时,会触发方法 @dblclick="handleDoubleClickMenuText()" ,该方法记录当前点击的菜单项id,并触发视图更新(当前菜单项id为记录的菜单id时,就会展示输入框,隐藏文本)
  • 通过设置 ref 变量,让输入框获得焦点 menuItemTextInputRef.value.focus(); 输入框实际却没获得
  1. <template>
  2. <el-tree
  3. node-key="id"
  4. :props="propsMap"
  5. :data="state.data"
  6. >
  7. <template #default=" {node, data} ">
  8. <span>
  9. <!-- 节点文本 -->
  10. <span
  11. v-show="state.operateMenuItemId !== data.id"
  12. @dblclick="handleDoubleClickMenuText(data.id, data.id)"
  13. >
  14. {{node.label}}
  15. </span>
  16. <!-- 编辑节点文本的输入框 仅在双击文本的时候展示 -->
  17. <el-input
  18. v-model="data.label"
  19. v-show="state.operateMenuItemId === data.id"
  20. ref="menuItemTextInputRef"
  21. @blur="handleDoubleClickMenuText('', data.id)"
  22. />
  23. </span>
  24. </template>
  25. </el-tree>
  26. </template>
  27. <script lang="ts" setup>
  28. import {
  29. reactive,
  30. ref,
  31. } from 'vue';
  32. import { MenuTreeData } from '@/types/common/menu-tree';
  33. import { ElInput } from 'element-plus';
  34. // 配置选项的映射
  35. const propsMap = {
  36. children: 'children',
  37. label: 'label',
  38. };
  39. const state = reactive({
  40. // 树形菜单数据
  41. data: [
  42. {
  43. id: 'a1',
  44. label: '菜单1',
  45. children: [
  46. {
  47. id: 'aa1',
  48. label: '菜单1.1',
  49. },
  50. {
  51. id: 'ab1',
  52. label: '菜单1.2',
  53. children: [
  54. {
  55. id: 'aba1',
  56. label: '菜单1.2.1',
  57. },
  58. ],
  59. },
  60. ],
  61. },
  62. {
  63. id: 'b1',
  64. label: '菜单2',
  65. },
  66. //...
  67. ] as MenuTreeData[],
  68. // 当前操作的菜单项的id
  69. operateMenuItemId: '',
  70. });
  71. // 菜单项文本输入框DOM
  72. const menuItemTextInputRef = ref();
  73. /**
  74. * 处理双击菜单项文本
  75. * @param id - 菜单项id
  76. */
  77. function handleDoubleClickMenuText(id: string) {
  78. state.operateMenuItemId = id;
  79. if (menuItemTextInputRef.value) {
  80. menuItemTextInputRef.value.focus();
  81. }
  82. }
  83. </script>

原因分析:

  • 渲染页面时,随着el-tree节点的遍历,会渲染多个el-input节点(因为使用了 v-show,节点存在,只是看不见)
  • 也就是说,页面里有多个 el-input,ref 被赋值了很多次,最终值是最后的一个el-input(果然,双击最后一个菜单项文本时,输入框获取到了焦点)

问题解决:

为了确保 el-input 只渲染一次(只存在一个有 ref="menuItemTextInputRef" 属性的 el-input),应该采用 v-if 替代 v-show

  1. <template>
  2. <el-tree
  3. node-key="id"
  4. :props="propsMap"
  5. :data="state.data"
  6. >
  7. <template #default=" {node, data} ">
  8. <span>
  9. <!-- 节点文本 -->
  10. <span
  11. v-if="state.operateMenuItemId !== data.id"
  12. @dblclick="handleDoubleClickMenuText(data.id, data.id)"
  13. >
  14. {{node.label}}
  15. </span>
  16. <!-- 编辑节点文本的输入框 仅在双击文本的时候展示 -->
  17. <el-input
  18. v-model="data.label"
  19. v-else
  20. ref="menuItemTextInputRef"
  21. @blur="handleDoubleClickMenuText('', data.id)"
  22. />
  23. </span>
  24. </template>
  25. </el-tree>
  26. </template>

拓展:

  • 页面上本来没有 el-input 这个DOM,只有双击后,更新了当前选中的菜单ID(state.operateMenuItemId) ,才能触发 DOM 更新;
  • DOM更新完成之后,才能获取 el-input 的焦点(也就是说,获取焦点这一步,应该稍微等一下,等 DOM 更新了,el-input 加载出来了,才能获取焦点);
  • 因此,采用 setTimeout 来延迟执行获取输入框焦点的代码;
  1. function handleDoubleClickMenuText(id: string) {
  2. state.operateMenuItemId = id;
  3. setTimeout(() => {
  4. if (menuItemTextInputRef.value) {
  5. menuItemTextInputRef.value.focus();
  6. }
  7. });
  8. }

2. el-table 表格相关问题

2.1 解决 el-table 某列内容长度超过列宽,默认换行问题

如图所示,非理想效果:

理想效果其实是:不换行,溢出隐藏,鼠标滑上去后有 tooltip 进行提示 

实现方法:

  1. <el-table-column
  2. v-for="(item, index) in header"
  3. :key="index"
  4. :class-name="'table-cell'"
  5. :show-overflow-tooltip="true"
  6. :label="item.title"
  7. :prop="item.key"
  8. />
  9. // 可以在全局 SCSS 中添加,也可以单独加在页面当中
  10. .el-tooltip__popper {
  11. max-width: 800px;
  12. background-color: red!important;
  13. }

注意:

  • 不能在 <style scoped></style> 中修改 ElementPlus 样式,不会生效
  • show-overflow-tooltip 属性需要谨慎使用,多列使用会影响页面加载速度

2.2 el-table 滚动条导致的行对不齐问题

如下图所示,左侧列固定,右侧列可以横向滚动,如果添加了滚动条,就会出现一行对不齐的情况

在行对齐的情况下,修改滚动条样式的解决方案:

  • 给 el-table 添加属性 height="300px"
  • 在全局公共样式 .scss 中,添加设置:
      ::-webkit-scrollbar {
        width: 10px; // 纵向滚动条的宽度
        height: 10px; // 横向滚动条的高度
      }
  • 在自定义滚动条的页面或组件中,重新定义 ::-webkit-scrollbar 属性

2.3 实现 el-table 隔行变色(ts 数据类型定义)

如下图所示,直接解构参数会导致 ts 报错,缺少数据类型接口

  1. interface changeRowParameter {
  2. row?: number; // 行
  3. column?: number; // 列
  4. rowIndex: number; // 行下标
  5. columnIndex?: number; // 列下标
  6. }
  7. /**
  8. * 间隔行颜色
  9. */
  10. const changeRow = ({ rowIndex }: changeRowParameter) => {
  11. if (rowIndex % 2 === 0) {
  12. // 奇数行背景色
  13. return props.cStyle.rowContent;
  14. }
  15. // 偶数行背景色
  16. return props.cStyle.wrapperContent;
  17. };

3. el-popover 组件内部添加注释导致的问题

如下代码所示,看起来似乎没有问题,却出现了报错

  1. <el-popover
  2. ref="popover1"
  3. placement="bottom-start"
  4. width="213"
  5. trigger="click"
  6. :show-arrow="false"
  7. popper-class="reset-tool-popover"
  8. :disabled="disable"
  9. v-model:visible="visible"
  10. >
  11. <template #reference>
  12. <!-- 属性文本 -->
  13. <span class="label" @click="handleClick">{{ label }}</span>
  14. </template>
  15. <div class="reset-box">
  16. <div class="reset-button-wrapper" v-if="reset">
  17. <!-- 重置按钮 -->
  18. <div class="reset-button" @click="handleReset">
  19. <div class="reset-left">
  20. <img src="@/assets/images/design/settings/reset.svg" alt="" />
  21. <span class="reset-action">Reset</span>
  22. </div>
  23. <span class="reset-shortcut">Alt + click</span>
  24. </div>
  25. </div>
  26. <!-- 重置说明 -->
  27. <p class="reset-explain">{{ explain }}</p>
  28. <div class="reset-button-wrapper global-explain" v-if="isGlobal">
  29. <img src="@/assets/images/design/settings/all-pages.svg" />
  30. <span class="global-explain-text">Body (All Pages)</span>
  31. </div>
  32. </div>
  33. </el-popover>

报错内容:Uncaught (in promise) ElementPlusError: [renderTrigger] trigger expects single rooted node...

报错原因:

  • 根据提示可得,el-popover 希望只有一个根节点
  • <div class="reset-box"> 作为内容区,只有一个DOM元素,不会导致报错
  • <template #reference> 作为插槽,不仅包含了一个DOM,还包含了一条注释

综上,使用 el-popover 时,在插槽里一定 “不能 ”使用注释

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/890740
推荐阅读
相关标签
  

闽ICP备14008679号