Browse Source

[新增] 评分组件

master
LAPTOP-D7TKRI82\邓 5 years ago
parent
commit
a10b38d2ed
  1. 20
      common/styles/sharedIconFont.css
  2. 281
      components/lf-rate/lf-rate.vue
  3. 4
      pages/login/index.vue

20
common/styles/sharedIconFont.css

@ -1,18 +1,26 @@
@font-face { @font-face {
font-family: "lf-iconfont"; /* Project id 2758976 */
src: url('//at.alicdn.com/t/font_2758976_9bezuvselm.woff2?t=1629452232587') format('woff2'),
url('//at.alicdn.com/t/font_2758976_9bezuvselm.woff?t=1629452232587') format('woff'),
url('//at.alicdn.com/t/font_2758976_9bezuvselm.ttf?t=1629452232587') format('truetype');
font-family: "le"; /* Project id 2758976 */
src: url('//at.alicdn.com/t/font_2758976_blqjbbep8zo.woff2?t=1629876001355') format('woff2'),
url('//at.alicdn.com/t/font_2758976_blqjbbep8zo.woff?t=1629876001355') format('woff'),
url('//at.alicdn.com/t/font_2758976_blqjbbep8zo.ttf?t=1629876001355') format('truetype');
} }
.lf-iconfont {
font-family: "lf-iconfont" !important;
.le {
font-family: "le" !important;
font-size: 16px; font-size: 16px;
font-style: normal; font-style: normal;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.lf-icon-xingxing-kong:before {
content: "\e649";
}
.lf-icon-xingxing-shi:before {
content: "\e651";
}
.lf-icon-shanchu:before { .lf-icon-shanchu:before {
content: "\e674"; content: "\e674";
} }

281
components/lf-rate/lf-rate.vue

@ -0,0 +1,281 @@
<template>
<view>
<view ref="uni-rate" class="uni-rate">
<view class="uni-rate__icon"
:style="{ 'margin-right': margin + 'px' }"
v-for="(star, index) in stars" :key="index"
@touchstart.stop="touchstart"
@touchmove.stop="touchmove">
<text class="le lf-icon-xingxing-shi" :style="{'color': color, 'font-size': size +'px'}" v-if="isFill"></text>
<text class="le lf-icon-xingxing-kong" :style="{'color': color, 'font-size': size +'px'}" v-else></text>
<!-- #ifdef APP-NVUE -->
<view :style="{ width: star.activeWitch.replace('%','')*size/100+'px'}" class="uni-rate__icon-on" >
<text class="le lf-icon-xingxing-shi" :style="{'text-align': 'left', 'color': disabled?'#ccc':activeColor, 'font-size': size +'px'}"></text>
</view>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<view :style="{ width: star.activeWitch}" class="uni-rate__icon-on">
<text class="le lf-icon-xingxing-shi" :style="{'color': disabled?disabledColor:activeColor, 'font-size': size +'px'}"></text>
</view>
<!-- #endif -->
</view>
<view class="uni-num" :style="{'color': activeColor}" v-if="number && valueSync">{{ valueSync }}</view>
</view>
</view>
</template>
<script>
// #ifdef APP-NVUE
const dom = uni.requireNativePlugin('dom');
// #endif
/**
* Rate 评分
* @description 评分组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=33
* @property {Boolean} isFill = [true|false] 星星的类型是否为实心类型, 默认为实心
* @property {String} color 未选中状态的星星颜色默认为 "#ececec"
* @property {String} activeColor 选中状态的星星颜色默认为 "#ffca3e"
* @property {String} disabledColor 禁用状态的星星颜色默认为 "#c0c0c0"
* @property {Number} size 星星的大小
* @property {Number} value/v-model 当前评分
* @property {Number} max 最大评分评分数量目前一分一颗星
* @property {Number} margin 星星的间距单位 px
* @property {Boolean} disabled = [true|false] 是否为禁用状态默认为 false
* @property {Boolean} readonly = [true|false] 是否为只读状态默认为 false
* @property {Boolean} allowHalf = [true|false] 是否实现半星默认为 false
* @property {Boolean} touchable = [true|false] 是否支持滑动手势默认为 true
* @event {Function} change uniRate value 改变时触发事件e={value:Number}
*/
export default {
name: "UniRate",
props: {
isFill: {
//
type: [Boolean, String],
default: true
},
color: {
//
type: String,
default: "#ececec"
},
activeColor: {
//
type: String,
default: "#ffca3e"
},
disabledColor: {
//
type: String,
default: "#c0c0c0"
},
size: {
//
type: [Number, String],
default: 24
},
value: {
//
type: [Number, String],
default: 1
},
max: {
//
type: [Number, String],
default: 5
},
margin: {
//
type: [Number, String],
default: 0
},
disabled: {
//
type: [Boolean, String],
default: false
},
readonly: {
//
type: [Boolean, String],
default: false
},
allowHalf: {
//
type: [Boolean, String],
default: false
},
touchable: {
//
type: [Boolean, String],
default: true
},
number: {
// value
type: Boolean,
default: false
}
},
data() {
return {
valueSync: ""
};
},
watch: {
value(newVal) {
this.valueSync = Number(newVal);
}
},
computed: {
stars() {
const value = this.valueSync ? this.valueSync : 0;
const starList = [];
const floorValue = Math.floor(value);
const ceilValue = Math.ceil(value);
for (let i = 0; i < this.max; i++) {
if (floorValue > i) {
starList.push({
activeWitch: "100%"
});
} else if (ceilValue - 1 === i) {
starList.push({
activeWitch: (value - floorValue) * 100 + "%"
});
} else {
starList.push({
activeWitch: "0"
});
}
}
return starList;
}
},
created() {
this.valueSync = Number(this.value);
this._rateBoxLeft = 0
this._oldValue = null
},
mounted() {
setTimeout(() => {
this._getSize()
}, 100)
},
methods: {
touchstart(e) {
if (this.readonly || this.disabled) return
const {
clientX,
screenX
} = e.changedTouches[0]
// TODO Nvue screenX clientX
this._getRateCount(clientX || screenX)
},
touchmove(e) {
if (this.readonly || this.disabled || !this.touchable) return
const {
clientX,
screenX
} = e.changedTouches[0]
this._getRateCount(clientX || screenX)
},
/**
* 获取星星个数
*/
_getRateCount(clientX) {
const size = Number(this.size)
if(size === NaN){
return new Error('size 属性只能设置为数字')
}
const rateMoveRange = clientX - this._rateBoxLeft
let index = parseInt(rateMoveRange / (size + this.margin))
index = index < 0 ? 0 : index;
index = index > this.max ? this.max : index;
const range = parseInt(rateMoveRange - (size + this.margin) * index);
let value = 0;
if (this._oldValue === index) return;
this._oldValue = index;
if (this.allowHalf) {
if (range > (size / 2)) {
value = index + 1
} else {
value = index + 0.5
}
} else {
value = index + 1
}
value = Math.max(0.5, Math.min(value, this.max))
this.valueSync = value
this._onChange()
},
/**
* 触发动态修改
*/
_onChange() {
this.$emit("input", this.valueSync);
this.$emit("change", {
value: this.valueSync
});
},
/**
* 获取星星距离屏幕左侧距离
*/
_getSize() {
// #ifndef APP-NVUE
uni.createSelectorQuery()
.in(this)
.select('.uni-rate')
.boundingClientRect()
.exec(ret => {
if (ret) {
this._rateBoxLeft = ret[0].left
}
})
// #endif
// #ifdef APP-NVUE
dom.getComponentRect(this.$refs['uni-rate'], (ret) => {
const size = ret.size
if (size) {
this._rateBoxLeft = size.left
}
})
// #endif
}
}
};
</script>
<style lang="scss" scoped>
.uni-rate {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
line-height: 1;
font-size: 0;
flex-direction: row;
}
.uni-rate__icon {
position: relative;
line-height: 1;
font-size: 0;
}
.uni-rate__icon-on {
overflow: hidden;
position: absolute;
top: 0;
left: 0;
line-height: 1;
text-align: left;
}
.uni-num{
font-size: 28rpx;
margin-left: 10rpx;
display: flex;
align-items: center;
}
</style>

4
pages/login/index.vue

@ -7,7 +7,7 @@
<view class="lf-m-t-30 lf-font-32" v-if="type == 'phone'">{{ userInfo.nickname || '游客用户' }}</view> <view class="lf-m-t-30 lf-font-32" v-if="type == 'phone'">{{ userInfo.nickname || '游客用户' }}</view>
<block v-if="type == 'userinfo'"> <block v-if="type == 'userinfo'">
<button class="btn" @click="getUserProfile"> <button class="btn" @click="getUserProfile">
<text class="lf-iconfont lf-icon-weixin lf-font-60 lf-text-vertical"></text>
<text class="le lf-icon-weixin lf-font-60 lf-text-vertical"></text>
<text class="lf-m-l-20">微信快捷登录</text> <text class="lf-m-l-20">微信快捷登录</text>
</button> </button>
<!-- <view class="lf-m-t-40 lf-font-28" @click="$toBack()">暂不绑定继续操作</view> --> <!-- <view class="lf-m-t-40 lf-font-28" @click="$toBack()">暂不绑定继续操作</view> -->
@ -15,7 +15,7 @@
</block> </block>
<block v-else-if="type == 'phone'"> <block v-else-if="type == 'phone'">
<button class="btn" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber"> <button class="btn" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">
<text class="lf-iconfont lf-icon-weixin lf-font-60 lf-text-vertical"></text>
<text class="le lf-icon-weixin lf-font-60 lf-text-vertical"></text>
<text class="lf-m-l-20">绑定手机号</text> <text class="lf-m-l-20">绑定手机号</text>
</button> </button>
<!-- <view class="lf-m-t-40 lf-font-28" @click="$url('/pages/login/accountLogin')">使用手机号登录</view> --> <!-- <view class="lf-m-t-40 lf-font-28" @click="$url('/pages/login/accountLogin')">使用手机号登录</view> -->

Loading…
Cancel
Save