目录
1. 间距组件功能介绍
- 此功能用于设置组件样式中的 内外边距 / 位置信息
- 未激活状态:
- 通过 clip-path 绘制梯形效果,原来是通过 svg 添加背景图片的,但是代码太多,设置起来不够灵活,因此换成 div
- 激活状态:
- 点击数字后,出现弹框,设置详细数据;如果已经设置了新的值,会将数字更改为蓝色
- 弹框出现之后,应该有一个黑色覆盖效果
- 根据点击的数字位置不相同,决定弹框内左上角图标效果
- 综上所述,我把 间距设置面板 / 间距设置弹框 分成了两个组件
2. svg 图片的使用
- 可以直接在 html 中使用 svg 标签
- 也可以将 svg 标签,拷贝到 .svg 文件里,并加上头部声明
- 以下面的代码为例:
- 可以更改 <path> 中的 fill,来决定 svg 图片的整体颜色
- 可以给 svg 图片添加类名
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1" width="16" height="16" viewBox="0 0 16 16" > <path opacity=".6" fill="#fff" d="M1 3h4v4H1z"></path> <path fill="#fff" d="M7 3h8v4H7z"></path> <path fill-rule="evenodd" clip-rule="evenodd" d="M10 8v1a2 2 0 01-2 2H4v2h4a4 4 0 004-4V8h-2zm-6.01 5L4 15l-3-3 3-3-.01 2v2z" fill="#fff" ></path> </svg>
3. 改造 element-plus Drawer
- 因为点击 间距设置面板之后,会出现间距设置弹框,而间距设置弹框有一层遮罩效果,因此想到了 element-plus Drawer 组件,基本结构如下
<el-drawer v-model="toChildParams.isPopShow" :direction="'rtl'" :withHeader="false" :lock-scroll="false" custom-class="setclass-drawer" destroy-on-close > <spacing-pop></spacing-pop> </el-drawer>
- 关于抽屉组件的一些属性:
- v-model 绑定了抽屉是否打开,也就相当于弹框是否显示
- direction 绑定了打开方向
- withHeader 绑定了是否显示抽屉标题
- lock-scroll 绑定了滚动条状态,建议看官网
- custom-class 绑定了自定义抽屉类名
- 弹框只有一小块,上下遮罩 都能实现 点击后关闭弹框,而 drawer 组件默认是充满屏幕高度的,且是白色背景
- 我看了抽屉组件的 html 结构,遮罩是充满全屏的,也就是说白色背景下面就是遮罩,因此我给白色背景加了个 point-events: none + 透明背景,这样就能点击白色背景的部分能透过去,直接点到遮罩,进而实现关闭了
- 如下代码所示:
.setclass-drawer.el-drawer { width: 240px !important; background-color: transparent; box-shadow: none; pointer-events: none; }
4. 修改全局 elementplus 样式有感
- /deep/ 最好用 :deep() 替换,以减少运行警告
- 在 <style lang="scss" scoped> 中修改 elementplus 时,由于 scoped 限制了样式的作用范围,:deep() 也可能失效,因此可以考虑修改全局的公共 elementplus 样式,全局修改(也就是单独的 css/scss 等文件中)不需要使用 :deep()
修改全局 elementplus 样式步骤:
- 在 assets/style 中 新建 element-plus.scss
- 在 style.scss 中引入 @import './element-plus';
- 给组件添加自定义类名,比如上方的抽屉组件,我加的自定义类名是 setclass-drawer,加了之后,在开发者工具中,可以查找到我自己加的类名
- 然后就可以在 elementplus 类名之前加上我的类名,进行修改
- 自己加的类名可以不止一个,用空格隔开即可
5. 关于枚举的使用感悟
- 如上图所示,点击单位后出现单位下拉框,此下拉框使用 elementplus 中的组件,数据结构是 { value: '', label: '' }
- 在逻辑代码里,当 选中值为 auto 时,会进行特别的操作,也就是我可能会写到 if (state.selectOptions === 'auto') {...} ,当数据变多时,前面这种 'auto' 就有可能会写错,此时就可以考虑枚举了
- 如上图所示,我写了下拉框列表中,单位 value 的枚举值,可以在 逻辑 中使用此枚举类型
- 那么我的代码可以替换成:if (state.selectOptions === SpacingSelectUnitEnum.AUTO) {...}
同时,枚举值除了可以在逻辑里使用,还可在 模板 里使用,但必须 return 出去- 如下所示:
- import { SpacingAndPositionEnum } from '@/types/common-style';
- setup() { return { SpacingAndPositionEnum }}
- <div class="sticky-info" v-if="position.selected === PositionTypeEnum.sticky">
6. 动态绑定图片背景内联样式
- 导入图片文件:
- import marginTopSVG from '@/assets/images/design/settings/spacing/spacing-pop-margin-top.svg';
将导入的图片赋值给一个变量:- state.iconImg = marginTopSVG;
在模板中,动态绑定内联样式,使用模板字符串插入图片变量:- <div class="icon-box" :style="{ background: `url(${iconImg}) no-repeat center center / 100% 100%` }"></div>
在 css 中能否使用变量绑定图片背景,这个我试了下不太行,也可能是我写错了- 在模板中,使用内联样式,必须记得:① style 前面的冒号:;② 双引号后面的大括号{};③ 模板字符串``;
- 如果配置了路径替代,就是说 src 可以被 @ 替代的话,那么在css 样式中,也可以使用 @/assets/xxx 写路径了
7. 梯形背景容器逻辑
- 双层循环,渲染出 margin/padding 的背景/标题/数字/提示
- 第一层循环:循环了 margin/padding容器 及 margin/padding标题
- 第二层循环:循环了 提示框 / margin/padding背景 / 数字及其点击事件
- 根据是否设置,决定数字样式::class="{ 'spacing__num--hasset': elem.hasSet }"
<template v-for="(item, index) of spacingDataList" :key="index"> <div :class="item.outerBoxClass"> <div class="spacing__text">{{ item.boxTitle }}</div> <!-- margin/padding 容器背景 --> <template v-for="(elem, index) of item.innerElem" :key="index"> <el-tooltip effect="light" :content="elem.tooltip" :placement="elem.tooltipPosition" :enterable="false" :offset="8" popper-class="setclass-tooltip" > <div :class="elem.class"> <!-- margin/padding 数字 --> <span class="spacing__num" :class="{ 'spacing__num--hasset': elem.hasSet }" @click="handleNumClick(elem, $event)" > {{ elem.number + elem.unit }} </span> </div> </el-tooltip> </template>
- 关于 tooltip 提示框:
- :offset="8": 提示框箭头偏移值
- :placement="elem.tooltipPosition":提示框出现位置
- :content="elem.tooltip":提示框基本内容
- :enterable="false"提示框禁止鼠标划入(当鼠标划入时,提示框会消失)
- popper-class="setclass-tooltip" 提示框自定义样式
循环这种双层结构的示例:- 不要直接修改遍历出来的 item,最好通过遍历出来的 index,查询到对应项,并修改
state.spacingDataList.forEach((spacingData: any, index: number) => { state.spacingDataList[index].innerElem.forEach((item: any, eleIndex: number) => { const ele = state.spacingDataList[index].innerElem[eleIndex]; // 当遍历到当前被修改的值时,进行的而操作 if (ele.name === info.position) { // 修改数值 ele.number = info.inputValue; ... }); });
8. vue中,获取当前点击位置 / dom信息等
- 给间距模块的数字部分绑定了点击事件,点击事件传递了当前被点击的值 / $event
- @click="handleNumClick(elem, $event)"
通过 $event 可以获取 当前点击的 dom元素,示例如下:- toChildParams.value.clickTop = e.srcElement.getBoundingClientRect().top + e.srcElement.getBoundingClientRect().height;
9. scss 中使用变量
- $spacing-border-color: rgb(33, 33, 33);
- &__padding-box { border: 1px solid $spacing-border-color; }
10. 渲染不同截取段的下拉内容
- 此处的应用场景:
- 当有自动按钮的时候,显示的下拉框列表中包含 auto;
- 当没有自动按钮的时候,显示的下拉框列表中不包含 auto;
11. props 中 使用枚举 / 实现两种类型二选一
- 使用枚举,限定字符串具体内容:
- position: {
type: String as PropType<SpacingAndPositionEnum>,
default: SpacingAndPositionEnum.marginTop,
},
使用数组,限定传入的值可以是字符串,也可以是数字- value: {
type: [String, Number],
default: '0',
required: false,
},
区分:type SpacingInputValueType = string | number;- 这种写法不可以在 props 中使用,但是可以在 state 中使用
- inputValue: 0 as SpacingInputValueType,
12. slider 组件 和 input 组件之间的关系
- 滑块绑定的数据,必须是数字类型
- 输入框绑定的数据,可以是字符串类型,也可以是数字类型
- 滑块的值可以设置一个范围
- 当输入框的值大于滑块的最大值时,滑块显示在滑块最大值上,输入框显示输入的值
- 当输入框的值小于滑块的最小值时,滑块显示在滑块最小值上,输入框显示输入的值
Vue3 低代码开发平台 间距设置功能 问题记录
最新推荐文章于 2024-08-22 16:18:02 发布
本文介绍了Vue项目中关于间距组件的功能改造,包括使用SVG图片、改造Element-Plus Drawer组件、全局样式修改、枚举在下拉框中的应用等。此外,还涉及动态绑定图片背景、梯形背景容器的实现以及Vue中获取DOM信息的方法。文章深入探讨了组件优化和代码维护性提升的策略。
摘要由CSDN通过智能技术生成