需求场景
我有一个列表需要渲染,并且提供列表项的移动操作,如下:
对于第一项与最后一项,既要上移下移的icon样式置灰,还要在点击事件中忽略对他们的操作(计算css样式,同时js逻辑也需要特殊处理就非常难受)
最终解决
给<i @click="xxx">
元素添加样式:pointer-events: none;
这样就阻止了其点击事件,所以我们只需要计算i
标签的样式何时需要添加pointer-events: none;
,而js逻辑中只需要负责单纯的上移或者下移的数组操作
示例代码
html:
html
<xxx组件库-table-column label="操作">
<template #default="{ row: option, $index: index }">
<xxx组件库-button
size="small"
type="text-primary"
@click="onDeleteOptionClick(option)"
>删除</xxx组件库-button
>
<i
class="xxx组件库icon xxx组件库icon-arrow-up"
:class="getOrderIconClass(EOrderChangeType.UP, index)"
@click="onOrderChangeClick(EOrderChangeType.UP, index)"
/>
<i
class="xxx组件库icon xxx组件库icon-arrow-down"
:class="getOrderIconClass(EOrderChangeType.DOWN, index)"
@click="onOrderChangeClick(EOrderChangeType.DOWN, index)"
/>
</template>
</xxx组件库-table-column>
ts:
ts
// 删除回调
const onDeleteOptionClick = (clickOption: IOptionItem) => {
interactionConfig.options = interactionConfig.options.filter(
(option) => option !== clickOption
);
};
// 移动类型枚举(上移/下移)
const enum EOrderChangeType {
UP = 'up',
DOWN = 'down',
}
// 移动回调(数组项位置交换)
const onOrderChangeClick = (type: EOrderChangeType, index: number) => {
const temp = interactionConfig.options[index];
if (type === EOrderChangeType.UP) {
interactionConfig.options[index] = interactionConfig.options[index - 1];
interactionConfig.options[index - 1] = temp;
} else if (type === EOrderChangeType.DOWN) {
interactionConfig.options[index] = interactionConfig.options[index + 1];
interactionConfig.options[index + 1] = temp;
}
};
// disable样式计算函数(第一项不能上移/最后一项不能下移)
const getOrderIconClass = (type: EOrderChangeType, index: number) => {
if (
(index === 0 && type === EOrderChangeType.UP) ||
(index === interactionConfig.options.length - 1 &&
type === EOrderChangeType.DOWN)
)
return 'xxx组件库icon-disabled';
return '';
};
scss:
scss
:deep(.mtdicon) {
color: green;
&.mtdicon-disabled {
pointer-events: none;
&::before {
color: gray;
}
}
}
plus
关于pointer-events: none;
的能力可能更加强大以及复杂,这里针对i
标签(一个最小dom单元)正好满足需求,如果是一些嵌套元素的点击事件,还需要再斟酌这个样式的细节。