基础radio和禁用
亮点1:利用computed写一个get和set对象,根据这个对象来确定点击的是什么
亮点2:display:none掉选择框,用一个div造一个新的dom放上去样式
<script setup>
import { ref, reactive, computed, onMounted, onUnmounted, nextTick } from 'vue'
import { useProp, useNeumorphism } from '../mixin/neumorphism'
const radio = ref() // 与html中ref=""对应,定位dom元素
const emit = defineEmits(['change','update:modelValue'])
const handleChange = (evt) => { nextTick(() => { if(props.disabled) return; model.value = props.label; emit('change', model.value) }) }
const props = defineProps({
...useProp,
...{
modelValue: {
type: [String, Number],
default: ''
},
label: {
type: [String, Number],
default: ''
},
disabled: {
type: Boolean,
default: false
},
}
})
let model = computed({
get() {
return props.modelValue
},
set(val) {
emit('update:modelValue', val)
radio.value && (radio.value.checked = model.value === props.label)
}
})
const { baseStyleObject } = useNeumorphism(props)
let styleObject = computed(() => ({
}))
</script>
<template>
<div class="san-radio neumorphism" :class="[{'neumorphism-checked': model === label},{'is-disabled': disabled}]" @click="handleChange">
<input ref="radio" :value="label" type="radio" v-model="model"/>
<slot></slot>
<template v-if="!$slots.default">{{label}}</template>
</div>
</template>
<script>
export default {
name: 'sanorin-radio',
}
</script>
<style scoped>
@import "../../style/index.css";
@import "../../style/neumorphism.css";
input{
display: none;
}
.san-radio {
display: inline-block;
margin: 15px 0;
padding: 8px;
border-radius: 5px;
cursor: pointer;
user-select:none;
}
.san-radio + .san-radio{
margin-left: 10px;
}
</style>
接下来写el-radio-group,用provide、inject接收group里的值,带响应式状态
// radio-group
<script setup>
import { computed, provide } from 'vue'
const emit = defineEmits(['update:modelValue'])
const props = defineProps({
modelValue: {
type: [String, Number],
default: ''
}
})
let radioGroupModelValue = computed(() => props.modelValue)
let updateRadioGroupModelValue = (e) => emit('update:modelValue', e)
provide('radioGroupModelValue',{ radioGroupModelValue, updateRadioGroupModelValue })
</script>
<template>
<div class="san-radio-group" role="radiogroup">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'sanorin-radio-group',
}
</script>
<style scoped>
</style>
<script setup>
import { ref, inject, computed, nextTick } from 'vue'
import { useProp, useNeumorphism } from '../mixin/neumorphism'
const radio = ref() // 与html中ref=""对应,定位dom元素
const emit = defineEmits(['change','update:modelValue'])
const handleChange = (evt) => { nextTick(() => { if(props.disabled) return; model.value = props.label; emit('change', model.value) }) }
const props = defineProps({
...useProp,
...{
modelValue: {
type: [String, Number],
default: ''
},
label: {
type: [String, Number],
default: ''
},
disabled: {
type: Boolean,
default: false
},
}
})
const { radioGroupModelValue, updateRadioGroupModelValue } = inject('radioGroupModelValue') || {}
let model = computed({
get() {
return radioGroupModelValue ? radioGroupModelValue.value : props.modelValue
},
set(val) {
if (radioGroupModelValue) return updateRadioGroupModelValue(val)
emit('update:modelValue', val)
}
})
const { baseStyleObject } = useNeumorphism(props)
let styleObject = computed(() => ({
}))
</script>
<template>
<div class="san-radio neumorphism" :class="[{'neumorphism-checked': model == label},{'is-disabled': disabled}]" @click="handleChange">
<input ref="radio" :value="label" type="radio" v-model="model"/>
<slot></slot>
<template v-if="!$slots.default">{{label}}</template>
{{model == label}}
</div>
</template>
<script>
export default {
name: 'sanorin-radio',
}
</script>
<style scoped>
@import "../../style/index.css";
@import "../../style/neumorphism.css";
input{
display: none;
}
.san-radio {
display: inline-block;
margin: 15px 0;
padding: 8px;
border-radius: 5px;
cursor: pointer;
user-select:none;
}
.san-radio + .san-radio{
margin-left: 10px;
}
</style>