news 2026/9/4 19:23:05

Vue3弹性布局(Flex)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue3弹性布局(Flex)

效果如下图:


在线预览

APIs

Flex

参数说明类型默认值
width弹性区域总宽度,单位pxstring | number‘auto’
verticalflex主轴的方向是否垂直,vertical使用flex-direction: columnbooleanfalse
wrap设置元素单行显示还是多行显示;参考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.vue

<script setup lang="ts">import{computed}from'vue'exportinterfaceProps{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'// 设置网格之间的间隙,数组时表示: [水平间距, 垂直间距]}constprops=withDefaults(defineProps<Props>(),{width:'auto',vertical:false,wrap:'nowrap',justify:'normal',align:'normal',gap:'middle'})constflexWidth=computed(()=>{if(typeofprops.width==='number'){return`${props.width}px`}returnprops.width})constgapValue=computed(()=>{if(props.gap===undefined){return0}if(typeofprops.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)){constgapMap={small:'8px',middle:'16px',large:'24px'}returngapMap[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>

在要使用的页面引入

其中引入使用了以下组件:

<script setup lang="ts">importFlexfrom'Flex.vue'import{ref}from'vue'constdirectionOptions=ref([{label:'horizontal',value:'horizontal'},{label:'vertical',value:'vertical'}])constdirection=ref('horizontal')constbaseStyle={width:'25%',height:'54px'}constjustifyOptions=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'}])constalignOptions=ref([{label:'flex-start',value:'flex-start'},{label:'center',value:'center'},{label:'flex-end',value:'flex-end'}])constjustify=ref(justifyOptions.value[0].value)constalignItems=ref(alignOptions.value[0].value)constboxStyle={width:'100%',height:'120px',borderRadius:'6px',border:'1px solid #40a9ff'}constgapOptions=ref([{label:'small',value:'small'},{label:'middle',value:'middle'},{label:'large',value:'large'},{label:'customize',value:'customize'}])constgapSize=ref('middle')constcustomGapSize=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>
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 19:40:58

JWT主要由哪几部分组成?

JWT&#xff0c;也就是JSON Web Token&#xff0c;这个“通行证”主要由三个部分组成。我们可以把它们想象成“通行证”的三个重要区域&#xff0c;每个区域都有它特殊的作用。头部&#xff08;Header&#xff09;:这部分就像“通行证”的封面&#xff0c;它告诉人们这个“通行…

作者头像 李华
网站建设 2026/9/4 0:18:42

Crawl4AI:3 步配好登录态、动态页面与结构化数据提取

Crawl4AI&#xff1a;3 步配好登录态、动态页面与结构化数据提取 【免费下载链接】crawl4ai &#x1f680;&#x1f916; Crawl4AI: Open-source LLM Friendly Web Crawler & Scraper. Dont be shy, join here: https://discord.gg/jP8KfhDhyN 项目地址: https://gitcode…

作者头像 李华
网站建设 2026/8/31 19:07:26

训练并发时的资源边界

训练并发时的资源边界本文围绕“并发上来后先守住哪条线”整理可复现的检查思路。所有阈值、配置和结果均应在隔离环境中记录输入、版本与资源条件后再解释&#xff1b;下文示例不对应真实组织、用户、流量或成本数据。 1. 用受控样例界定问题 2. DDP 与 FSDP 的通信背压&#…

作者头像 李华
网站建设 2026/9/2 11:01:10

JavaScript原型链完全指南:从prototype到继承底层原理

1. 先别背答案&#xff1a;原型链存在的理由&#xff0c;比链表本身更重要前端面试卷到一定阶段&#xff0c;"原型链"差不多是必考点。我面试过不少候选人&#xff0c;喊一句"你了解原型链吗"&#xff0c;对方立刻开始背&#xff1a;prototype是函数的属性…

作者头像 李华