feature: commit radio-group component
This commit is contained in:
parent
285c9fd306
commit
d91b0b909c
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
};
|
|
@ -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
|
||||
};
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
|
@ -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>;
|
|
@ -7,6 +7,7 @@ import Avatar from './components/avatar.vue';
|
|||
import ButtonEdit from './components/button-edit.vue';
|
||||
import FButton from '../components/button/src/button.component';
|
||||
import Switch from './components/switch.vue';
|
||||
import RadioGroup from './components/radio-group.vue';
|
||||
|
||||
const canEdit = ref(true);
|
||||
const disable = ref(false);
|
||||
|
@ -34,6 +35,7 @@ const canAutoComplete = ref(false);
|
|||
<label for="checkbox">disable:{{ disable }}</label>
|
||||
<FButton :disable="disable"></FButton>
|
||||
<Switch></Switch>
|
||||
<RadioGroup></RadioGroup>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue