vue 星星评分组件

2018-12-04  本文已影响36人  _是七栎啊_

评分插件在购物的应用中经常可以看得到,但是用着别人的总是没有自己写的顺手,正好趁着这段时间做一个移动端应用的时候写了一个基于VUE的评分组件,功能没有写全

效果图.gif

主体结构:

.scoreLayer(v-show="isShowScore" @click="hideScoreLayer($event)")
  .center-box
    .star-box.flex-between
      ul.star-list(@touchstart="touchStart" @touchmove="touchMove" ref="star")
        li.star-item(
          v-for="i in scoreList"
          :class="{half: i.state == 1, full: i.state == 2}"
        )
      p.star-num {{score}}分
    button.btn-confirm(@click="submit") 确定

最外层是一个遮罩,因为评分做成一个弹框形式,因此给弹框一个层,让其浮动在其他内容之上
接下来是样式设计:

.flex-between
  display flex
  justify-content space-between
.scoreLayer
  display flex
  align-items center
  justify-content center
  background-color rgba(0,0,0,.3)
  .center-box
    padding-top 0.4rem
    padding-bottom 0.4rem
    width 50%
    background-color #FFF
    border-radius 5px
    box-shadow 0 0 5px #ccc
    .star-box
      padding 0 0.2rem
      align-items center
    .star-item
      display inline-block
      width 0.5rem
      height 0.5rem
      background url('./img/emptyStar.png') no-repeat center
      background-size 0.5rem 0.5rem
      &.half
        background url('./img/halfStar.png') no-repeat center
      &.full
        background url('./img/fullStar.png') no-repeat center

基本样式就不多说了,将该组件的效果实现吧

export default {
  data () {
    return {
      x0: 0, // 滑动初始点击位置
      len: 0, // 包裹星星的div的宽度
      score: 0, // 分数
      isShowScore: false // 是否显示弹框
    }
  },
  computed: {
    scoreList () {
      // 用一个数组存储每个星星的状态,如果是满星就是2,半星就是1,没有就是0
      let i = 1
      let state
      const stateArr = []
      do {
        if (this.score >= 2 * i ) {
          state = 2
        } else if (this.score == 2 * i - 1) {
          state = 1
        } else {
          state = 0
        }
        stateArr.push({
          state
        })
        i++
      } while (i <= 5)
      return stateArr
    }
  },
  methods: {
    hideScoreLayer (evt) {
      if (typeof evt ==='symbol' || (evt && evt.target.classList.contains('scoreLayer'))) {
        this.isShowScore = false
        this.score = 0
      }
    },
    showScoreLayer () {
      this.isShowScore = true
    },
    touchStart (evt) {
      if (evt && evt.touches.length === 1) {
        this.len = this.$refs.star.offsetWidth
        this.x0 = evt.touches[0].clientX
      }
    },
    touchMove (evt) {
      this.score = 0
      if (evt) {
        let score = parseInt((evt.touches[0].clientX - this.x0)/this.len * 10)
        this.score = score > 10 ? 10 : score
      }
    },
    submit () {
      // 提交数据
    }
  }
}

在这个组件中,只实现了右滑评分的效果,如果需要左滑就需要在touchMove事件中进一步判断
上述仅是我的一个小小的分享,可能有不好的地方,可以给我提出来,thx,告辞~

上一篇下一篇

猜你喜欢

热点阅读