UNPKG

@fesjs/fes-design

Version:
170 lines (156 loc) 5.62 kB
import { defineComponent, computed, watch, createVNode, createTextVNode } from 'vue'; import _defineProperty from '@babel/runtime/helpers/esm/defineProperty'; import getPrefixCls from '../_util/getPrefixCls'; import { useTheme } from '../_theme/useTheme'; import { StarFilled, StarOutlined } from '../icon'; import { rateProps } from './props'; import { sizeMap } from './const'; import { useRate } from './useRate'; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } const prefixCls = getPrefixCls('rate'); var rate = defineComponent({ name: 'FRate', props: rateProps, emits: ['update:modelValue', 'change', 'clear'], setup(props, _ref) { let { emit, slots } = _ref; const { rateItemArr, isHover, curActiveIndex, getRateArr, rateClick, hoverLeave, hoverMove } = useRate(props, emit); useTheme(); const getCommonStyle = () => { return { cursor: props.readonly && 'auto', height: `${sizeMap[props.size]}px` }; }; // 只读状态改变鼠标样式 const iconStyle = computed(() => { return _objectSpread(_objectSpread({}, getCommonStyle()), {}, { color: props.color }); }); const emptyIconStyle = computed(() => { return _objectSpread({}, getCommonStyle()); }); // icon尺寸 const iconSize = computed(() => { return sizeMap[props.size]; }); watch(() => props.count, () => { getRateArr(); }, { immediate: true }); const emptyIcon = () => { return !props.colorFilled ? createVNode(StarOutlined, { "size": iconSize.value }, null) : slots !== null && slots !== void 0 && slots.content ? slots === null || slots === void 0 ? void 0 : slots.content({ size: iconSize.value }) : createVNode(StarFilled, { "size": iconSize.value }, null); }; // 渲染满星 const renderFullStar = () => { return createVNode("div", { "class": "rate-icon full-icon", "style": iconStyle.value }, [slots !== null && slots !== void 0 && slots.content ? slots === null || slots === void 0 ? void 0 : slots.content({ size: iconSize.value }) : createVNode(StarFilled, { "size": iconSize.value }, null)]); }; // 渲染半星 const renderHalfStar = () => { return createVNode("div", { "class": "rate-icon full-icon", "style": iconStyle.value }, [createVNode("div", { "class": "background-icon" }, [createTextVNode(" "), emptyIcon()]), createVNode("div", { "class": "half-icon" }, [slots !== null && slots !== void 0 && slots.content ? slots === null || slots === void 0 ? void 0 : slots.content({ size: iconSize.value }) : createVNode(StarFilled, { "size": iconSize.value }, null)])]); }; // 渲染空星 const renderEmptyStar = () => { return createVNode("div", { "class": "rate-icon empty-icon", "style": emptyIconStyle.value }, [emptyIcon()]); }; const containerHoverEnter = () => { isHover.value = true; }; const containerHoverLeave = () => { isHover.value = false; }; // 渲染item const renderItem = item => { let judgment; // 非只读状态下,如果是hover状态就只看hover属性的boolean确认高亮效果 if (isHover.value && !props.readonly) { judgment = item.hover; } else { judgment = item.active; } if (judgment && item.half) { return renderHalfStar(); } if (judgment && !item.half) { return renderFullStar(); } return renderEmptyStar(); }; // 根据状态渲染 const renderRateByStatus = () => { return createVNode("div", { "class": `${prefixCls}-container`, "onMouseenter": () => containerHoverEnter(), "onMouseleave": () => containerHoverLeave() }, [rateItemArr.value.map((item, index) => { return createVNode("div", { "onClick": event => !props.readonly && rateClick(event, index), "onMousemove": event => !props.readonly && hoverMove(event, index), "onMouseleave": () => !props.readonly && hoverLeave() }, [renderItem(item)]); })]); }; // 获取当前星级对应的文字 const getCurrentText = () => { return props.texts[curActiveIndex.value]; }; // 渲染文字 const renderText = () => { if (!props.showText) { return null; } return createVNode("div", { "class": `${prefixCls}-text` }, [getCurrentText()]); }; // 容器样式 const containerClass = computed(() => { return [prefixCls, `${prefixCls}-size-${props.size}`]; }); return () => createVNode("div", { "class": containerClass.value }, [renderRateByStatus(), renderText()]); } }); export { rate as default };