[微信小程序]自定义组件—星星评分
小程序项目中需要使用打分组件 因为只有这一个需求 所以没有引用UI组件 参考网上大神 记录一下自定义组件
需求需要组件既可以进行交互还要有纯展示禁止交互 所以参考element-ui组件
第一步在json中需要配置:
component 为 true 设为自定义组件
singComponent 作为引用组件的页面的json的声明配置项,值为引用的组件路径。
JSON
// An highlighted block
{
"component": true,
"usingComponent": {}
}
wxml中写组件的基本结构和需要绑定的属性,值和事件
starSize 定义组件显示的样式属性,通过properties来获取,默认值为normal 对应的还有small, large。这个对应相关的wxss来显示相应的效果
star 当前星级
gradable 当前组件是否交互(禁用)
grade 点击事件
通过点击事件来改变score值,而来改变image点亮状态。
WXML
// An highlighted block
<view class="star_wrapper star_wrapper_{{starSize}}">
<view wx:for="{{star}}" wx:key="{{item.id}}" data-index="{{item.id}}" data-gradable="{{gradable}}" bindtap="grade">
<image src="{{item.id > score ? defaultSrc : activeSrc}}"></image>
</view>
</view>
wxss样式不多说 没什么需要改动 因为是space-between 所以容器铺满时会比较难看 引用时可以限制容器宽度或者加padding
WXSS
// An highlighted block
view{box-sizing: border-box;}
/* 注意组件的宽度,默认横向撑开整个容器 */
.star_wrapper{
display: flex;
flex: row;
justify-content: space-between;
width: 100%;
height: auto;
}
.star_wrapper_normal image{
width: 38rpx;
height: 36rpx;
}
.star_wrapper_large image{
width: 52rpx;
height: 50rpx;
}
.star_wrapper_small image{
width: 30rpx;
height: 28rpx;
}
组件引用时
JS
// An highlighted block
Component({
properties: {
/**
* 组件大小
* small: 小
* normal: 正常
* large: 大
*/
starSize: {
type: String,
value: 'normal'
},
// 评分值
score: {
type: Number,
value: 0
},
// 同时使用多个组件,事件监听的方法名
starIdx: {
type: String,
value: 'I'
},
// 是否可评分
gradable: {
type: Boolean,
value: true
}
},
data: {
star: [
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
{ id: 5 }
],
defaultSrc: '../../assets/demand_star.png', //底图
activeSrc: '../../assets/demand_star_active.png' // 选中图
},
// 组件生命周期
lifetimes: {
attached() {
},
detached() {
}
},
// 兼容v2.2.3以下写法
attached() {
},
// 挂载页面的生命周期
pageLifetimes: {
},
methods: {
grade(e) {
// 如果只是展示分值,就屏蔽评分
// console.log(e.currentTarget.dataset.index)
if (!this.data.gradable) return;
this.setData({
score: e.currentTarget.dataset.index
}, () => {
const scoreDetail = {
score: e.currentTarget.dataset.index
};
let evenName = 'getscore' + this.data.starIdx;
this.triggerEvent(evenName, scoreDetail)
this.triggerEvent('setIndex', scoreDetail)
})
}
}
})