赞
踩
目录
1.1 使用 el-form 表单校验规则,无法对 number 类型输入框校验
1.2 隐藏后重新显示的 el-input 无法自动获得焦点(双击实现输入框编辑)
2.1 解决 el-table 某列内容长度超过列宽,默认换行问题
2.3 实现 el-table 隔行变色(ts 数据类型定义)
- <el-form :rules="rules" :model="scheduleFormLabel">
- <el-form-item label="活动人数:" required prop="peopleNum">
- <el-input
- type="number"
- placeholder="请输入活动人数"
- v-model="scheduleFormLabel.peopleNum"
- />
- <template #suffix>
- <span class="t-white t-f12">人</span>
- </template>
- </el-input>
- </el-form-item>
- </el-form>
- rules: {
- peopleNum: [
- {
- required: true, message: '', trigger: 'blur',
- },
- {
- type: 'number',
- min: 1,
- max: 100000,
- message: '活动人数应该在1-100000之间',
- trigger: 'blur',
- },
- ],
- },
解决方案:给 v-model 加上 .number 即可
<el-input v-model.number="scheduleFormLabel.peopleNum"></el-input>
需求:这有一个菜单树,双击菜单项文本后,编辑菜单项名称
实现逻辑:
- <template>
- <el-tree
- node-key="id"
- :props="propsMap"
- :data="state.data"
- >
- <template #default=" {node, data} ">
- <span>
- <!-- 节点文本 -->
- <span
- v-show="state.operateMenuItemId !== data.id"
- @dblclick="handleDoubleClickMenuText(data.id, data.id)"
- >
- {{node.label}}
- </span>
-
- <!-- 编辑节点文本的输入框 仅在双击文本的时候展示 -->
- <el-input
- v-model="data.label"
- v-show="state.operateMenuItemId === data.id"
- ref="menuItemTextInputRef"
- @blur="handleDoubleClickMenuText('', data.id)"
- />
- </span>
- </template>
- </el-tree>
- </template>
-
- <script lang="ts" setup>
- import {
- reactive,
- ref,
- } from 'vue';
- import { MenuTreeData } from '@/types/common/menu-tree';
- import { ElInput } from 'element-plus';
-
- // 配置选项的映射
- const propsMap = {
- children: 'children',
- label: 'label',
- };
-
- const state = reactive({
- // 树形菜单数据
- data: [
- {
- id: 'a1',
- label: '菜单1',
- children: [
- {
- id: 'aa1',
- label: '菜单1.1',
- },
- {
- id: 'ab1',
- label: '菜单1.2',
- children: [
- {
- id: 'aba1',
- label: '菜单1.2.1',
- },
- ],
- },
- ],
- },
- {
- id: 'b1',
- label: '菜单2',
- },
- //...
- ] as MenuTreeData[],
- // 当前操作的菜单项的id
- operateMenuItemId: '',
- });
-
- // 菜单项文本输入框DOM
- const menuItemTextInputRef = ref();
-
- /**
- * 处理双击菜单项文本
- * @param id - 菜单项id
- */
- function handleDoubleClickMenuText(id: string) {
- state.operateMenuItemId = id;
- if (menuItemTextInputRef.value) {
- menuItemTextInputRef.value.focus();
- }
- }
- </script>
原因分析:
问题解决:
为了确保 el-input 只渲染一次(只存在一个有 ref="menuItemTextInputRef" 属性的 el-input),应该采用 v-if 替代 v-show
- <template>
- <el-tree
- node-key="id"
- :props="propsMap"
- :data="state.data"
- >
- <template #default=" {node, data} ">
- <span>
- <!-- 节点文本 -->
- <span
- v-if="state.operateMenuItemId !== data.id"
- @dblclick="handleDoubleClickMenuText(data.id, data.id)"
- >
- {{node.label}}
- </span>
- <!-- 编辑节点文本的输入框 仅在双击文本的时候展示 -->
- <el-input
- v-model="data.label"
- v-else
- ref="menuItemTextInputRef"
- @blur="handleDoubleClickMenuText('', data.id)"
- />
- </span>
- </template>
- </el-tree>
- </template>
拓展:
- 页面上本来没有 el-input 这个DOM,只有双击后,更新了当前选中的菜单ID(state.operateMenuItemId) ,才能触发 DOM 更新;
- DOM更新完成之后,才能获取 el-input 的焦点(也就是说,获取焦点这一步,应该稍微等一下,等 DOM 更新了,el-input 加载出来了,才能获取焦点);
- 因此,采用 setTimeout 来延迟执行获取输入框焦点的代码;
function handleDoubleClickMenuText(id: string) { state.operateMenuItemId = id; setTimeout(() => { if (menuItemTextInputRef.value) { menuItemTextInputRef.value.focus(); } }); }
如图所示,非理想效果:
理想效果其实是:不换行,溢出隐藏,鼠标滑上去后有 tooltip 进行提示
实现方法:
- <el-table-column
- v-for="(item, index) in header"
- :key="index"
- :class-name="'table-cell'"
- :show-overflow-tooltip="true"
- :label="item.title"
- :prop="item.key"
- />
-
- // 可以在全局 SCSS 中添加,也可以单独加在页面当中
- .el-tooltip__popper {
- max-width: 800px;
- background-color: red!important;
- }
注意:
- 不能在 <style scoped></style> 中修改 ElementPlus 样式,不会生效
- show-overflow-tooltip 属性需要谨慎使用,多列使用会影响页面加载速度
如下图所示,左侧列固定,右侧列可以横向滚动,如果添加了滚动条,就会出现一行对不齐的情况
在行对齐的情况下,修改滚动条样式的解决方案:
- 给 el-table 添加属性 height="300px"
- 在全局公共样式 .scss 中,添加设置:
::-webkit-scrollbar {
width: 10px; // 纵向滚动条的宽度
height: 10px; // 横向滚动条的高度
}- 在自定义滚动条的页面或组件中,重新定义 ::-webkit-scrollbar 属性
如下图所示,直接解构参数会导致 ts 报错,缺少数据类型接口
- interface changeRowParameter {
- row?: number; // 行
- column?: number; // 列
- rowIndex: number; // 行下标
- columnIndex?: number; // 列下标
- }
-
- /**
- * 间隔行颜色
- */
- const changeRow = ({ rowIndex }: changeRowParameter) => {
- if (rowIndex % 2 === 0) {
- // 奇数行背景色
- return props.cStyle.rowContent;
- }
- // 偶数行背景色
- return props.cStyle.wrapperContent;
- };
如下代码所示,看起来似乎没有问题,却出现了报错
- <el-popover
- ref="popover1"
- placement="bottom-start"
- width="213"
- trigger="click"
- :show-arrow="false"
- popper-class="reset-tool-popover"
- :disabled="disable"
- v-model:visible="visible"
- >
- <template #reference>
- <!-- 属性文本 -->
- <span class="label" @click="handleClick">{{ label }}</span>
- </template>
- <div class="reset-box">
- <div class="reset-button-wrapper" v-if="reset">
- <!-- 重置按钮 -->
- <div class="reset-button" @click="handleReset">
- <div class="reset-left">
- <img src="@/assets/images/design/settings/reset.svg" alt="" />
- <span class="reset-action">Reset</span>
- </div>
- <span class="reset-shortcut">Alt + click</span>
- </div>
- </div>
- <!-- 重置说明 -->
- <p class="reset-explain">{{ explain }}</p>
- <div class="reset-button-wrapper global-explain" v-if="isGlobal">
- <img src="@/assets/images/design/settings/all-pages.svg" />
- <span class="global-explain-text">Body (All Pages)</span>
- </div>
- </div>
- </el-popover>
报错内容:Uncaught (in promise) ElementPlusError: [renderTrigger] trigger expects single rooted node...
报错原因:
- 根据提示可得,el-popover 希望只有一个根节点
- <div class="reset-box"> 作为内容区,只有一个DOM元素,不会导致报错
- <template #reference> 作为插槽,不仅包含了一个DOM,还包含了一条注释
综上,使用 el-popover 时,在插槽里一定 “不能 ”使用注释
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。