@fesjs/fes-design
Version:
fes-design for PC
170 lines (156 loc) • 5.62 kB
JavaScript
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 };