ant-design-vue/components/rate/Rate.vue

135 lines
2.8 KiB
Vue
Raw Normal View History

2017-11-01 09:03:42 +00:00
<template>
<ul
2017-11-02 07:05:31 +00:00
:class="classes"
2017-11-01 09:03:42 +00:00
@mouseleave="onMouseLeave">
<template v-for="i in count">
<Star
ref="stars"
:index="i"
:disabled="disabled"
:prefix-cls="`${prefixCls}-star`"
:allowHalf="allowHalf"
2017-11-02 07:19:32 +00:00
:value="currentValue"
2017-11-01 09:03:42 +00:00
@onClick="onClick"
@onHover="onHover"
:key="i">
<template slot-scope="props">
<slot>
2017-11-02 07:05:31 +00:00
<span>{{character}}</span>
2017-11-01 09:03:42 +00:00
</slot>
</template>
</Star>
</template>
</ul>
</template>
<script>
2017-11-02 07:05:31 +00:00
import Star from './Star.vue'
import Icon from '../icon/index'
import { getOffsetLeft } from '../util/util'
2017-11-01 09:03:42 +00:00
export default {
name: 'Rate',
props: {
2017-11-02 07:05:31 +00:00
prefixCls: {
type: String,
default: 'ant-rate',
},
2017-11-01 09:03:42 +00:00
count: {
type: Number,
default: 5,
},
2017-11-02 07:05:31 +00:00
value: Number,
2017-11-01 09:03:42 +00:00
defaultValue: {
type: Number,
default: 0,
},
onChange: {
type: Function,
default: () => {},
},
onHoverChange: {
type: Function,
default: () => {},
},
allowHalf: {
type: Boolean,
default: false,
},
disabled: {
type: Boolean,
default: false,
},
2017-11-02 02:56:18 +00:00
character: {
type: String,
2017-11-02 07:05:31 +00:00
default: '★',
2017-11-02 02:56:18 +00:00
},
2017-11-01 09:03:42 +00:00
},
2017-11-02 07:05:31 +00:00
data () {
const { value, defaultValue } = this
const reValue = value === undefined ? defaultValue : value
2017-11-01 09:03:42 +00:00
return {
2017-11-02 07:19:32 +00:00
currentValue: reValue,
2017-11-02 07:05:31 +00:00
stateValue: reValue,
2017-11-01 09:03:42 +00:00
}
},
2017-11-02 07:05:31 +00:00
computed: {
classes () {
const { prefixCls, disabled } = this
return {
[`${prefixCls}`]: true,
[`${prefixCls}-disabled`]: disabled,
2017-11-01 09:03:42 +00:00
}
2017-11-02 02:56:18 +00:00
},
2017-11-01 09:03:42 +00:00
},
methods: {
2017-11-02 07:05:31 +00:00
onClick (event, index) {
const clValue = this.getStarValue(index, event.pageX)
this.stateValue = clValue
this.onMouseLeave()
this.$emit('input', clValue)
this.onChange(clValue)
2017-11-01 09:03:42 +00:00
},
2017-11-02 07:05:31 +00:00
onHover (event, index) {
2017-11-02 07:19:32 +00:00
this.currentValue = this.getStarValue(index, event.pageX)
this.changeValue(this.currentValue)
this.onHoverChange(this.currentValue)
2017-11-01 09:03:42 +00:00
},
getStarDOM (index) {
return this.$refs.stars[index].$el
},
getStarValue (index, x) {
2017-11-02 07:05:31 +00:00
let value = index
2017-11-01 09:03:42 +00:00
if (this.allowHalf) {
const leftEdge = getOffsetLeft(this.getStarDOM(0))
const width = getOffsetLeft(this.getStarDOM(1)) - leftEdge
2017-11-02 07:05:31 +00:00
if ((x - leftEdge - width * (index - 1)) < width / 2) {
2017-11-01 09:03:42 +00:00
value -= 0.5
}
}
return value
},
2017-11-02 07:05:31 +00:00
onMouseLeave () {
2017-11-02 07:19:32 +00:00
this.currentValue = undefined
2017-11-02 07:05:31 +00:00
this.changeValue()
this.onHoverChange()
},
changeValue (val) {
if (val === undefined) {
2017-11-02 07:19:32 +00:00
this.currentValue = this.stateValue
2017-11-02 07:05:31 +00:00
}
},
},
watch: {
value (val = 0) {
2017-11-02 07:19:32 +00:00
this.currentValue = this.stateValue = val
2017-11-02 07:05:31 +00:00
this.$emit('input', val)
2017-11-01 09:03:42 +00:00
},
},
components: {
Star,
Icon,
2017-11-02 07:05:31 +00:00
},
2017-11-01 09:03:42 +00:00
}
</script>