wangxueliang
7 years ago
9 changed files with 358 additions and 0 deletions
@ -0,0 +1,119 @@
|
||||
<template> |
||||
<ul |
||||
:class="[prefixCls, disabled ? `${prefixCls}-disabled` : '', className]" |
||||
@mouseleave="onMouseLeave"> |
||||
<template v-for="i in count"> |
||||
<Star |
||||
ref="stars" |
||||
:index="i" |
||||
:disabled="disabled" |
||||
:prefix-cls="`${prefixCls}-star`" |
||||
:allowHalf="allowHalf" |
||||
:value="currentValue" |
||||
@onClick="onClick" |
||||
@onHover="onHover" |
||||
:key="i"> |
||||
<template slot-scope="props"> |
||||
<slot> |
||||
<Icon type="star"/> |
||||
</slot> |
||||
</template> |
||||
</Star> |
||||
</template> |
||||
</ul> |
||||
</template> |
||||
|
||||
<script> |
||||
import Star from './Star.vue'; |
||||
import Icon from '../icon/index'; |
||||
import { getOffsetLeft } from '../util/util'; |
||||
|
||||
export default { |
||||
name: 'Rate', |
||||
props: { |
||||
count: { |
||||
type: Number, |
||||
default: 5, |
||||
}, |
||||
value: { |
||||
type: Number, |
||||
default: 0, |
||||
}, |
||||
defaultValue: { |
||||
type: Number, |
||||
default: 0, |
||||
}, |
||||
onChange: { |
||||
type: Function, |
||||
default: () => {}, |
||||
}, |
||||
onHoverChange: { |
||||
type: Function, |
||||
default: () => {}, |
||||
}, |
||||
allowHalf: { |
||||
type: Boolean, |
||||
default: false, |
||||
}, |
||||
disabled: { |
||||
type: Boolean, |
||||
default: false, |
||||
}, |
||||
className: String, |
||||
}, |
||||
data() { |
||||
return { |
||||
prefixCls: 'ant-rate', |
||||
hoverValue: undefined, |
||||
currentValue: undefined, |
||||
markValue: undefined, |
||||
} |
||||
}, |
||||
created () { |
||||
this.currentValue = this.markValue = this.value || this.defaultValue |
||||
}, |
||||
watch: { |
||||
hoverValue(val) { |
||||
if(val === undefined) { |
||||
this.currentValue = this.markValue; |
||||
return; |
||||
} |
||||
this.currentValue = val; |
||||
} |
||||
}, |
||||
methods: { |
||||
onClick(event, index) { |
||||
let clValue = this.getStarValue(index, event.pageX); |
||||
this.markValue = clValue; |
||||
this.onMouseLeave(); |
||||
this.onChange(clValue); |
||||
}, |
||||
onHover(event, index) { |
||||
this.hoverValue = this.getStarValue(index, event.pageX); |
||||
this.onHoverChange(this.hoverValue); |
||||
}, |
||||
getStarDOM (index) { |
||||
return this.$refs.stars[index].$el |
||||
}, |
||||
getStarValue (index, x) { |
||||
let value = index; |
||||
if (this.allowHalf) { |
||||
const leftEdge = getOffsetLeft(this.getStarDOM(0)) |
||||
const width = getOffsetLeft(this.getStarDOM(1)) - leftEdge |
||||
if ((x - leftEdge - width * (index-1)) < width / 2) { |
||||
value -= 0.5 |
||||
} |
||||
} |
||||
return value |
||||
}, |
||||
onMouseLeave() { |
||||
this.hoverValue = undefined |
||||
this.onHoverChange(undefined); |
||||
}, |
||||
}, |
||||
components: { |
||||
Star, |
||||
Icon, |
||||
} |
||||
} |
||||
</script> |
@ -0,0 +1,52 @@
|
||||
<template> |
||||
<li |
||||
:class="getClassName()" |
||||
@click="onClick" |
||||
@mousemove="onHover"> |
||||
<div :class="`${this.prefixCls}-first`"><slot></slot></div> |
||||
<div :class="`${this.prefixCls}-second`"><slot></slot></div> |
||||
</li> |
||||
</template> |
||||
<script> |
||||
export default { |
||||
name: 'Star', |
||||
props: { |
||||
index: Number, |
||||
disabled: Boolean, |
||||
prefixCls: String, |
||||
allowHalf: Boolean, |
||||
value: Number, |
||||
}, |
||||
data() { |
||||
return { |
||||
} |
||||
}, |
||||
mounted() { |
||||
}, |
||||
computed: { |
||||
|
||||
}, |
||||
methods: { |
||||
getClassName() { |
||||
const { prefixCls, index, value, allowHalf } = this; |
||||
const starValue = index; |
||||
if (allowHalf && value + 0.5 === starValue) { |
||||
return `${prefixCls} ${prefixCls}-half ${prefixCls}-active`; |
||||
} |
||||
return starValue <= value ? `${prefixCls} ${prefixCls}-full` : `${prefixCls} ${prefixCls}-zero`; |
||||
}, |
||||
onClick(e) { |
||||
if(this.disabled) return; |
||||
this.$emit("onClick", e, this.index); |
||||
}, |
||||
onHover(e) { |
||||
if(this.disabled) return; |
||||
this.$emit("onHover", e, this.index); |
||||
}, |
||||
}, |
||||
watch: { |
||||
}, |
||||
commponents: { |
||||
} |
||||
} |
||||
</script> |
@ -0,0 +1,3 @@
|
||||
import Rate from './Rate'; |
||||
|
||||
export default Rate; |
@ -0,0 +1,2 @@
|
||||
import '../../style/index.less'; |
||||
import './index.less'; |
@ -0,0 +1,73 @@
|
||||
@import "../../style/themes/default"; |
||||
@import "../../style/mixins/index"; |
||||
|
||||
@rate-prefix-cls: ~"@{ant-prefix}-rate"; |
||||
|
||||
.@{rate-prefix-cls} { |
||||
margin: 0; |
||||
padding: 0; |
||||
list-style: none; |
||||
font-size: 20px; |
||||
display: inline-block; |
||||
vertical-align: middle; |
||||
|
||||
&-disabled &-star { |
||||
cursor: not-allowed; |
||||
&:hover { |
||||
transform: scale(1); |
||||
} |
||||
} |
||||
|
||||
&-star { |
||||
margin: 0; |
||||
padding: 0; |
||||
display: inline-block; |
||||
margin-right: 8px; |
||||
position: relative; |
||||
transition: all .3s; |
||||
color: @rate-star-bg; |
||||
cursor: pointer; |
||||
|
||||
&-first, |
||||
&-second { |
||||
user-select: none; |
||||
transition: all .3s; |
||||
} |
||||
|
||||
&:hover { |
||||
transform: scale(1.1); |
||||
} |
||||
|
||||
&-first { |
||||
position: absolute; |
||||
left: 0; |
||||
top: 0; |
||||
width: 50%; |
||||
height: 100%; |
||||
overflow: hidden; |
||||
opacity: 0; |
||||
} |
||||
|
||||
&-half &-first, |
||||
&-half &-second { |
||||
opacity: 1; |
||||
} |
||||
|
||||
&-half &-first, |
||||
&-full &-second { |
||||
color: @rate-star-color; |
||||
} |
||||
|
||||
&-half:hover &-first, |
||||
&-full:hover &-second { |
||||
color: tint(@rate-star-color, 20%); |
||||
} |
||||
} |
||||
|
||||
&-text { |
||||
margin-left: 8px; |
||||
vertical-align: middle; |
||||
display: inline-block; |
||||
font-size: @font-size-base; |
||||
} |
||||
} |
@ -0,0 +1,40 @@
|
||||
function getScroll(w, top) { |
||||
let ret = top ? w.pageYOffset : w.pageXOffset; |
||||
const method = top ? 'scrollTop' : 'scrollLeft'; |
||||
if (typeof ret !== 'number') { |
||||
const d = w.document; |
||||
// ie6,7,8 standard mode
|
||||
ret = d.documentElement[method]; |
||||
if (typeof ret !== 'number') { |
||||
// quirks mode
|
||||
ret = d.body[method]; |
||||
} |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
function getClientPosition(elem) { |
||||
let box; |
||||
let x; |
||||
let y; |
||||
const doc = elem.ownerDocument; |
||||
const body = doc.body; |
||||
const docElem = doc && doc.documentElement; |
||||
box = elem.getBoundingClientRect(); |
||||
x = box.left; |
||||
y = box.top; |
||||
x -= docElem.clientLeft || body.clientLeft || 0; |
||||
y -= docElem.clientTop || body.clientTop || 0; |
||||
return { |
||||
left: x, |
||||
top: y, |
||||
}; |
||||
} |
||||
|
||||
export const getOffsetLeft = (el) => { |
||||
const pos = getClientPosition(el); |
||||
const doc = el.ownerDocument; |
||||
const w = doc.defaultView || doc.parentWindow; |
||||
pos.left += getScroll(w); |
||||
return pos.left; |
||||
} |
@ -0,0 +1,63 @@
|
||||
<template> |
||||
<div> |
||||
基本 |
||||
<Rate className="custom"></Rate> |
||||
</br> |
||||
半星 |
||||
<Rate :allowHalf="allowHalf"></Rate> |
||||
</br> |
||||
默认3颗星 |
||||
<Rate :value="initValue"></Rate> |
||||
</br> |
||||
只读 |
||||
<Rate :value="initValue" :disabled="disabled"></Rate> |
||||
</br> |
||||
回调函数 |
||||
<Rate |
||||
:onChange="onChange" |
||||
:onHoverChange="onHoverChange"></Rate> |
||||
<span v-if="hoverValue">{{hoverValue}}stars</span> |
||||
<span v-if="rValue">{{rValue}}stars</span> |
||||
<br/> |
||||
<Rate |
||||
:allowHalf="allowHalf" |
||||
:onHoverChange="onHoverChangeAH"></Rate> |
||||
<span v-if="hoverValueAH">{{hoverValueAH}}stars</span> |
||||
</br> |
||||
自定义 |
||||
<Rate :value="initValue"> |
||||
<template slot-scope="props"> |
||||
<span>A</span> |
||||
</template> |
||||
</Rate> |
||||
</div> |
||||
</template> |
||||
<script> |
||||
import { Rate } from '../components/index' |
||||
export default { |
||||
data () { |
||||
return { |
||||
allowHalf: true, |
||||
initValue: 3, |
||||
disabled: true, |
||||
hoverValue: undefined, |
||||
rValue: undefined, |
||||
hoverValueAH: undefined, |
||||
} |
||||
}, |
||||
methods: { |
||||
onHoverChange(val) { |
||||
this.hoverValue = val; |
||||
}, |
||||
onChange(val) { |
||||
this.rValue = val; |
||||
}, |
||||
onHoverChangeAH(val) { |
||||
this.hoverValueAH = val; |
||||
} |
||||
}, |
||||
components: { |
||||
Rate |
||||
}, |
||||
} |
||||
</script> |
Loading…
Reference in new issue