文章图片
文章图片
文章目录
-
- 一 需求明确
- 一 问题分析
- 二. 代码实现
- 三.调用
- 总结
- vue 小总结
- 参考文档
何时使用一 需求明确 实现一个star组件, 展示5个星,
对评价进行展示
支持 (全星, 半星, 空星),
支持 大小(24px, 36px, 48px)
一 问题分析 要展示5颗星,v-for
接口定义
属性 | 默认值 | 备注 |
---|---|---|
size | 48(备选项,48,36,24) | 星星的大小 (单位px) |
score | Number | 星星个数, 为3.6展示3星半 |
.star24_half
.star36_half
.star48_half
状态定义
.on 全星
.half 半星
.off 0星
二. 代码实现
v-for="(itemClass,index) in itemClasses" :class="itemClass" class="star-item" :key="index">
通过监听
starType
的样式, 控制星的大小 props: {
// 1.定义外部传递来的属性
size:{ // 尺寸
type:Number
},
score:{// 展示得分
type:Number
}},
starType() {
return 'star-' + this.size;
},
.star.star-item&.star-48&.star-36
&.star-24
-for="(itemClass, index) in itemClasses" :class="itemClass" class="star-item" :key="index">
="text/ecmascript-6">
const LENGTH = 5;
const CLS_ON = 'on';
const CLS_HALF = 'half';
const CLS_OFF = 'off';
export default {
props: {
// 1.定义外部传递来的属性
size: { // 尺寸
type: Number
},
score: {// 展示得分
type: Number
}},
data() {
return {
detailShow: false // 默认是不展示
}
},
computed: {
startType() {// 依赖于 size 属性
return 'star-' + this.size
},// 3. 利用计算属性,计算星星个数
itemClasses(){
let result = [] // 构造出 ['on','on','on','half', 'off']这样的数组
// Math.floor(3.6 *2) /2 =3.5
// Math.floor(4 *2) /2 =4
// 向下取0.5倍数
let score = Math.floor(this.score *2) /2
let hasDecimal = score % 1 !==0 // 是否有小数
let integer = Math.floor(score) // 是否有整数// 1. 构造全星
for (let i = 0;
i < integer;
i++) {
result.push(CLS_ON)
}// 2. 添加半星
if (hasDecimal) {
result.push(CLS_HALF)
}// 3. 补齐空星
while(result.length < LENGTH){
result.push(CLS_OFF)
}return result
}
}
};
="less" scoped>
// mixin 混入
// @import "../../common/stylus/mixins.less";
.bg-image-base(@url: '') {
@2xImgUrl: "@2x.png";
// call mixin .c-icon();
background-image: url("@{url}@{2xImgUrl}");
};
@media (-webkit-min-device-pixel-ratio: 2),
(min-device-pixel-ratio: 2) {
.bg-image-base(@url: '') {
@3xImgUrl: "@3x.png";
// call mixin .c-icon();
background-image: url("@{url}@{3xImgUrl}");
}
}// .bg-image('star24_half','')// .on 全星
// .half 半星
// .off 0星// 2. 定义css样式
.star {
font-size: 0;
.star-item {
// 横向排布
display: inline-block;
background-repeat: no-repeat;
}&.star-48 {.star-item {
width: 20px;
height: 20px;
margin-right: 22px;
background-size: 20px 20px;
// 设置最后一个元素没有 右侧间距
&:last-child {
margin-right: 0;
}&.on {
.bg-image-base('star48_on')
}&.half {
.bg-image-base('star48_half')
}&.off {
.bg-image-base('star48_off')
}
}
}&.star-36 {.star-item {
width: 15px;
height: 15px;
margin-right: 6px;
background-size: 15px 15px;
// 设置最后一个元素没有 右侧间距
&:last-child {
margin-right: 0;
}&.on {
.bg-image-base('star36_on')
}&.half {
.bg-image-base('star36_half')
}&.off {
.bg-image-base('star36_off')
}
}
} &.star-24 {.star-item {
width: 10px;
height: 10px;
margin-right: 3px;
background-size: 10px 10px;
// 设置最后一个元素没有 右侧间距
&:last-child {
margin-right: 0;
}&.on {
.bg-image-base('star24_on')
}&.half {
.bg-image-base('star24_half')
}&.off {
.bg-image-base('star24_off')
}
}
}}
三.调用
- 注册组件
export default {
...
props: {},components: {
'v-star': Star
},data() {
return {}
},
created() {// 转换为对应的样式},methods: {
}}
- 引用组件
总结 这里的核心思路在于, 通过运用计算属性computed,
- 利用父级传来的score, 计算出 列表 itemClasses, 补足星数
- 利用父级传来的size, 同步 startType(), 方法, 与 ‘star-’(star-48, star-36, star-24), 样式属性进行配合, 决定了星星的大小
- 使用mixins, 方法, 简化了代码编写的思路
:
)绑定属性值,ps: 否则, 将被解析为
string
字符串,如下:
参考文档 https://ant.design/components/rate-cn/
https://element.eleme.cn/#/zh-CN/component/rate
https://github.com/ElemeFE/element/blob/dev/packages/rate/src/main.vue
推荐阅读
- python|12 个要收藏的前端 CSS 网站
- html|前端打印设置相关
- HTML+CSS|【HTML+CSS+JS】前端三剑客实现3D旋转照片墙
- 前端|【HTML+CSS+JS】注册页面模板
- CSS样式|CSS效果集合
- 纯css3实现下拉箭头、关闭按钮旋转效果
- javascript|客观评价 增长趋势比 vite 还猛的 TailwindCSS
- html|Vue项目实战
- 前端|【前端面试必知】行内块元素之间的空白间隔是什么原因引起的