效果如下图:
APIs Flex 参数 说明 类型 默认值 width 弹性区域总宽度,单位px string | number ‘auto’ vertical flex主轴的方向是否垂直,vertical使用flex-direction: columnboolean false wrap 设置元素单行显示还是多行显示;参考flex-wrap ‘nowrap’ | ‘wrap’ | ‘wrap-reverse’ ‘nowrap’ justify 设置元素在主轴方向上的对齐方式;参考justify-content string ‘normal’ align 设置元素在交叉轴方向上的对齐方式;参考align-items string ‘normal’ gap 设置网格之间的间隙,数组时表示:[水平间距, 垂直间距] number | number[] | ‘small’ | ‘middle’ | ‘large’ ‘middle’
Slots 名称 说明 类型 default 自定义内容 v-slot:default
创建弹性布局组件Flex.vue < script setup lang= "ts" > import { computed} from 'vue' export interface Props { width? : string | number // 弹性区域总宽度,单位 px vertical? : boolean // flex 主轴的方向是否垂直,vertical 使用 flex-direction: column wrap? : 'nowrap' | 'wrap' | 'wrap-reverse' // 设置元素单行显示还是多行显示;参考 flex-wrap justify? : string // 设置元素在主轴方向上的对齐方式;参考 justify-content align? : string // 设置元素在交叉轴方向上的对齐方式;参考 align-items gap? : number | number [ ] | 'small' | 'middle' | 'large' // 设置网格之间的间隙,数组时表示: [水平间距, 垂直间距] } const props= withDefaults ( defineProps < Props> ( ) , { width: 'auto' , vertical: false , wrap: 'nowrap' , justify: 'normal' , align: 'normal' , gap: 'middle' } ) const flexWidth= computed ( ( ) => { if ( typeof props. width=== 'number' ) { return ` ${ props. width} px ` } return props. width} ) const gapValue= computed ( ( ) => { if ( props. gap=== undefined ) { return 0 } if ( typeof props. gap=== 'number' ) { 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) ) { const gapMap= { small: '8px' , middle: '16px' , large: '24px' } return gapMap[ props. gap] } } ) < / script> < template> < divclass = "flex-wrap" : class = "{ 'flex-vertical': vertical }" : style= "` width: ${ flexWidth} ; gap: ${ gapValue} ; margin-bottom: - ${ Array . isArray ( props. gap) && wrap? props. gap[ 1 ] : 0 } px; --wrap: ${ wrap} ; --justify: ${ justify} ; --align: ${ align} ; ` "> < slot> < / slot> < / div> < / template> < style lang= "less" scoped> . 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单选(Radio) Vue3按钮(Button) Vue3滑动输入条(Slider) < script setup lang= "ts" > import Flexfrom 'Flex.vue' import { ref} from 'vue' const directionOptions= ref ( [ { label: 'horizontal' , value: 'horizontal' } , { label: 'vertical' , value: 'vertical' } ] ) const direction= ref ( 'horizontal' ) const baseStyle= { width: '25%' , height: '54px' } const justifyOptions= ref ( [ { 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' } ] ) const alignOptions= ref ( [ { label: 'flex-start' , value: 'flex-start' } , { label: 'center' , value: 'center' } , { label: 'flex-end' , value: 'flex-end' } ] ) const justify= ref ( justifyOptions. value[ 0 ] . value) const alignItems= ref ( alignOptions. value[ 0 ] . value) const boxStyle= { width: '100%' , height: '120px' , borderRadius: '6px' , border: '1px solid #40a9ff' } const gapOptions= ref ( [ { label: 'small' , value: 'small' } , { label: 'middle' , value: 'middle' } , { label: 'large' , value: 'large' } , { label: 'customize' , value: 'customize' } ] ) const gapSize= ref ( 'middle' ) const customGapSize= ref ( 16 ) < / script> < template> < div> < h1> { { $route. name} } { { $route. meta. title} } < / h1> < h2class = "mt30 mb10" > 基本使用< / h2> < Flex vertical> < Radio: options= "directionOptions" v- model: value= "direction" / > < Flex: vertical= "direction === 'vertical'" > < div v- for = "n in 4" : key= "n" : style= "{ ...baseStyle, background: `${n % 2 ? '#1677ffbf' : '#1677ff'}` }" / > < / Flex> < / Flex> < h2class = "mt30 mb10" > 对齐方式< / h2> < Flex align= "start" vertical> < p> Select justify: < / p> < Radio v- model: value= "justify" button: options= "justifyOptions" / > < p> Select align: < / p> < Radio v- model: value= "alignItems" button: options= "alignOptions" / > < Flex: style= "{ ...boxStyle }" : justify= "justify" : align= "alignItems" > < Button type= "primary" > Primary< / Button> < Button type= "primary" > Primary< / Button> < Button type= "primary" > Primary< / Button> < Button type= "primary" > Primary< / Button> < / Flex> < / Flex> < h2class = "mt30 mb10" > 设置间隙< / h2> < Flex vertical> < Radio: options= "gapOptions" v- model: value= "gapSize" / > < Slider v- if = "gapSize === 'customize'" v- model: value= "customGapSize" / > < Flex: gap= "gapSize !== 'customize' ? gapSize : customGapSize" > < Button type= "primary" > Primary< / Button> < Button> Default< / Button> < Button type= "dashed" > Dashed< / Button> < Button type= "link" > Link< / Button> < / Flex> < / Flex> < h2class = "mt30 mb10" > 自动换行< / h2> < Flex wrap= "wrap" : width= "600" : gap= "[8, 16]" > < Button v- for = "n in 16" : key= "n" type= "primary" > Button< / Button> < / Flex> < / div> < / template>