pull/2/head
Leopoldthecoder 2016-08-17 19:56:39 +08:00
parent f301f215c6
commit 1c3d119caf
15 changed files with 525 additions and 1 deletions

View File

@ -151,5 +151,8 @@
],
"card": [
"./packages/card/index.js"
],
"rate": [
"./packages/rate/index.js"
]
}

91
examples/docs/rate.md Normal file
View File

@ -0,0 +1,91 @@
<script>
export default {
data() {
return {
value1: null,
value2: null,
value3: null,
value4: null,
value5: 3.6
};
}
}
</script>
<style>
.demo-box.demo-rate {
margin: 20px 0;
}
</style>
## 基础用法
<div class="demo-box demo-rate">
<el-rate v-model="value1"></el-rate>
</div>
``` html
<el-rate v-model="value1"></el-rate>
```
## 区分颜色
利用颜色对分数及情感倾向进行分级。分数可以被分为三个等级,对应的两个阈值可分别通过 `low-threshold``high-threshold` 设定。
<div class="demo-box demo-rate">
<el-rate v-model="value2" multi-color></el-rate>
</div>
``` html
<el-rate v-model="value2" multi-color></el-rate>
```
## 辅助文字
为组件设置 `show-text` 属性会在右侧显示辅助文字。通过设置 `texts` 可以为每一个分值指定对应的辅助文字。`texts` 为一个数组,长度应等于最大值 `max`
<div class="demo-box demo-rate">
<el-rate v-model="value3" show-text></el-rate>
</div>
``` html
<el-rate v-model="value3" show-text></el-rate>
```
## 其他 icon
<div class="demo-box demo-rate">
<el-rate v-model="value4" smiley></el-rate>
</div>
``` html
<el-rate v-model="value4" smiley></el-rate>
```
## 只读
为组件设置 `disabled` 属性表示组件为只读,支持小数分值。此时若设置 `show-text`,则会在右侧显示目前的分值。可以提供 `text-template` 作为显示模板,模板为一个包含了 `{value}` 的字符串,`{value}` 会被解析为分值。
<div class="demo-box demo-rate">
<el-rate v-model="value5" disabled show-text text-template="{value} 分"></el-rate>
</div>
``` html
<el-rate v-model="value5" disabled show-text text-template="{value} 分"></el-rate>
```
## Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---------- |-------- |---------- |------------- |-------- |
| v-model | 绑定值 | Number | | 0 |
| max | 最大分值 | Number | | 5 |
| multi-color | 是否根据分数等级区分颜色 | Boolean | | false |
| lowThreshold | 低分和中等分数的界限值,值本身被划分在低分中 | Number | | 2 |
| highThreshold | 高分和中等分数的界限值,值本身被划分在高分中 | Number | | 4 |
| smiley | 是否使用 smiley icon | Boolean | | false |
| disabled | 是否为只读 | Boolean | | false |
| show-text | 是否显示辅助文字 | Boolean | | false |
| texts | 辅助文字数组 | Array | | ['极差', '失望', '一般', '满意', '惊喜'] |
| text-template | 只读时的辅助文字模板 | String | | '{value}' |
## Events
| 事件名称 | 说明 | 回调参数 |
|---------- |-------- |---------- |
| change | 分值改变时触发 | 改变后的分值 |

View File

@ -178,6 +178,11 @@
"name": "滑块 (slider)",
"title": "slider 滑块",
"description": "通过拖动滑块在一个固定区间内进行选择"
},
{
"path": "/rate",
"name": "评分 (rate)",
"title": "评分组件"
}
]
},

View File

@ -0,0 +1,31 @@
var cooking = require('cooking');
var path = require('path');
cooking.set({
entry: {
index: path.join(__dirname, 'index.js')
},
dist: path.join(__dirname, 'lib'),
template: false,
format: 'umd',
moduleName: 'ElRate',
extractCSS: 'style.css',
extends: ['vue', 'saladcss']
});
cooking.add('resolve.alias', {
'main': path.join(__dirname, '../../src'),
'packages': path.join(__dirname, '../../packages')
});
cooking.add('externals', {
vue: {
root: 'Vue',
commonjs: 'vue',
commonjs2: 'vue',
amd: 'vue'
}
});
module.exports = cooking.resolve();

BIN
packages/rate/fonts/icomoon.eot Executable file

Binary file not shown.

19
packages/rate/fonts/icomoon.svg Executable file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="icomoon" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe900;" glyph-name="rate-face-void" d="M0 448c0 282.766 229.234 512 512 512s512-229.234 512-512c0-282.766-229.234-512-512-512s-512 229.234-512 512zM947.2 448c0 240.351-194.849 435.2-435.2 435.2s-435.2-194.849-435.2-435.2c0-240.351 194.849-435.2 435.2-435.2s435.2 194.849 435.2 435.2zM294.4 588.853c0 28.247 22.726 51.147 51.2 51.147 28.277 0 51.2-22.664 51.2-51.147v-51.307c0-28.247-22.726-51.147-51.2-51.147-28.277 0-51.2 22.664-51.2 51.147v51.307zM627.2 588.853c0 28.247 22.726 51.147 51.2 51.147 28.277 0 51.2-22.664 51.2-51.147v-51.307c0-28.247-22.726-51.147-51.2-51.147-28.277 0-51.2 22.664-51.2 51.147v51.307zM361.143 281.6c-22.711 0-41.143-18.637-41.143-41.6s18.432-41.6 41.143-41.6h301.714c22.711 0 41.143 18.637 41.143 41.6s-18.432 41.6-41.143 41.6h-301.714z" />
<glyph unicode="&#xe901;" d="M512.001 960c-282.771 0-512.001-229.23-512.001-512.002 0-282.77 229.23-511.998 512.001-511.998 282.769 0 511.999 229.227 511.999 511.998s-229.23 512.002-511.999 512.002v0z" />
<glyph unicode="&#xe902;" d="M294.4 588.853c0 28.247 22.726 51.147 51.2 51.147 28.277 0 51.2-22.664 51.2-51.147v-51.307c0-28.247-22.726-51.147-51.2-51.147-28.277 0-51.2 22.664-51.2 51.147v51.307zM627.2 588.853c0 28.247 22.726 51.147 51.2 51.147 28.277 0 51.2-22.664 51.2-51.147v-51.307c0-28.247-22.726-51.147-51.2-51.147-28.277 0-51.2 22.664-51.2 51.147v51.307zM694.529 181.197l-3.422 1.216c-56.15 27.872-116.388 42.047-178.882 42.047-64.556 0-125.611-14.316-181.515-42.45l-3.382-1.132c-2.102-0.628-4.945-1.529-8.489-1.529-20.554 0-37.239 18.29-37.239 40.734 0 10.655 4.571 21.361 12.114 29.399l-0.456 2.483 9.516 4.698c66.74 33.104 139.336 50.537 209.907 50.537 71.889 0 142.336-16.984 210.314-50.948 11.943-7.181 19.405-20.953 19.405-35.903 0-26.328-21.71-47.958-47.871-39.153z" />
<glyph unicode="&#xe903;" d="M512-64c-282.766 0-512 229.234-512 512s229.234 512 512 512c282.766 0 512-229.234 512-512s-229.234-512-512-512v0z" />
<glyph unicode="&#xe904;" d="M294.4 588.853c0 28.247 22.726 51.147 51.2 51.147 28.277 0 51.2-22.664 51.2-51.147v-51.307c0-28.247-22.726-51.147-51.2-51.147-28.277 0-51.2 22.664-51.2 51.147v51.307zM627.2 588.853c0 28.247 22.726 51.147 51.2 51.147 28.277 0 51.2-22.664 51.2-51.147v-51.307c0-28.247-22.726-51.147-51.2-51.147-28.277 0-51.2 22.664-51.2 51.147v51.307zM361.143 281.6c-22.711 0-41.143-18.637-41.143-41.6s18.432-41.6 41.143-41.6h301.714c22.711 0 41.143 18.637 41.143 41.6s-18.432 41.6-41.143 41.6h-301.714z" />
<glyph unicode="&#xe905;" d="M512.001 960c-282.77 0-512.001-229.23-512.001-511.999s229.23-512.001 512.001-512.001c282.77 0 511.999 229.23 511.999 511.999s-229.229 512.001-511.999 512.001v0z" />
<glyph unicode="&#xe906;" d="M817.495 305.565c-0.445-1.485-0.963-2.939-1.569-4.35-0.676-1.572-1.455-3.089-2.317-4.556-55.631-107.613-169.518-181.459-301.323-181.459-0.096 0-0.19 0.002-0.286 0.002s-0.19-0.002-0.286-0.002c-131.804 0-245.693 73.845-301.323 181.459-0.862 1.467-1.641 2.984-2.317 4.556-0.606 1.41-1.124 2.865-1.569 4.35-1.103 3.68-1.705 7.569-1.705 11.597 0 6.566 1.579 12.771 4.372 18.282 6.897 13.601 21.239 22.955 37.822 22.955s30.927-9.355 37.823-22.955h0.676c41.411-81.453 127.131-137.544 226.507-137.652 99.375 0.108 185.095 56.2 226.507 137.652h0.676c6.897 13.601 21.239 22.955 37.823 22.955s30.927-9.355 37.822-22.955c2.794-5.511 4.372-11.715 4.372-18.282 0-4.029-0.602-7.918-1.705-11.597zM627.2 588.853c0 28.247 22.726 51.147 51.2 51.147 28.277 0 51.2-22.664 51.2-51.147v-51.307c0-28.247-22.726-51.147-51.2-51.147-28.277 0-51.2 22.664-51.2 51.147v51.307zM294.4 588.853c0 28.247 22.726 51.147 51.2 51.147 28.277 0 51.2-22.664 51.2-51.147v-51.307c0-28.247-22.726-51.147-51.2-51.147-28.277 0-51.2 22.664-51.2 51.147v51.307z" />
<glyph unicode="&#xe907;" glyph-name="rate-star-void" d="M779.518 29.414c10.587-6.217 18.901-9.345 23.926-9.961-0.519 0.064-4.025-0.689-8.174-3.745-4.111-3.028-5.83-6.069-5.909-6.499 0.928 5.022 0.452 13.902-2.267 25.831l-48.871 214.449c-11.327 49.703 8.583 109.981 46.99 143.349l167.879 145.854c9.047 7.86 14.515 14.575 16.618 18.988-0.298-0.625-0.709-4.339 0.932-9.381 1.625-4.994 4.071-7.682 4.562-7.95-4.432 2.418-12.992 4.717-25.18 5.835l-223.357 20.487c-50.107 4.596-101.469 41.879-121.596 88.102l-87.917 201.902c-4.865 11.172-9.736 18.558-13.464 22.030 0.263-0.245 3.332-1.609 8.231-1.609s7.966 1.364 8.228 1.608c-3.729-3.473-8.599-10.858-13.464-22.029l-87.917-201.902c-20.245-46.493-71.405-83.498-121.596-88.102l-223.357-20.487c-12.361-1.134-21.058-3.451-25.573-5.895 0.491 0.266 2.985 2.987 4.647 8.087 1.682 5.159 1.254 8.952 0.946 9.593 2.149-4.476 7.719-11.291 16.911-19.277l167.879-145.854c38.555-33.497 58.274-93.837 46.99-143.349l-48.871-214.449c-2.708-11.883-3.172-20.709-2.242-25.684-0.086 0.458-1.816 3.501-5.91 6.501-4.101 3.005-7.542 3.743-8.025 3.684 5.004 0.611 13.26 3.712 23.753 9.874l192.138 112.831c43.815 25.73 107.277 25.631 150.924 0l192.138-112.831zM465.263 93.189l-192.138-112.831c-68.347-40.136-109.472-10.003-91.85 67.322l48.871 214.449c6.589 28.911-6.009 67.933-28.834 87.764l-167.879 145.854c-59.718 51.883-44.364 99.791 35.183 107.088l223.357 20.487c29.367 2.694 62.617 26.566 74.634 54.163l87.917 201.902c31.697 72.793 83.086 72.801 114.787 0l87.917-201.902c11.853-27.22 45.236-51.466 74.634-54.163l223.357-20.487c79.149-7.26 94.51-55.544 35.183-107.088l-167.879-145.854c-22.513-19.56-35.514-58.452-28.834-87.764l48.871-214.449c17.62-77.317-23.159-107.66-91.85-67.322l-192.138 112.831c-25.767 15.131-67.185 15.341-93.309 0z" />
<glyph unicode="&#xe908;" glyph-name="rate-star" d="M558.572 93.189c-25.767 15.131-67.185 15.341-93.309 0l-192.138-112.831c-68.347-40.136-109.472-10.003-91.85 67.322l48.871 214.449c6.589 28.911-6.009 67.933-28.834 87.764l-167.879 145.854c-59.718 51.883-44.364 99.791 35.183 107.088l223.357 20.487c29.367 2.694 62.617 26.566 74.634 54.163l87.917 201.902c31.697 72.793 83.086 72.801 114.787 0l87.917-201.902c11.853-27.22 45.236-51.466 74.634-54.163l223.357-20.487c79.149-7.26 94.51-55.544 35.183-107.088l-167.879-145.854c-22.513-19.56-35.514-58.452-28.834-87.764l48.871-214.449c17.62-77.317-23.159-107.66-91.85-67.322l-192.138 112.831z" />
</font></defs></svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
packages/rate/fonts/icomoon.ttf Executable file

Binary file not shown.

BIN
packages/rate/fonts/icomoon.woff Executable file

Binary file not shown.

7
packages/rate/index.js Normal file
View File

@ -0,0 +1,7 @@
const Rate = require('./src/main');
Rate.install = function(Vue) {
Vue.component(Rate.name, Rate);
};
module.exports = Rate;

View File

@ -0,0 +1,15 @@
{
"name": "el-rate",
"version": "0.0.0",
"description": "A rate component for Vue.js.",
"keywords": [
"element",
"vue",
"component"
],
"main": "./lib/index.js",
"repository": "https://github.com/element-component/element/tree/master/packages/rate",
"author": "elemefe",
"license": "MIT",
"dependencies": {}
}

241
packages/rate/src/main.vue Normal file
View File

@ -0,0 +1,241 @@
<template>
<div class="el-rate">
<span
v-for="item in max"
class="el-rate__item"
@mouseenter="setCurrentValue(item)"
@mouseleave="resetCurrentValue"
@click="selectValue(item)"
:style="{ cursor: disabled ? 'auto' : 'pointer' }">
<i
:class="[classes[item - 1], {'hover': hoverIndex === item}]"
class="el-rate__icon"
:style="getIconStyle(item)">
<span class="path1" v-if="smiley && item <= currentValue"></span>
<span class="path2" v-if="smiley && item <= currentValue"></span>
<i
v-if="showDecimalIcon(item)"
:class="decimalIconClass"
:style="decimalStyle"
class="el-rate__decimal">
<span class="path1" v-if="smiley"></span>
<span class="path2" v-if="smiley"></span>
</i>
</i>
</span>
<span v-if="showText" class="el-rate__text" :style="textStyle">{{ text }}</span>
</div>
</template>
<script type="text/babel">
const CLASS_MAP = {
noSmiley: 'icon-rate-star',
noSmileyVoid: 'icon-rate-star-void',
smileyLow: 'icon-rate-face-gray',
smileyMedium: 'icon-rate-face-yellow',
smileyHigh: 'icon-rate-face-orange',
smileyVoid: 'icon-rate-face-void'
};
const COLOR_MAP = {
lowColor: '#99A9BF',
mediumColor: '#F7BA2A',
highColor: '#FF9900',
voidColor: '#C6D1DE',
disbaledVoidColor: '#EFF2F7'
};
import '../style.css';
export default {
name: 'el-rate',
data() {
return {
classes: null,
currentValue: 0,
colors: null,
hoverIndex: -1
};
},
props: {
value: {
type: Number,
default: 0
},
lowThreshold: {
type: Number,
default: 2
},
highThreshold: {
type: Number,
default: 4
},
max: {
type: Number,
default: 5
},
multiColor: {
type: Boolean,
default: false
},
smiley: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
showText: {
type: Boolean,
default: false
},
texts: {
type: Array,
default() {
return ['极差', '失望', '一般', '满意', '惊喜'];
}
},
textTemplate: {
type: String,
default: '{value}'
}
},
computed: {
text() {
let result = '';
if (this.disabled) {
result = this.textTemplate.replace('{value}', this.value);
} else {
result = this.texts[this.currentValue - 1];
}
return result;
},
textStyle() {
let color = '';
if (this.multiColor || this.smiley) {
color = this.getValueFromMap(this.currentValue, COLOR_MAP);
} else {
color = COLOR_MAP.mediumColor;
}
return { color };
},
decimalStyle() {
return {
color: this.smiley ? '' : this.activeColor,
width: this.valueDecimal + '%'
};
},
valueDecimal() {
return this.value * 100 - Math.floor(this.value) * 100;
},
decimalIconClass() {
let className = '';
if (!this.smiley) {
className = CLASS_MAP.noSmiley;
} else {
className = this.getValueFromMap(this.value, CLASS_MAP);
}
return className;
},
voidClass() {
const noSmileyVoidClass = this.disabled ? CLASS_MAP.noSmiley : CLASS_MAP.noSmileyVoid;
return this.smiley ? CLASS_MAP.smileyVoid : noSmileyVoidClass;
},
activeClass() {
let className = '';
if (this.smiley) {
className = this.getValueFromMap(this.currentValue, CLASS_MAP);
} else {
className = CLASS_MAP.noSmiley;
}
return className;
},
activeColor() {
let color = '';
if (!this.smiley) {
if (this.multiColor) {
color = this.getValueFromMap(this.currentValue, COLOR_MAP);
} else {
color = COLOR_MAP.mediumColor;
}
}
return color;
},
classes() {
let result = new Array(this.max);
result.fill(this.activeClass, 0, this.currentValue).fill(this.voidClass, this.currentValue, this.max);
return result;
}
},
watch: {
value(val) {
this.$emit('change', val);
this.currentValue = val;
}
},
methods: {
getValueFromMap(value, map) {
let result = '';
if (value <= this.lowThreshold) {
result = map.lowColor || map.smileyLow;
} else if (value >= this.highThreshold) {
result = map.highColor || map.smileyHigh;
} else {
result = map.mediumColor || map.smileyMedium;
}
return result;
},
showDecimalIcon(item) {
return this.disabled && this.valueDecimal > 0 && item - 1 < this.value && item > this.value;
},
getIconStyle(item) {
const voidColor = this.disabled ? COLOR_MAP.disbaledVoidColor : COLOR_MAP.voidColor;
const noSmileyColor = item <= this.currentValue ? this.activeColor : voidColor;
return {
color: this.smiley ? '' : noSmileyColor
};
},
selectValue(value) {
if (this.disabled) {
return;
}
this.currentValue = value;
this.$emit('input', value);
},
setCurrentValue(value) {
if (this.disabled) {
return;
}
this.currentValue = value;
this.hoverIndex = value;
},
resetCurrentValue() {
if (this.disabled) {
return;
}
this.currentValue = this.value;
this.hoverIndex = -1;
}
},
created() {
this.currentValue = this.value;
}
};
</script>

60
packages/rate/style.css Executable file
View File

@ -0,0 +1,60 @@
@font-face {
font-family: 'icomoon';
src: url('fonts/icomoon.eot?q2cz0t');
src: url('fonts/icomoon.eot?q2cz0t#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?q2cz0t') format('truetype'),
url('fonts/icomoon.woff?q2cz0t') format('woff'),
url('fonts/icomoon.svg?q2cz0t#icomoon') format('svg');
font-weight: normal;
font-style: normal;
}
[class^="icon-"], [class*=" icon-"] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icomoon' !important;
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-rate-face-void:before {
content: "\e900";
}
.icon-rate-face-gray .path1:before {
content: "\e901";
color: rgb(192, 204, 218);
}
.icon-rate-face-gray .path2:before {
content: "\e902";
color: rgb(132, 146, 166);
}
.icon-rate-face-yellow .path1:before {
content: "\e903";
color: rgb(247, 186, 42);
}
.icon-rate-face-yellow .path2:before {
content: "\e904";
color: rgb(172, 110, 2);
}
.icon-rate-face-orange .path1:before {
content: "\e905";
color: rgb(255, 153, 0);
}
.icon-rate-face-orange .path2:before {
content: "\e906";
color: rgb(173, 101, 0);
}
.icon-rate-star-void:before {
content: "\e907";
}
.icon-rate-star:before {
content: "\e908";
}

View File

@ -33,3 +33,4 @@
@import "./col.css";
@import "./spinner.css";
@import "./card.css";
@import "./rate.css";

View File

@ -0,0 +1,45 @@
@charset "UTF-8";
@import "./common/var.css";
@component-namespace el {
@b rate {
height: 20px;
@e item {
display: inline-block;
position: relative;
font-size: 0;
vertical-align: middle;
}
@e icon {
position: relative;
display: inline-block;
font-size: 18px;
margin-right: 6px;
color: #C6D1DE;
&.hover {
transform: scale(1.1);
}
.path2 {
position: absolute;
left: 0;
top: 0;
}
}
@e decimal {
position: absolute;
top: 0;
left: 0;
display: inline-block;
overflow: hidden;
}
@e text {
font-size: 14px;
vertical-align: middle;
}
}
}

View File

@ -48,6 +48,8 @@ import Upload from '../packages/upload/index.js';
import Progress from '../packages/progress/index.js';
import Spinner from '../packages/spinner/index.js';
import Message from '../packages/message/index.js';
import Card from '../packages/card/index.js';
import Rate from '../packages/rate/index.js';
const install = function(Vue) {
if (install.installed) return;
@ -99,6 +101,8 @@ const install = function(Vue) {
Vue.component(Progress.name, Progress);
Vue.component(Spinner.name, Spinner);
Vue.component(Message.name, Message);
Vue.component(Card.name, Card);
Vue.component(Rate.name, Rate);
Vue.use(Loading);
@ -166,5 +170,7 @@ module.exports = {
Upload,
Progress,
Spinner,
Message
Message,
Card,
Rate
};