【vue3组件封装】checkbox复选框与复选框组,radioGroup单选框

2023-08-30 08:08:45

源码:https://gitee.com/chenxiangzhi/components.git
历史文章:

  1. 封装含校验的Input

Checkbox

单个复选框

01 使用

<s-checkbox:checked="state.remember"name="remember"@update="updateForm"label="记住密码"/><scriptlang="ts"setup>import{ SCheckbox}from"@/components"// ...// 返回一个对象,包括name和value,value为布尔值constupdateForm=(param:BaseForm)=>{
  state[param.name]= param.value}</script>

02 Types

typeCheckboxProp={
	checked:boolean,// 值
	name:string,// 名称
	label:string}typeBaseForm={
   name:string;
   value:string|number|boolean;};

03 封装

<template><divclass="s-checkbox"><inputtype="checkbox"id="checkbox":checked="props.checked"@input="update"><labelfor="checkbox">{{ props.label }}</label></div></template><scriptlang="ts"setup>const emit=defineEmits(["update"])const props=defineProps({checked:{type: Boolean,default:false},name: String,label:{type: String,default:""}})constupdate=(e:Event)=>{const targetChecked=(e.targetas HTMLInputElement).checkedemit("update",{name: props.name,value: targetChecked})}</script>

Checkbox-Group

复选框组

01 使用

<template><s-checkbox-groupname="selectedKeys":value="state.selectedKeys":options="[{label:'1',value:1},{label:'2',value:2}]"@update="changeOptions"/></template><scriptlang="ts"setup>import{ SCheckboxGroup}from"@/components"import{ reactive}from"vue"const state=reactive({selectedKeys:[]})// 返回选中的value数组和选项数组constchangeOptions=(keys, options)=>{
  console.log(keys, options)}</script>

02 Types

// 单个选项typeCheckboxOption={
    label:string,// 显示的label
    value:string|number,// 对应的值
    key?:string, 
    checked?:boolean// 是否选中}// 组件属性typeCheckboxGroupProp={
    value:Array<string|number>,// 选中的值数组
    name:string,// 名称
    layout:"row"|"column",// 排列方向
    options:CheckboxOption[]// 可选列表}

03 封装

<template><div:class="['s-checkbox-group',{column:props.layout==='column'},{row:props.layout==='row'}]"><divclass="s-checkbox-group__option"v-for="item in state.options":key="item.key"><inputtype="checkbox":id="item.key":checked="item.checked"@input="(e)=>{update(e,item)}"><label:for="item.key">{{ item.label }}</label></div></div></template><scriptlang="ts"setup>import{ computed, PropType, reactive}from"vue"import{ CheckboxOption}from"@types"const emit=defineEmits(["update"])// 组件属性const props=defineProps({value:{type: Array,default:()=>[]},name: String,options:{type: Arrayas PropType<CheckboxOption[]>,default:()=>[]},layout:{type: String,default:"row"}})// 初始化选项:加入key属性和checked属性functioninitOptions(){return props.options.length? props.options.map(op=>{if(!op.key){
        op.key= op.value.toString()}if(props.value.length){
        op.checked=!!props.value.includes(op.value)}else{
        op.checked=false}return op}):[]}// 响应式状态const state=reactive({options:initOptions()})// 选中的选项const selectedOptions=computed(()=> state.options.filter(op=> op.checked))// 更新与传递constupdate=(e:Event,item:CheckboxOption)=>{const targetChecked=(e.targetas HTMLInputElement).checkedconst target= state.options.find(op=> op.key=== item.key)if(target){
    target.checked= targetCheckedemit("update", selectedOptions.value.map(op=> op.value), selectedOptions)}}</script><stylelang="less">.s-checkbox-group{&.row .s-checkbox-group__option{display: inline-block;margin-right:@itemSpace}
  &.column .s-checkbox-group__option{height:@listHeight;line-height:@listHeight;}}</style>

RadioGroup

单选框

01 使用

<template><s-radio-groupname="status":options="statusOptions"layout="column":value="state.status"@update="updateForm"/></template><scriptlang="ts"setup>import{ SRadioGroup}from"@/components"// ...const statusOptions=[{label:"启用",value:1},{label:"禁用",value:0}]constupdateForm=(params: BaseForm)=>{
    state[params.name]:Number(params.value)}</script>

02 Types

// 单个选项typeRadio={
   label:string;
   value:string|number;
   key?:string;};// 选项数组typeRadioOptions=Array<Radio>;// 属性typeRadioGroupProp={
	options:RadioOptions,// 选项数组
	value:string,// 选项值
	name:string,// 名称
	layout?:'row'|'column'// 排列方式}

03 封装

<template><div:class="['s-radio-group',{column:props.layout==='column'},{row:props.layout==='row'}]"><divclass="s-radio"v-for="item in props.options":key="item.value"@click="onChange"><inputtype="radio":id="item.value":value="item.value":checked="props.value === item.value"/><label:for="item.value":data-value="item.value">{{ item.label }}</label></div></div></template><scriptlang="ts"setup>import{ PropType}from"vue"import{ RadioOptions}from"@types"const props=defineProps({options: Arrayas PropType<RadioOptions>,value:[String, Number],name: String,layout:{type: String,default:"row"}})const emit=defineEmits(["update"])// 点击单选框或者label都可以触发constonChange=(e: Event)=>{const target=(e.targetas HTMLInputElement)if(target.tagName==="LABEL"){emit("update",{name: props.name,value: target.dataset.value})}elseif(target.tagName==="INPUT"){emit("update",{name: props.name,value: target.value})}}</script><stylelang="less"scoped>.column{display: flex;flex-direction: column;margin-bottom: 10px;}.row{display: flex;}.s-radio-group{.s-radio{input,label{cursor: pointer;}line-height:@listHeight;height:@listHeight;margin-right: 10px;white-space: nowrap;}}</style>
  • 作者:samhuamao
  • 原文链接:https://blog.csdn.net/aaaaapipi/article/details/127402265
    更新时间:2023-08-30 08:08:45