3.22 Rate 评分
简介
评分组件 Rate 多用于展示评价或者对事物快速评级。本文将分析源码实现,耐心读完,相信会对您有所帮助。组件源码实现详见packages/rate/src/main.vue 。 🔗 组件文档 Rate 🔗 gitee源码 main.vue
更多组件剖析详见 👉 📚 Element 2 源码剖析组件总览 。
源码实现
组件的 prop 声明,各属性功能说明详见 官方文档rate#attributes 。
组件DOM结构
组件的根节点是类名el-rate的div元素,子元素包含评分icon图标和辅助文字两部分。
精简之后的结构代码如下:
<template>
<div class="el-rate">
<span v-for="(item, key) in max" class="el-rate__item">
<i class="el-rate__icon"></i>
</span>
<span class="el-rate__text">{{ text }}</span>
</div>
</template>评分icon图标
组件的主要逻辑都在评分icon图标部分,接下来将采用渐进式的讲解方式,对比分析各代码功能逻辑。
基础展示
评分icon图标基于属性max渲染一个类名el-rate__item的span元素列表生成。默认个数为 5。使用计算属性 classes 返回不同状态(选中/未选中)的 icon 类名。使用方法 getIconStyle 返回不同状态(选中/未选中)的 icon 颜色。
此时组件代码如下,没有鼠标交互事件,只能用作展示。
运行如下示例代码
组件支持评分分级,通过 iconClasses、 colors、 lowThreshold、 highThreshold等属性控制显示逻辑内容。
评分默认被分为三个等级,可以利用颜色数组对分数及情感倾向进行分级(默认情况下不区分颜色)。三个等级所对应的颜色用
colors属性设置,而它们对应的两个阈值则通过low-threshold和high-threshold设定。也可以通过传入颜色对象来自定义分段,键名为分段的界限值,键值为对应的颜色。
当组件用v-model传入了一个值, v-model的语法糖会把这个值当成props的value传到组件中。此时组件内部使用属性currentValue等同于属性value。
⚠️ 当后面添加鼠标事件后,鼠标移动会直接改变 currentValue,属性currentValue不等同于属性value,
基础展示的样式计算
计算属性 classes基于组件的绑定值判断选中状态,生成的icon图标类名数组,由于遍历MAX是从1开始,所以调用时需item-1。
方法getIconStyle 返回当前图标状态颜色。根据组件的只读状态,返回不同的未选中颜色。
计算属性activeClass使用方法getValueFromMap,返回对应分段区间的选中状态icon类名。
计算属性 classMap 返回 3 个分段区间对应颜色的对象。
若
iconClasses属性传入数组,共有 3 个元素,转换成对象,分段界限值基于lowThreshold、highThreshold、max,各区间为[0,lowThreshold]、(lowThreshold,highThreshold)、[highThreshold,max]。若传入对象,可自定义分段,键名为分段的界限值,键值为对应的icon类名。
属性 iconClasses默认值 ['el-icon-star-on', 'el-icon-star-on', 'el-icon-star-on'],组件默认各评分层级 icon 类型相同。
计算属性 activeColor 基于同样的处理逻辑,返回对应分段区间的选中状态icon颜色。
计算属性voidClass根据是否只读状态,返回未选中状态icon类名。计算属性rateDisabled返回组件是否只读状态。
若表单禁用设置为 true,则表单内组件上的 disabled 属性不再生效。
支持半选
接下来在类名el-rate__icon的i元素中添加一个类名el-rate__decimal的i元素,用于实现半选效果。
方法showDecimalIcon 控制组件支持半选展示状态。
只读模式下,默认支持半选效果。
非只读模式下,小数位要不小于0.5才会显示半选效果。
属性pointerAtLeftHalf 用于普通模式下控制半星展示,当绑定值包含小数位时为true。
Icon类名使用计算属性decimalIconClass设置,跟上一小节的activeClass实现一样。
半选显示样式通过计算属性decimalStyle控制,返回包含选中颜色、宽度的样式对象。
只读模式下,按照小数位百分比
valueDecimal显示宽度。非只读模式下,小数位不管多大,只显示半颗星
50%。
不同模式下样式对比如下:
鼠标交互事件
在元素添加一些事件和样式处理逻辑,用于支持鼠标滑动、点击事件。
span元素样式根据只读状态设置光标的类型。
mousemove事件监听方法setCurrentValue,用于设置鼠标悬停元素索引 hoverIndex(从1开始)和currentValue,只读模式下无效。
在半选模式下,选择类名el-rate__icon的DOM元素作为目标,获取基于目标节点的内填充边在 X 轴方向上的偏移量 offsetX。
如果offsetX小于目标元素的内部宽度的一半,则认为光标在目标元素的左半边,pointerAtLeftHalf 值为 true,currentValue值为 item-0.5;反之pointerAtLeftHalf 值为 false,currentValue值为 item。所以选中效果就是半星->整星 或 整星->半星 的过程。
属性hoverIndex 用于icon图标鼠标悬停放大效果。
mouseleave事件监听方法resetCurrentValue,用于重置pointerAtLeftHalf、hoverIndex和currentValue等属性值,只读模式下无效
clcik事件监听方法selectValue用于触发组件自定义change事件,返回改变后的分值,只读模式下无效。 $emit('input', val) 用来更新组件v-model 值。
辅助文字
类名el-rate__text的span元素用于显示辅助文字,是否显示由属性 showText 、showScore值控制,文字的颜色由属性 textColor控制。
显示内容使用了计算属性 text。 当 showScore=true, 显示当前分数,将当前组件分值使用 scoreTemplate 模板进行内容格式化。 当 showText=true, 显示当前辅助文字,基于当前组件分值调用对应索引(属性 texts)的文字描述。
属性showText和showScore不能同时为真。
键盘事件
回到根节点,添加如下代码。
属性 role 、aria-valuenow 、aria-valuetext、aria-valuemin、aria-valuemax用于实现 ARIA无障碍网页应用。
属性 tabindex="0" 表示元素是可聚焦的,并且可以通过键盘导航来聚焦到该元素。
添加方法handleKey监听keydown事件,只读模式下无效。
当根节点元素聚焦后,使用方向键增加/减少分值,按下键
Up/Right用于增加分值,按下键Left/Down用于减少分值。默认步进为1,当允许半选时,步进为0.5。边界值处理,最小值(
0)和最大值(max)。最后触发组件定义
change事件,返回改变后的分值;同时更新v-model值。
组件需要指定一个
$emit('input')来改变组件v-model值,否则无法更新用户传入的v-model值。
组件样式
组件样式源码 packages\theme-chalk\src\rate.scss 使用混合指令 b、e 嵌套生成组件样式。
在created,增加逻辑如果value传入非数值,使用$emit('input', 0),更新v-model值为0。
📚参考&关联阅读
最后更新于