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 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>
|
||||||
|
|
|
@ -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