)
效果如下图在线预览APIsFlex参数说明类型默认值width弹性区域总宽度单位pxstring | number‘auto’verticalflex主轴的方向是否垂直vertical使用flex-direction: columnbooleanfalsewrap设置元素单行显示还是多行显示参考flex-wrap‘nowrap’ | ‘wrap’ | ‘wrap-reverse’‘nowrap’justify设置元素在主轴方向上的对齐方式参考justify-contentstring‘normal’align设置元素在交叉轴方向上的对齐方式参考align-itemsstring‘normal’gap设置网格之间的间隙数组时表示:[水平间距, 垂直间距]number | number[] | ‘small’ | ‘middle’ | ‘large’‘middle’Slots名称说明类型default自定义内容v-slot:default创建弹性布局组件Flex.vuescript setup langtsimport{computed}fromvueexportinterfaceProps{width?:string|number// 弹性区域总宽度单位 pxvertical?:boolean// flex 主轴的方向是否垂直vertical 使用 flex-direction: columnwrap?:nowrap|wrap|wrap-reverse// 设置元素单行显示还是多行显示参考 flex-wrapjustify?:string// 设置元素在主轴方向上的对齐方式参考 justify-contentalign?:string// 设置元素在交叉轴方向上的对齐方式参考 align-itemsgap?:number|number[]|small|middle|large// 设置网格之间的间隙数组时表示: [水平间距, 垂直间距]}constpropswithDefaults(definePropsProps(),{width:auto,vertical:false,wrap:nowrap,justify:normal,align:normal,gap:middle})constflexWidthcomputed((){if(typeofprops.widthnumber){return${props.width}px}returnprops.width})constgapValuecomputed((){if(props.gapundefined){return0}if(typeofprops.gapnumber){return${props.gap}px}if(Array.isArray(props.gap)){return${props.gap[1]}px${props.gap[0]}px}if([small,middle,large].includes(props.gap)){constgapMap{small:8px,middle:16px,large:24px}returngapMap[props.gap]}})/scripttemplatedivclassflex-wrap:class{ flex-vertical: vertical }:stylewidth:${flexWidth}; gap:${gapValue}; margin-bottom: -${Array.isArray(props.gap)wrap?props.gap[1]:0}px; --wrap:${wrap}; --justify:${justify}; --align:${align};slot/slot/div/templatestyle langlessscoped.flex-wrap{display:flex;flex-wrap:var(--wrap);justify-content:var(--justify);align-items:var(--align);font-size:14px;color:rgba(0,0,0,0.88);transition:all0.3s;}.flex-vertical{flex-direction:column;}/style在要使用的页面引入其中引入使用了以下组件Vue3单选RadioVue3按钮ButtonVue3滑动输入条Sliderscript setup langtsimportFlexfromFlex.vueimport{ref}fromvueconstdirectionOptionsref([{label:horizontal,value:horizontal},{label:vertical,value:vertical}])constdirectionref(horizontal)constbaseStyle{width:25%,height:54px}constjustifyOptionsref([{label:flex-start,value:flex-start},{label:center,value:center},{label:flex-end,value:flex-end},{label:space-between,value:space-between},{label:space-around,value:space-around},{label:space-evenly,value:space-evenly}])constalignOptionsref([{label:flex-start,value:flex-start},{label:center,value:center},{label:flex-end,value:flex-end}])constjustifyref(justifyOptions.value[0].value)constalignItemsref(alignOptions.value[0].value)constboxStyle{width:100%,height:120px,borderRadius:6px,border:1px solid #40a9ff}constgapOptionsref([{label:small,value:small},{label:middle,value:middle},{label:large,value:large},{label:customize,value:customize}])constgapSizeref(middle)constcustomGapSizeref(16)/scripttemplatedivh1{{$route.name}}{{$route.meta.title}}/h1h2classmt30 mb10基本使用/h2Flex verticalRadio:optionsdirectionOptionsv-model:valuedirection/Flex:verticaldirection verticaldiv v-forn in 4:keyn:style{ ...baseStyle, background: ${n % 2 ? #1677ffbf : #1677ff} }//Flex/Flexh2classmt30 mb10对齐方式/h2Flex alignstartverticalpSelect justify:/pRadio v-model:valuejustifybutton:optionsjustifyOptions/pSelect align:/pRadio v-model:valuealignItemsbutton:optionsalignOptions/Flex:style{ ...boxStyle }:justifyjustify:alignalignItemsButton typeprimaryPrimary/ButtonButton typeprimaryPrimary/ButtonButton typeprimaryPrimary/ButtonButton typeprimaryPrimary/Button/Flex/Flexh2classmt30 mb10设置间隙/h2Flex verticalRadio:optionsgapOptionsv-model:valuegapSize/Slider v-ifgapSize customizev-model:valuecustomGapSize/Flex:gapgapSize ! customize ? gapSize : customGapSizeButton typeprimaryPrimary/ButtonButtonDefault/ButtonButton typedashedDashed/ButtonButton typelinkLink/Button/Flex/Flexh2classmt30 mb10自动换行/h2Flex wrapwrap:width600:gap[8, 16]Button v-forn in 16:keyntypeprimaryButton/Button/Flex/div/template