feature: commit radio-group component

This commit is contained in:
wang-xh 2022-10-02 16:12:18 +08:00
parent 285c9fd306
commit d91b0b909c
8 changed files with 234 additions and 1 deletions

11
.vscode/settings.json vendored
View File

@ -1,3 +1,12 @@
{ {
"editor.defaultFormatter": "esbenp.prettier-vscode" "editor.defaultFormatter": "esbenp.prettier-vscode",
"[typescript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"[typescriptreact]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"[vue]": {
"editor.defaultFormatter": "Wscats.vue"
}
} }

View File

@ -0,0 +1,12 @@
import type { App } from 'vue';
import RadioGroup from './src/radio-group.component';
export * from './src/radio-group.props';
export { RadioGroup };
export default {
install(app: App): void {
app.component(RadioGroup.name, RadioGroup);
}
};

View File

@ -0,0 +1,38 @@
import { ChangeRadio, Radio } from './types';
import { computed, Ref, SetupContext } from 'vue';
import { RadioGroupProps } from '../radio-group.props';
export function changeRadio(props: RadioGroupProps, context: SetupContext, modelValue: Ref<string>): ChangeRadio {
const canChangeRadioButton = computed(() => !props.disabled);
const enumData = computed(() => props.enumData || []);
function getValue(item: Radio): any {
return item[props.valueField];
};
function getText(item: Radio): any {
return item[props.textField];
};
function onClickRadio(item, $event: Event) {
if (canChangeRadioButton.value) {
const newValue = getValue(item);
if (modelValue.value !== item) {
modelValue.value = newValue;
context.emit('changeValue', newValue);
context.emit('update:modelValue', newValue);
}
}
$event.stopPropagation();
}
return {
enumData,
getValue,
getText,
onClickRadio
};
}

View File

@ -0,0 +1,32 @@
import { ComputedRef, Ref } from 'vue';
export interface Radio {
/**
*
*/
value: ComputedRef<any>;
/**
*
*/
name: ComputedRef<any>;
}
export interface ChangeRadio {
enumData: ComputedRef<Array<Radio>>;
/**
*
*/
getValue(item: Radio): any;
/**
*
*/
getText(item: Radio): any;
/**
*
*/
onClickRadio: (item: Radio, $event: Event) => void;
}

View File

@ -0,0 +1,56 @@
import { defineComponent, computed, ref } from 'vue';
import type { SetupContext } from 'vue';
import { radioGroupProps, RadioGroupProps } from './radio-group.props';
import { changeRadio } from './composition/change-radio';
export default defineComponent({
name: 'FRadioGroup',
props: radioGroupProps,
emits: [
'changeValue',
'update:modelValue',
],
setup(props: RadioGroupProps, context: SetupContext) {
const modelValue = ref(props.modelValue);
const { enumData, onClickRadio, getValue, getText } = changeRadio(props, context, modelValue);
const horizontalClass = computed(() => ({
'farris-checkradio-hor': props.horizontal
}));
return () => {
return (
<div class={['farris-input-wrap', horizontalClass.value]}>
{
enumData.value.map((item, index) => {
const id = 'radio_' + props.name + index;
return (
<div class="custom-control custom-radio" >
<input
type="radio"
class="custom-control-input"
name={props.name}
id={id}
value={getValue(item)}
checked={getValue(item) === modelValue.value}
disabled={props.disabled}
tabindex={props.tabIndex}
onClick={(event: MouseEvent) => onClickRadio(item, event)}
/>
<label class="custom-control-label" for={id}>
{ getText(item) }
</label>
</div>
);
})
}
</div>
);
};
},
});

View File

@ -0,0 +1,45 @@
import { ExtractPropTypes, PropType } from 'vue';
import { Radio } from './composition/types';
export const radioGroupProps = {
/**
*
*/
id: String,
/**
*
*/
name: { type: String, default: '' },
/**
*
*/
enumData: Array<Radio>,
/**
* key值
*/
textField: { type: String, default: 'name' },
/**
* key值
*/
valueField: { type: String, default: 'value' },
/**
*
*/
horizontal: { type: Boolean, default: false },
/**
*
*/
disabled: { type: Boolean, default: false },
/**
*
*/
modelValue: { type: String, default: '' },
/**
* Tab键索引
*/
tabIndex: Number,
};
export type RadioGroupProps = ExtractPropTypes<typeof radioGroupProps>;

View File

@ -7,6 +7,7 @@ import Avatar from './components/avatar.vue';
import ButtonEdit from './components/button-edit.vue'; import ButtonEdit from './components/button-edit.vue';
import FButton from '../components/button/src/button.component'; import FButton from '../components/button/src/button.component';
import Switch from './components/switch.vue'; import Switch from './components/switch.vue';
import RadioGroup from './components/radio-group.vue';
const canEdit = ref(true); const canEdit = ref(true);
const disable = ref(false); const disable = ref(false);
@ -34,6 +35,7 @@ const canAutoComplete = ref(false);
<label for="checkbox">disable:{{ disable }}</label> <label for="checkbox">disable:{{ disable }}</label>
<FButton :disable="disable"></FButton> <FButton :disable="disable"></FButton>
<Switch></Switch> <Switch></Switch>
<RadioGroup></RadioGroup>
</template> </template>
<style scoped> <style scoped>

View File

@ -0,0 +1,39 @@
<script setup lang="ts">
import { ref } from "vue";
import RadioGroup from "../../components/radio-group/src/radio-group.component";
const radioDisabled = ref(false);
const radioEnumData = ref([
{ value: "aa", name: "标签一" },
{ value: "bb", name: "标签二" },
{ value: "cc", name: "标签三" },
]);
const radioHorizontal = ref(false);
const value = ref("aa");
function testConsole(value) {
// console.log("change radio value to", value);
}
</script>
<template>
<p></p>
<label for="radio_disabled" class="mr-1">是否禁用单选组</label>
<input type="checkbox" id="radio_disabled" v-model="radioDisabled" />
<label for="radio_horizontaol" class="mr-1 ml-3">是否水平排列</label>
<input type="checkbox" id="radio_horizontaol" v-model="radioHorizontal" />
<br />
<RadioGroup
:disabled="radioDisabled"
:enum-data="radioEnumData"
:horizontal="radioHorizontal"
v-model="value"
@change-value="testConsole"
>
</RadioGroup>
<br />
当前选中值: {{ value }}
</template>