Commit bc4a424b authored by June's avatar June

fixed:完善星评组件

parent eab45325
......@@ -2,22 +2,24 @@
<view class="rate-wrap">
<view
class="rate_icon"
:style="{ 'margin-right': marginNumber + 'px' }"
v-for="(star, index) in stars"
:style="{ 'margin-right': marginNumber + 'px' }"
:key="index"
@touchstart.stop="touchstart"
@touchstart="touchstart($event, index + 1)"
@touchmove.stop="touchmove"
@mousedown.stop="mousedown"
@mousemove.stop="mousemove"
@mouseleave="mouseleave"
>
<text
class="start"
:style="starSize"
/>
<view class="rate_icon-on" :style="{ width: star.activeWitch}">
<view
class="rate_icon-on"
:style="{ width: star.activeWitch}"
>
<text
class="start_fill"
:style="starSize"
/>
</view>
</view>
......@@ -25,22 +27,11 @@
</template>
<script>
/**
* @param {Number} size 星星的大小
* @param {Number} value/v-model 当前评分
* @param {Number} max 最大评分评分数量,目前一分一颗星
* @param {Number} margin 星星的间距,单位 px
* @param {Boolean} disabled = [true|false] 是否为禁用状态,默认为 false
* @param {Boolean} readonly = [true|false] 是否为只读状态,默认为 false
* @param {Boolean} allowHalf = [true|false] 是否实现半星,默认为 false
* @param {Boolean} touchable = [true|false] 是否支持滑动手势,默认为 true
* @event {Function} change Rate 的 value 改变时触发事件,e={value:Number}
*/
import { throttle } from '@/utils/common.js'
export default {
name: "Rate",
props: {
size: {
size: { // px
type: [Number, String],
default: 17
},
......@@ -55,37 +46,34 @@
default: 5
},
margin: {
// 星星的间距
// 星星的间距 px
type: [Number, String],
default: 0
},
disabled: {
// 是否可点击
type: [Boolean, String],
type: Boolean,
default: false
},
readonly: {
// 是否只读
type: [Boolean, String],
type: Boolean,
default: false
},
allowHalf: {
// 是否显示半星
type: [Boolean, String],
type: Boolean,
default: true
},
touchable: {
// 是否支持滑动手势
type: [Boolean, String],
type: Boolean,
default: true
}
},
data() {
return {
valueSync: "",
userMouseFristMove: true,
userRated: false,
userLastRate: 1
valueSync: ''
};
},
watch: {
......@@ -102,15 +90,15 @@
for (let i = 0; i < this.max; i++) {
if (floorValue > i) {
starList.push({
activeWitch: "100%"
activeWitch: '100%'
});
} else if (ceilValue - 1 === i) {
starList.push({
activeWitch: (value - floorValue) * 100 + "%"
activeWitch: (value - floorValue) * 100 + '%'
});
} else {
starList.push({
activeWitch: "0"
activeWitch: '0'
})
}
}
......@@ -119,12 +107,16 @@
marginNumber() {
return Number(this.margin)
},
starSize() {
const size = this.size
return `width: ${size}px;height: ${size}px;`
}
},
created() {
this.valueSync = Number(this.value)
this._rateBoxLeft = 0
this._oldValue = null
},
mounted() {
setTimeout(() => {
......@@ -132,20 +124,23 @@
}, 100)
},
methods: {
touchstart(e) {
if (this.readonly || this.disabled) return
const { clientX } = e.changedTouches[0]
this._getRateCount(clientX)
touchstart(e, idx) {
if (this.readonly || this.disabled || !this.touchable) return
if(this.valueSync === 1) {
this.valueSync = 0
} else {
this.valueSync = idx
}
this._onChange()
},
touchmove(e) {
touchmove: throttle(function (e) {
if (this.readonly || this.disabled || !this.touchable) return
const { clientX } = e.changedTouches[0]
this._getRateCount(clientX)
},
}, 200),
/**
* 获取星星个数
*/
// 获取星星个数
_getRateCount(clientX) {
this._getSize()
const size = Number(this.size)
......@@ -154,16 +149,17 @@
}
// move星星的距离
const rateMoveRange = clientX - this._rateBoxLeft
let index = parseInt(rateMoveRange / (size + this.marginNumber))
const marginNumber = this.marginNumber
let index = parseInt(rateMoveRange / (size + marginNumber))
index = index < 0 ? 0 : index;
index = index > this.max ? this.max : index;
const range = parseInt(rateMoveRange - (size + this.marginNumber) * index);
console.log(range)
let value = 0;
if (this._oldValue === index) return;
this._oldValue = index;
// 移入星星的距离
const range = parseInt(rateMoveRange - (size + marginNumber) * index)
let value = 0
if (this.allowHalf) {
if (range > (size / 2)) {
if(range <= 0 && index === 0) {
value = 0
} else if (range > (size / 2)) {
value = index + 1
} else {
value = index + 0.5
......@@ -171,32 +167,28 @@
} else {
value = index + 1
}
value = Math.max(0.5, Math.min(value, this.max))
console.log(value)
value = Math.max(0, Math.min(value, this.max))
this.valueSync = value
this._onChange()
},
/**
* 触发动态修改
*/
// 触发动态修改
_onChange() {
this.$emit("update:modelValue", this.valueSync);
this.$emit("update:value", this.valueSync);
this.$emit("change", {
value: this.valueSync
});
},
/**
* 获取星星距离屏幕左侧距离
*/
//获取星星距离屏幕左侧距离
_getSize() {
uni.createSelectorQuery()
.in(this)
.select('.rate-wrap')
.boundingClientRect()
.exec(ret => {
if (ret) {
this._rateBoxLeft = ret[0].left
.exec(res => {
if (res) {
this._rateBoxLeft = res[0].left
}
})
}
......@@ -229,26 +221,14 @@
.start {
display: inline-block;
width: 34rpx;
height: 34rpx;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAMAAAAPzWOAAAAApVBMVEUAAAD/Zhr/byr/Zhr/jlj/eCb/Zhv/aBz/Zhr/Zxv/Zhr/Zhr/Zxr/Zxv/Zhr/Zhr/Zxr/Zxv/aBv/aRz/Zxr/Zxv/aBv/aBv/Zxz/ax7/Zhr/Zhr/Zhv/Zhr/Zxr/Zxv/Zxz/ax7/aiH/ah//Zxr/Zxr/Zxr/Zxv/Zxv/Zx3/aBz/Zxr/Zxv/Zhv/Zxv/Zxv/aB3/Zhr/Zxv/Zhv/Zxv/Zxr/ZhqOyFXpAAAANnRSTlMA+wzxAgaNO/az4+msSuzYt3BPLMGAZ0AkGdPFvKViVTUfExCYk4Z4X0Ux3J6CfFgpznLKa7mhqILLAAACjElEQVRYw+2W2XqqMBSF2cwzgoJWFGvV43isU9f7P1o/9StoxSTE264bwR3/bJM9KX9qLGvYj5yR/hLDxEWO+gIjBqXtXuZhKM94sxGcP3sali/8Gf/6MEf+giPt65MaYvmaI1dXOnKMDxsrRSld6UpB/sGpXrYYSDmi4b16m2iwZB2plMq4MqkckXflP1qML4QdsRhnJOrI4OGQmroSEKya69oKA4xd4hNmj4YF0FmsOFVB7wXx7GtNAMisq0OFDQBeZzMftWtYk5HpRISLaN1K209SMvb7Nq5yO9NsfGvMNAAgdzCNg56hsDXuZj87klktjoHBPNkZSgPp4+XJJwxLNCFTpPROSMqYcBRJpWXsOEikix+8EhLIQj5KiImZLGRRls02qCvHGHtYVNlmS1F67s2V6BvYSylGfhv9U9iND3fnonOfQTNQw3tuexioD52KRk0YqxAto6a602eDgA/hGLUhTAtRhqXBr8/XOZAJM4bPpqeDIMWyS0aNTiBLIOs8bFhT3BQDkQZ71Jk9i0jlQvq8MSNEjwvRMOYt+OBCXM5GbwgVrlqcSrgUmc1MTjs9iBS5gjMbb3ASyBv0mfajyDikgphxYmOi8LXGjlV44SoCcsAqPQm+xAbLlGGdwxSBfMJnWIcofh9iMZvGb7/LKyJmar3fI7bXwWV6jzGIjKcMnaDero09IE8PDsE271IqwooRAOENsXCB/JL0Ox/Qtjf8FrrPIWSXbo4iYB+UDaIFeHFpPLIqyv6nPwd7YH3XQawccAv9erBkG6y704LzDzqAm1WhXYGj0ZmxhslOQPT9PhAejLo9IsD1c0LOrqFxCMBLnyzSiwgAmbw6bFiJpbN6cLJUlT9x9Q2wO0gQqPtdlQAAAABJRU5ErkJggg==);
background-position: 0 0;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.start_fill_half {
display: inline-block;
width: 34rpx;
height: 34rpx;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAMAAAAPzWOAAAAAqFBMVEUAAAD2kYn/Zhr/Zhv/Zhv/Zhr/Zhv/Zhv/eiH/Zxv/aB3/aR3/ay3/l2n/Zxr/Zxr/aBr/Zxz/Zhv/Zhr/Zhr/Zhr/Zxv/Zxr/aiL/ah//Zhr/Zhr/Zhv/Zxv/Zhv/Zxv/aBz/ahz/ah7/ayH/fTT/Zxv/Zxv/aBv/Zxr/Zxz/bCH/cyb/Zxr/Zxr/Zxr/Zhv/Zxz/Zxr/Zhr/Zhr/Zhz/aBz/Zxv/ZhrAwdp6AAAAN3RSTlMAGfzujfLbswdyPSsLArh+TET66OPFpIc4IPbr0peCeDIaEg8Evp5nXyQWDcGtqW5ZVdbLZFHJ+Q6zgQAAAkxJREFUWMPt1tuSojAQBuAMR1EURUBAHNDxfNbR/d//zbZW2cQRCSHezn9JFV81JN3V5De10wzOhnlqv2UMcIu5ecM4AEC4GCKQN8YxAHyQlY6eNKLhjpAUvqyxjv8j9hA9+UJyhKTYShaiM2Sjoil5vAwhDmYyxkR/RL7kShmAItKlTHSG5KWEtZFPMCR/0KlrfKkMoaWFkoUwhAzqltJVishEhSMMNFrXvYsiQpbAdplVTIXpqnsYdYy8iCJCLjoA9Lfz9NqyX/zHk2bSt0sRsrZ2SYx7vNloMX40FjpoShCWqLfQzPPtgxWtQR9bgCDC0o56h72CgNJuPYQldNGld0IWIQ69O6Y8Mkb/fWRNEU0eWdIB0ZJGoj6WtNskkciDyc58LoWsPPhfhGUkgbT62NqEiCkfpcbsuQu1mkg2RKdRnO61kEyFyQwWpwYSqthNyaukwkhTxz43CrEEkWaMoM3ZjESQ9RBz3hY3EkEG+OYZZKIIIEnVxqMKICqi9xEPK64xhgDSQZeL9EQQDSkXsUSQZcVuPBdBQiRc5FsEseFOeYgughADLY4RQQgxceIgXTFkgE8OkoohR+w4SPAKCazx83iFwUESvIwy+sk0FKVRarTdIuA7lqkg1ibkIWdk5ctrkbgt9Ks9oDv2Q/dwhoH9NE0S2mhZBxha9Bv+oCl4YY3jj7nqA96lff+xStwoR46M8BbT50uUAMbpn2FAq27AvPRCjgbg7XwFvs2fBSqAvrMpWZcvBgBXs6uW8vDa5M3yrNvbkN9U5i8qUQdciqz2fwAAAABJRU5ErkJggg==);
background-position: 0 0;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.start_fill {
display: inline-block;
width: 34rpx;
height: 34rpx;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEQAAABECAMAAAAPzWOAAAAAmVBMVEUAAAD/Zxr/Zhr/Zhr/cC7/dCX/Zhv/Zxv/aBz/Zhv/Zxr/Zhr/Zxr/Zxr/Zhv/Zxz/Zxz/Zhr/Zhv/Zxr/Zhr/Zxr/aBr/aB3/aRz/aBv/ahr/aB3/Zxr/Zxv/aBv/Zxv/aB//aCD/Zhr/Zxr/Zxr/Zxv/Zxv/ZiL/aB//aCL/Zhv/Zhv/Zxr/cRz/Zhr/Zxr/aBv/aR7/Zhprn+e+AAAAMnRSTlMA/PbrBQnaQTb68OaimmxRLN++spRgTEY7MCYii3VmXCgg49XOyKoeGA62qFYSf35xETz/Gz4AAAG8SURBVFjD7dbbcoIwEIDhTSgnAUE5CHi2Wu253fd/uLaOpiCYLGGmvfG/FT92lhkI3Pqf1sm99ez0M5wBfsfSPoY5wmO87IF84KnnHoN4Z4SttJEhivweg4hYqT9I71HuNlWETbWQBdYKtAYZ1RG27jGIKOgxiMjdd0ZSbJR0NfZeE3HzbsbjFlsyVvRtlNnMwNZ48FKYin9PJ8PkyWIozxsH8zBqscxsFlsudmk0TtLXqhFZqJWRVda4Qc14IZA5avcgkFgf8QTypI8YAnnTR2KBHAxdg+UgsrkmMoRK9kDLWECtXENhafOr29lYQqPC6Gi8QEtRJ8UNobWVRzd4BlcqN2RjAlebjoiGDZLWpL0wG6QtKchM9ZbmBKQARRYBeVQhlKWsFcYBCWUKxKYgc+URi5CvQAIKslUgOwrC7+TIACmVUmOPpEIpMqEh71JkTv14yvJpyL0U2eJF7sNwETS2zaSPh19c7B8P468zjvUiifGJtWJx7SFxsdpEgpgMfxs7tTenX/0tB0ljPLdr3CyK8Zwh3UnBT+sPoSXnfI8lSMstRLRSuJK9+5ljqTwKO6EDklahbcKtv+kLjzJulSJV8MoAAAAASUVORK5CYII=);
background-position: 0 0;
background-repeat: no-repeat;
......
......@@ -16,7 +16,7 @@
<view class="w-100 my-4 flex j-star a-center">
<view class="font-32 font-bold mr-2">商品评分</view>
<rate
:value="1.3"
:value.sync="form.v1"
size="17"
margin="15"
/>
......@@ -27,16 +27,17 @@
class="input-area font-24"
placeholder-class="icon-edit"
placeholder="说说您的使用感受,为更多小伙伴购买提供参考~"
maxlength="10"
v-model="form.val"
/>
<view class="w-100 flex j-between a-end">
<viwe class="flex j-start a-center">
<view class="flex flex-column j-center a-center mr-2">
<view class="flex flex-column j-center a-center mr-2" @click="handlePhoto">
<image class="icon" src="/static/images/common/icon-img.png" mode="aspectFit" />
<text>添加图片</text>
</view>
<view class="flex flex-column j-center a-center">
<view class="flex flex-column j-center a-center" @click="handleVideo">
<image class="icon" src="/static/images/common/icon-video.png" mode="aspectFit" />
<text>添加视频</text>
</view>
......@@ -58,7 +59,7 @@
<view class="w-100 my-4 flex j-star a-center">
<view class="font-2 mr-2">商品评分</view>
<rate
:value="1.3"
:value.sync="form.v2"
size="17"
margin="15"
/>
......@@ -67,7 +68,7 @@
<view class="w-100 my-4 flex j-star a-center">
<view class="font-28 mr-2">商品评分</view>
<rate
:value="1.3"
:value.sync="form.v3"
size="17"
margin="15"
/>
......@@ -76,7 +77,7 @@
<view class="w-100 my-4 flex j-star a-center">
<view class="font-28 mr-2">商品评分</view>
<rate
:value="1.3"
:value.sync="form.v4"
size="17"
margin="15"
/>
......@@ -85,7 +86,7 @@
<view class="descColor font-24">满意请给5星哦~</view>
</view>
<view class="submit font-32 text-center">提交</view>
<view class="submit font-32 text-center" @click="handleSubmit">提交</view>
</view>
</template>
......@@ -98,6 +99,10 @@
data() {
return {
form: {
v1: 0,
v2: 0,
v3: 0,
v4: 0,
val: ''
}
}
......@@ -105,7 +110,33 @@
computed: {
words() {
return this.form.val.trim().length
return this.form.val.length
}
},
methods: {
async handlePhoto() {
try{
const a = await this.$cWx('chooseImage', {count: 5})
console.log(a)
}catch(e){
console.log(e)
this.$toast({title: '程序错误'})
}
},
async handleVideo() {
try{
const a = await this.$cWx('chooseVideo', {count: 5})
console.log(a)
}catch(e){
console.log(e)
this.$toast({title: '程序错误'})
}
},
handleSubmit() {
console.log(this.form)
}
}
}
......
import { isFunction } from "@/utils/types.js"
import { isFunction, isObeject } from "@/utils/types.js"
import Toast from "@/lib/toast/index.js"
import store from "@/store/index.js"
/**
......@@ -103,4 +103,38 @@ export function getURLwithArgs(){
}
urlWithArgs = urlWithArgs.substring(0, urlWithArgs.length-1)
return urlWithArgs
}
/**
* @desc 微信接口promise
* @param { String } wxapi *
* @param { Object } ops 接口的配置
* @param { Object } cops 自定义的配置
*/
export function cWx(wxapi, ops = {}, cops = {}) {
if(!isObeject(ops) || !isObeject(cops)) throw new Error('配置必须是对象')
if(cops.loading) {
wx.showLoading({
mask: true
})
}
return new Promise((resolve, reject) => {
wx[wxapi]({
...ops,
success: res => {
cops.scb && typeof cops.scb === 'function' && cops.scb()
resolve({status: true, data: res, msg: 'success'})
},
fail: err => {
cops.fcb && typeof cops.fcb === 'function' && cops.fcb()
reject({status: true, data: null, msg: err})
},
complete: () => {
cops.ccb && typeof cops.ccb === 'function' && cops.ccb()
if(cops.loading) {
wx.hideLoading()
}
}
})
})
}
\ No newline at end of file
......@@ -5,12 +5,14 @@ import Modal from '@/lib/modal/index.js'
import { checkLogin } from '@/utils/modules/login.js'
import globalMixins from '@/mixins/globalMixins.js'
import dayjs from 'dayjs'
import { cWx } from '@/utils/common.js'
Vue.prototype.$getStorage = getStorage
Vue.prototype.$setStorage = setStorage
Vue.prototype.$toast = Toast
Vue.prototype.$modal = Modal
Vue.prototype.$checkLogin = checkLogin
Vue.prototype.$cWx = cWx
Vue.filter('parseTime', timestamp => {
if (!~~timestamp) return '——'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment