react 实现评分组件

写了个评分组件,效果如下

组件Rate.js

import React, { Component } from 'react'
import './Rate.less'

export default class Rate extends Component {
  state = {
    count: this.props.number || 5,
    num: this.props.def || 0,
    enter: 0,
    leave: this.props.def || 0,
    state: ['不满意', '满意', '超满意']
  }
  /** 页面渲染前 */
  componentWillMount = () => {}
  /** 页面渲染后 */
  componentDidMount = () => {}
  /** 数据更新前 */
  componentWillUpdate = () => {
    this.showState()
  }
  showState() {
    let { count, num, enter, state } = this.state
    let f = Math.ceil(count / 2)
    if (num == 0 && enter == 0) {
      return ''
    } else if (num < f && enter < f) {
      return state[0]
    } else if (
      num == count ||
      enter == count
    ) {
      return state[2]
    } else {
      return state[1]
    }
  }
  /** 数据更新后 */
  componentDidUpdate = () => {}
  render() {
    let { count, num, enter, leave } = this.state
    return (
      <div className="rate">
        <p className="photo">
          {new Array(count).fill().map((item, index) => (
            <span
              key={index}
              onClick={() => {
                num = index + 1
                leave = num
                this.setState({ num, leave })
              }}
              onMouseEnter={() => {
                enter = index + 1
                num = 0
                this.setState({ enter, num })
              }}
              onMouseLeave={() => {
                enter = 0
                num = leave
                this.setState({ enter, num })
              }}
            >
              {enter > index ? (
                <i className="high" />
              ) : num > index ? (
                <i className="high" />
              ) : (
                <i className="nohigh" />
              )}
            </span>
          ))}
          {this.showState()}
        </p>
      </div>
    )
  }
}

组件样式 Rate.less

.rate .photo span {
  position: relative;
  display: inline-block;
  width: 0.4rem;
  height: 0.4rem;
  overflow: hidden;
  margin-right: 0.1rem;
  cursor: pointer;
}
.rate .photo span:last-child {
  margin-right: 0px;
}
.rate .photo span .nohigh {
  background-color: red;
  position: absolute;
  width: 0.4rem;
  height: 0.4rem;
  top: 0;
  left: 0;
  background: url('./star.png') no-repeat;
  background-size: 0.4rem 0.4rem;
}
.rate .photo span .high {
  background-color: purple;
  position: absolute;
  width: 0.4rem;
  height: 0.4rem;
  top: 0;
  left: 0;
  background: url('./star_active.png') no-repeat;
  background-size: 0.4rem 0.4rem;
}
.rate .starNum {
  font-size: 26px;
  color: #de4414;
  margin-top: 0.04rem;
  margin-bottom: 0.1rem;
}
.rate .bottoms {
  height: 54px;
  border-top: 1px solid #d8d8d8;
}
.rate .photo {
  margin-top: 30px;
}
.rate .bottoms a {
  margin-bottom: 0;
}
.rate .bottoms .garyBtn {
  margin-right: 57px !important;
}
.rate .bottoms a {
  width: 130px;
  height: 35px;
  line-height: 35px;
  border-radius: 3px;
  display: inline-block;
  font-size: 16px;
  transition: all 0.2s linear;
  margin: 16px 0 22px;
  text-align: center;
  cursor: pointer;
}
.garyBtn {
  margin-right: 60px !important;
  background-color: #e1e1e1;
  color: #999999;
}
.blueBtn {
  background-color: #1968b1;
  color: #fff;
}
.blueBtn:hover {
  background: #0e73d0;
}

  

背景图

调用

<Rate number={10} def={5} />
number:为评分总数,默认为5
def:为评分数,默认为0

 

posted @ 2019-07-05 10:17 reaf 阅读(...) 评论(...) 编辑 收藏