基于vue2项目,代码会全部在下面贴出,大家重点关注相关v-for循环实现及样式实现,先看效果:
先看单选
单选组件<easy-radio>:
<template>
<div>
<div class="radio-item" v-for="(option, index) in options" :key="index" @change="changeRadio">
<input
:id="`radio-${option.value}`"
type="radio"
:value="option.value"
v-model="easyValue"
>
<label :for="`radio-${option.value}`">{{ option.label }}</label>
</div>
</div>
</template>
<script>
export default {
name: 'RadioGroup',
data () {
return {
options: [
{
label: 'Very easy',
value: 1
}, {
label: 'Easy to find',
value: 2
}, {
label: 'Neutral',
value: 3
}, {
label: 'With a few difficulties',
value: 4
}, {
label: 'Very difficult',
value: 5
}
]
}
},
props: {
easyValue: {
type: ['String', 'Number'],
default: 0
}
},
methods: {
changeRadio (e) {
this.$emit('getEasyValue', this.easyValue)
}
}
}
</script>
<style lang="scss" scoped>
.radio-item {
display: flex;
align-items: center;
margin-bottom: 15px;
height: 20px;
input {
cursor: pointer;
visibility: hidden;
margin-right: 7px;
}
label {
margin-left: 10px;
cursor: pointer;
position: relative;
}
input+label {
&::before {
position: absolute;
top: 50%;
margin-top: -10px;
left: -30px;
content: '';
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
border-radius: 50%;
border: 1px solid #D7D7D7;
box-sizing: border-box;
}
}
input:checked+label {
&::before {
width: 12px;
height: 12px;
background: #dc2f2f!important;
border: 1px solid #dc2f2f;
background-clip: content-box!important;
box-sizing: content-box;
padding: 3px;
}
}
}
</style>
父组件使用单选组件:
<template>
<easy-radio :easyValue="findEasyValue" @getEasyValue="getFindEasyValue"></easy-radio>
</template>
<script>
import EasyRadio from '../components/easyRadio'
export default {
data () {
return {
findEasyValue: 0
}
},
components: {
EasyRadio
},
methods: {
getFindEasyValue (val) {
this.findEasyValue = val
}
}
}
</script>
多选组件
多选组件<improve-check> (业务场景创建的名字,这里偷懒就不单独起通用的名字)
<template>
<div>
<label class="checkbox-item" v-for="(option, index) in options" :key="index" @change="changeCheckbox">
<input
:id="`checkbox-${option.value}`"
type="checkbox"
:value="option.value"
v-model="improveValue"
>
<span>{{ option.label }}</span>
</label>
</div>
</template>
<script>
export default {
name: 'CheckboxGroup',
data () {
return {
options: [
{
label: 'Product Filters (prices, colours, sizes, etc.)',
value: 1
}, {
label: 'Using the menu to find a product category (e.g. chairs, mirrors, etc.)',
value: 2
}, {
label: 'Search engine results',
value: 3
}, {
label: 'Others',
value: 4
}
]
}
},
props: {
improveValue: {
type: Array,
default: []
}
},
methods: {
changeCheckbox (e) {
this.$emit('getImproveValue', this.improveValue)
}
}
}
</script>
<style lang="scss" scoped>
.checkbox-item {
display: flex;
align-items: center;
margin-bottom: 15px;
height: 20px;
input {
cursor: pointer;
visibility: hidden;
margin-right: 7px;
}
span {
margin-left: 10px;
position: relative;
cursor: pointer;
}
input+span {
&::before {
position: absolute;
top: 50%;
margin-top: -10px;
left: -30px;
content: '';
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
border: 1px solid #D7D7D7;
box-sizing: border-box;
}
}
input:checked+span {
&::before {
content: '√';
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
color: #fff;
font-weight: 600;
background: #dc2f2f!important;
border: 1px solid #dc2f2f;
}
}
}
</style>
父组件使用多选组件:
<template>
<improve-check :improveValue="improveValue" @getImproveValue="getImproveValue"></improve-check>
</template>
<script>
import ImproveCheck from '../components/improveCheck'
export default {
data () {
return {
improveValue: []
}
},
components: {
ImproveCheck
},
methods: {
getImproveValue (val) {
this.improveValue = val
// 选others的时候显示输入框填写原因
if (this.improveValue.includes(4)) {
this.showImproveReason = true
} else {
this.showImproveReason = false
}
}
}
}
</script>
大家重点关注的应该是dom结构和对应样式的实现,最后再放一个星星评分的效果也是纯手写,感兴趣的可以评论,有人需要的话后续我再更新,平时忙成狗,文章也是草草10分钟完成,希望可以帮助到大家!