React 封装星星评分组件

悠悠 2022-10-06 11:58 295阅读 0赞

在这里插入图片描述
实现的需求为传入对商品的评分数据,页面显示对应的星星个数。

1. 准备三张对应不同评分的星星图片

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

2. 期望实现的效果

这样的
在这里插入图片描述
调用

  1. <StarScore score={ data.wm_poi_score}/>

3. 对传入的数据进行处理

我们需要得到评分的整数和小数部分

  1. let wm_poi_score = this.props.score || '';
  2. let score = wm_poi_score.toString();
  3. let scoreArray = score.split('.');

如果传入 4.7 ,那么得到的 scoreArray 就是['4', '7']

4. 根据数据计算对应的星星个数

  1. // 满星个数
  2. let fullstar = parseInt(scoreArray[0]);
  3. // 半星个数
  4. let halfstar = parseInt(scoreArray[1]) >= 5 ? 1 : 0;
  5. // 灰色星个数
  6. let nullstar = 5 - fullstar - halfstar;

5. 根据星星个数,渲染组件

  1. let starjsx = [];
  2. // 渲染满星
  3. for (let i = 0; i < fullstar; i++) {
  4. starjsx.push(<div key={ i + 'full'} className="star fullstar"></div>)
  5. }
  6. // 渲染半星
  7. if (halfstar) {
  8. for (let j = 0; j < halfstar; j++) {
  9. starjsx.push(<div key={ j + 'half'} className="star halfstar"></div>)
  10. }
  11. }
  12. // 渲染灰色星
  13. if (nullstar) {
  14. for (let k = 0; k < nullstar; k++) {
  15. starjsx.push(<div key={ k + 'null'} className="star nullstar"></div>)
  16. }
  17. }

ok,我们想要的效果就实现啦

6. 手动评分

在这里插入图片描述

页面初次展示时,渲染 5 个灰色的星星。为每一个星星添加一个 click 事件。当点击之时,获取该星星所对应的下标 index,为其添加高亮的样式。

  1. <div className="star-area">
  2. {this.renderStar()}
  3. </div>
  4. doEva(i) {
  5. this.setState({
  6. startIndex: i + 1
  7. });
  8. }
  9. renderStar() {
  10. let array = []
  11. for (let i = 0; i < 5; i++) {
  12. let cls = i >= this.state.startIndex ? "star-item" : "star-item light"
  13. array.push(
  14. <div onClick={ () => this.doEva(i)} key={ i} className={ cls}></div>
  15. )
  16. }
  17. return array
  18. }

完整代码

  1. import React from 'react';
  2. import './StarScore.scss';
  3. // 渲染5颗星得分方法
  4. class StarScore extends React.Component {
  5. renderScore() {
  6. let wm_poi_score = this.props.score || '';
  7. let score = wm_poi_score.toString();
  8. let scoreArray = score.split('.');
  9. // 满星个数
  10. let fullstar = parseInt(scoreArray[0]);
  11. // 半星个数
  12. let halfstar = parseInt(scoreArray[1]) >= 5 ? 1 : 0;
  13. // 灰色星个数
  14. let nullstar = 5 - fullstar - halfstar;
  15. let starjsx = [];
  16. // 渲染满星
  17. for (let i = 0; i < fullstar; i++) {
  18. starjsx.push(<div key={ i + 'full'} className="star fullstar"></div>)
  19. }
  20. // 渲染半星
  21. if (halfstar) {
  22. for (let j = 0; j < halfstar; j++) {
  23. starjsx.push(<div key={ j + 'half'} className="star halfstar"></div>)
  24. }
  25. }
  26. // 渲染灰色星
  27. if (nullstar) {
  28. for (let k = 0; k < nullstar; k++) {
  29. starjsx.push(<div key={ k + 'null'} className="star nullstar"></div>)
  30. }
  31. }
  32. return starjsx;
  33. }
  34. render() {
  35. return <div className="star-score">{ this.renderScore()}</div>;
  36. }
  37. }
  38. export default StarScore;

StarScore.scss

  1. .star-score {
  2. .star {
  3. width: 10px;
  4. height: 10px;
  5. float: left;
  6. background-size: cover;
  7. }
  8. .fullstar {
  9. background-image: url('./img/fullstar.png');
  10. }
  11. .halfstar {
  12. background-image: url('./img/halfstar.png');
  13. }
  14. .nullstar {
  15. background-image: url('./img/gray-star.png');
  16. }
  17. }
  18. import './Main.scss';
  19. import React from 'react';
  20. class Main extends React.Component {
  21. constructor(props) {
  22. super(props);
  23. }
  24. }
  25. /** * 点击评分 */
  26. doEva(i) {
  27. this.setState({
  28. startIndex: i + 1
  29. });
  30. }
  31. /** * 渲染评分用的星 */
  32. renderStar() {
  33. let array = []
  34. for (let i = 0; i < 5; i++) {
  35. let cls = i >= this.state.startIndex ? "star-item" : "star-item light"
  36. array.push(
  37. <div onClick={ () => this.doEva(i)} key={ i} className={ cls}></div>
  38. )
  39. }
  40. return array
  41. }
  42. render() {
  43. return (
  44. <div className="content">
  45. <div className="star-area">
  46. { this.renderStar()}
  47. </div>
  48. </div>
  49. );
  50. }
  51. }
  52. export default Main;
  53. .content {
  54. height: 100%; .eva-content {
  55. background-color: #fff;
  56. overflow: hidden;
  57. margin: px2rem(10px);
  58. margin-top: px2rem(74px);
  59. }
  60. .star-area {
  61. text-align: center;
  62. margin-top: px2rem(30px);
  63. }
  64. .star-item {
  65. width: px2rem(32px);
  66. height: px2rem(32px);
  67. background-image: url('./img/gray-star.png');
  68. background-size: cover;
  69. display: inline-block;
  70. margin-right: px2rem(10px); &.light {
  71. background-image: url('./img/light-star.png');
  72. }
  73. }
  74. }

发表评论

表情:
评论列表 (有 0 条评论,295人围观)

还没有评论,来说两句吧...

相关阅读