Skip to content

手写antd评分组件

1. 需求

功能: 最大分值,选中分值,事件交互

2. 功能实现

jsx
import classNames from 'classnames'
import './JKRate.css'
import PropTypes from 'prop-types'
import { useState } from 'react'

function JKRate({count=5, value=0, onChange}) {
  const items = []
  const [mouseVal, setMouseVal] = useState(value)
  for (let i = 0; i < count; i++) {
    const starStyle = classNames({
      'jk-ant-rate-star': true,
      'jk-ant-rate-star-active': i < mouseVal? true : false,
    })
    items.push(
      <li key={i} className={starStyle} onMouseEnter={()=>handleMouseEnter(i)} onClick={()=>handleClick(i)}></li>
    )
  }

  const handleMouseEnter = (index) => {
    setMouseVal(index+1)
  }

  const handleClick = (index) => {
    setMouseVal(index+1)
    onChange(index+1)
  }

  const handleMouseLeave = () => {
    setMouseVal(value)
  }

  return (
    <>
      <ul className='jk-ant-rate' onMouseLeave={handleMouseLeave}>
        {items}
      </ul>
    </>
  )
}

JKRate.propTypes = {
  count: PropTypes.number,
  value: PropTypes.number,
  onChange: PropTypes.func,
}

export default JKRate
css
@font-face {
    font-family: "iconfont";
    src: url('iconfont.ttf?t=1683785532839') format('truetype');
}

.jk-ant-rate{
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    color: rgba(0, 0, 0, 0.06);
    font-size: 20px;
    line-height: unset;
    list-style: none;
    font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji';
    display: inline-block;
    outline: none;
}

.jk-ant-rate-star{
    margin-inline-end: 8px;
    font-family: "iconfont" !important;
    position: relative;
    display: inline-block;
    color: inherit;
    cursor: pointer;
}

.jk-ant-rate-star::before {
    content: "\f0144";
}
.jk-ant-rate-star-active {
    color: #fadb14;
}
js
import JKButton from './JKButton/JKButton.jsx'
import JKRate from './JKRate/JKRate.jsx'

export  {JKButton, JKRate}
jsx
import { Rate, Row, Space } from 'antd'
import { JKRate } from './JKAntd'
import { useState } from 'react'

function App() {
  const [value1, setValue1] = useState(3)
  const [value2, setValue2] = useState(3)
  const [value3, setValue3] = useState(3)
  const [value4, setValue4] = useState(3)
  return (
    <>
      <Row>
        <Space>
          <span>评价:</span>
          <Rate value={value1} onChange={setValue1} /> {value1}
        </Space>
      </Row>
      <Row>
        <Space>
          <span>评价:</span>
          <Rate count={6} value={value2} onChange={setValue2} /> {value2}
        </Space>
      </Row>
      <br />
      <br />
      <Row>
        <Space>
          <span>评价:</span>
          <JKRate value={value3} onChange={setValue3} /> {value3}
        </Space>
      </Row>
      <Row>
        <Space>
          <span>评价:</span>
          <JKRate count={6} value={value4} onChange={setValue4} /> {value4}
        </Space>
      </Row>
    </>
  )
}

export default App

运行效果:
Alt text