1. 程式人生 > >vue實現星級評價及上傳多張圖片等功能(類似淘寶商品評價頁面)

vue實現星級評價及上傳多張圖片等功能(類似淘寶商品評價頁面)

最近在寫一個關於vue的商城專案,然後整合在移動端中,開發需求中有一介面,類似淘寶商城評價介面!實現效果圖如下所示:

評價頁

點選看大圖,且可左右滑動

功能需求分析

  1. 預設為5顆星,為非常滿意,4顆滿意,根據不同星級顯示不同滿意程度。
    2.評價內容,最多為200字。
    3.上傳圖片最多上傳6張,圖片不可拉伸,可刪除,可點選放大左右滑動展示

具體實現關鍵程式碼

  1. 關於星級功能:
    寫一個五星陣列,預設陣列中有亮的星級圖片,用bool值判斷是否變暗。

     

        預設星級陣列

     

    點選實現的關鍵程式碼:

    // 評分
        rating: function (index, string) {
            var total = this.stars.length // 星星總數
            var idx = index + 1 // 這代表選的第idx顆星-也代表應該顯示的星星數量
            // 進入if說明頁面為初始狀態
            if (this.scoreStartNum === 0) {
              this.scoreStartNum = idx
              for (var i = 0; i < idx; i++) {
                this.stars[i].src = starOnImg
                this.stars[i].active = true
              }
            } else {
              // 如果再次點選當前選中的星級-僅取消掉當前星級,保留之前的。
              if (idx == this.scoreStartNum) {
                for (var i = index; i < total; i++) {
                  if (i != 0) {
                    this.stars[i].src = starOffImg
                    this.stars[i].active = false
                  }
                }
              }
              // 如果小於當前最高星級,則直接保留當前星級
              if (idx < this.scoreStartNum) {
                for (var i = idx; i < this.scoreStartNum; i++) {
                  if (i != 0) {
                    this.stars[i].src = starOffImg
                    this.stars[i].active = false
                  }
                }
              }
              // 如果大於當前星級,則直接選到該星級
              if (idx > this.scoreStartNum) {
                for (var i = 0; i < idx; i++) {
                  this.stars[i].src = starOnImg
                  this.stars[i].active = true
                }
              }
    
              var count = 0 // 計數器-統計當前有幾顆星
              for (var i = 0; i < total; i++) {
                if (this.stars[i].active) {
                  count++
                }
              }
              this.scoreStartNum = count
            }
            if (this.scoreStartNum === 1) {
              this.scoreInfo = '很差'
            } else if (this.scoreStartNum === 2) {
              this.scoreInfo = '差'
            } else if (this.scoreStartNum === 3) {
              this.scoreInfo = '一般'
            } else if (this.scoreStartNum === 4) {
              this.scoreInfo = '滿意'
            } else if (this.scoreStartNum === 5) {
              this.scoreInfo = '很滿意'
            }
  2. 評價內容輸入
<textarea v-bind:maxlength="Surplus" @input="descArea" v-model="inputText" name="abstract" id="abstract" placeholder="寶貝滿足你的期待嗎?說說你的使用心得,分享給想買的他們吧!"></textarea>

Surplus 表示最大限制字數,v-model繫結輸入字型,去掉邊框可以設定:border: none;

  1. 上傳多張圖片功能

單獨寫了個uploadImages元件,用input來設定圖片上傳

<input type="file"  class="input-file" multiple="multiple" name="avatar" ref="avatarInput" @change="changeImage($event)" accept="image/gif,image/jpeg,image/jpg,image/png">

在@change="handleChange"拿到圖片資訊,有兩種方式展示:

  1. 圖片流形式展示圖片
let reader = new FileReader()
          let that = this
          reader.readAsDataURL(file)
          reader.onload = function (e) {
            console.log(this.result)
            that.imgUrls.push(this.result)
          }

2.上傳阿里雲等第三方,直接拿到圖片url路徑,在此我用的第一種方式。
用mint-ui的錄播圖形式來做圖片的左右滑動功能。

<mt-swipe :auto="0" :show-indicators="false" @change="handleChange" :continuous="false" :defaultIndex="num">
            <mt-swipe-item v-for="(item,index) in imgUrls" :key="item.id">
              <div class="num"  >{{index+1+'/'+imgUrls.length}}</div>
                <img :src="imgUrls[index]" class="img"/>
            </mt-swipe-item>
          </mt-swipe>

:auto="0"為不自動播放,:show-indicators="false"表示不展示下面的圓點,:defaultIndex="num"預設展示第幾張圖片,:continuous="false" 是否重複播放。

關鍵程式碼為:

methods: {
    //拿到圖片資訊轉化為圖片流
    changeImage: function (e) {
      if (e.target.files.length <= (this.maxImages - this.imgUrls.length)) {
        for (var i = 0; i < e.target.files.length; i++) {
          let file = e.target.files[i]
          this.file = file
          console.log(this.file)
          let reader = new FileReader()
          let that = this
          reader.readAsDataURL(file)
          reader.onload = function (e) {
            console.log(this.result)
            that.imgUrls.push(this.result)
          }
        }
        // 剩餘張數
        this.leftImages = this.maxImages - (this.imgUrls.length + e.target.files.length)
        this.pictureNums = String(this.maxImages - (this.imgUrls.length + e.target.files.length)) + '/' + String(this.maxImages)
      } else {
        Toast('只能選擇' + (this.maxImages - this.imgUrls.length) + '張了')
      }
    },
    //刪除
    delect (index) {
      this.imgUrls.splice(index, 1)
      this.leftImages++
      console.log('數量' + this.leftImages)
      if (this.leftImages == this.maxImages) {
        this.pictureNums = '上傳圖片'
      } else {
        this.pictureNums = String(this.leftImages) + '/' + String(this.maxImages)
      }
    },
    //輪播圖滑動改變index
    handleChange(index){
      this.num = index
    },
    //看大圖
    bigImg (index) {
      this.showBigImg = true
      this.num = index
    }
  }

樣式如下

<template>
    <div class="avatar">
      <!--展示圖片-->
      <div class="hasPic" v-if="imgUrls.length>0" v-for="(item,index) in imgUrls">
        <img class="seledPic" ref="picture" :src="item?item:require('../../static/images/imagebj.jpg')" name="avatar" @click="bigImg(index)">
        <img class="delect" src="../../static/images/del.png" @click="delect(index)">
      </div>
      <!--點選方法圖左右滑動-->
      <div class="imgMask" v-if="showBigImg" @click.stop="showBigImg=!showBigImg">
        <div class="showImg">
          <mt-swipe :auto="0" :show-indicators="false" @change="handleChange" :continuous="false" :defaultIndex="num">
            <mt-swipe-item v-for="(item,index) in imgUrls" :key="item.id">
              <div class="num"  >{{index+1+'/'+imgUrls.length}}</div>
                <img :src="imgUrls[index]" class="img"/>
            </mt-swipe-item>
          </mt-swipe>

        </div>
      </div>
      <!--預設圖片-->
      <div class="selPic"  v-if="imgUrls.length<6">
        <img src="../../static/images/imagebj.jpg" name="avatar">
        <span>{{pictureNums}}</span>
        <input type="file"  class="input-file" multiple="multiple" name="avatar" ref="avatarInput" @change="changeImage($event)" accept="image/gif,image/jpeg,image/jpg,image/png">
      </div>
    </div>
  </template>

注意點:
1.專案中用到了mint -ui,轉移專案中錄播圖程式碼時,會報錯,在終端專案中輸入:npm i mint-ui -S