評分組件 Rate 的別樣解法


各種偏門捷徑實現如圖所示的評分組件

 

一、低配版

const rate = (num) =>"★★★★★☆☆☆☆☆".substring(5 - num, 10 - num);

沒錯,只需一行代碼就能實現評分(狗頭)

雖然星星的樣式一言難盡,也沒有星星的交互,但這種實現方式你想到過嗎?

 

 

二、標准版

rc-rate 的實現思路,ant-design 就是用的這個 rate 組件

首先實現單個星星 Star 組件

import React from 'react'; export default class Star extends React.Component { onHover = e => { const { onHover, index } = this.props; onHover(e, index); }; onClick = e => { const { onClick, index } = this.props; onClick(e, index); }; getClassName() { // 根據當前評分修改 star 的 class
    const { index, value } = this.props; const starValue = index + 1; let className = starValue <= value ? 'full' : 'zero'; return className; } render() { const { onHover, onClick } = this; const { index, count, value, character } = this.props; // character 用於自定義星星圖標
    const characterNode = typeof character === 'function' ? character(this.props) : character; const start = ( <li className={this.getClassName()}>
        <div onClick={onClick} onMouseMove={onHover} role="radio" aria-checked={value > index ? 'true' : 'false'} aria-posinset={index + 1} aria-setsize={count} > {/* 如果要做半星,就把 characterNode 拆成兩個 div */} {characterNode} </div>
      </li> ); return start; } }

在 Star 組件中,暴露出 onClick 和 onHover 事件

然后基於當前評分 value 和當前位置 index 來切換自身的 class,以實現普通狀態和高亮狀態

 

然后是 Rate 組件:

import React from 'react'; import Star from './star'; export default class Rate extends React.Component { constructor(props) { super(props); this.state = { value: undefined, hoverValue: undefined, }; } // 鼠標移出組件時,清空 hoverValue
  onMouseLeave = () => { this.setState({ hoverValue: undefined, }); }; onClick = (event, index) => { this.onMouseLeave(); this.setState({ value: index + 1, }); }; onHover = (event, index) => { this.setState({ hoverValue: index + 1, }); }; render() { const { count, className, character, } = this.props; const { value, hoverValue } = this.state; const stars = []; // 根據當前 value 生成所有星星
    for (let index = 0; index < count; index += 1) { stars.push( <Star key={index} index={index} count={count} value={hoverValue || value} onClick={this.onClick} onHover={this.onHover} character={character} />, ); } return ( <ul className={className} onMouseLeave={this.onMouseLeave} role="radiogroup"
      > {stars} </ul> ); } }

在 Rate 組件中主要記錄了實際評分 value 和 hover 狀態下的臨時評分 hoverValue

當鼠標移動的時候,以 hoverValue 渲染組件

當鼠標移出 Rate 組件時清空 hoverValue,以 value 渲染組件

 

 

三、青春版

這種方案以 CSS 為主,HTML 部分相當簡單:

攤平了也就是一個簡單的 div 包裹了幾個 input-radio 元素,這些 radio 都添加了同一個 name

接下來就用神奇的 CSS 一步一步實現評分組件的交互

 

首先實現選中元素時的效果

/* less */ @color-full: coral; @color-zero: #eee; .rate { margin: 0; padding: 0; // 重置原本的 input-radio 樣式 input[name="rate"] { -webkit-appearance: none; border: none; outline: none; cursor: pointer; background: @color-zero; // 點擊評分后的效果 &:checked, // 鼠標移入的效果 &:hover { background: @color-full;
    } } }

通過 radio 選中時的 :checked 狀態,可以修改其點擊后的樣式

然后再通過相鄰元素選擇器 ~ ,修改兄弟元素的樣式

input[name="rate"] { // 點擊評分后的效果 &:checked, &:hover, // 兄弟元素的樣式 &:checked ~ input[name="rate"], &:hover ~ input[name="rate"] { background: @color-full;
  } }

只是這時候的評分是反向的,沒關系,用 flex-flow: row-reverse; 將元素反向排列即可

.rate { display: flex; flex-flow: row-reverse;
}

最后通過 data-set 給 radio 綁定值即可實現取值,不再贅述

 

 

參考資料:

《tiny-rate》

《react-component/rate》

《講道理,僅3行核心css代碼的rate評分組件,我被自己秀到頭皮發麻》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM