前端Vue3项目响应式布局实战——基于Flex布局和媒体查询的响应式布局设计

06-01 1247阅读

效果演示

Desktop端

前端Vue3项目响应式布局实战——基于Flex布局和媒体查询的响应式布局设计

iPad/Mobile端

前端Vue3项目响应式布局实战——基于Flex布局和媒体查询的响应式布局设计

Flex布局

Flexbox 布局总结

1. Flex 容器属性:
  • display:定义为 flex 容器。
  • flex-direction:主轴方向(行或列)。
  • flex-wrap:控制换行行为。
  • justify-content:主轴对齐方式(左右或上下)。
  • align-items:交叉轴对齐方式(纵向对齐)。
  • align-content:多行对齐方式(仅当有换行时有效)。
    2. Flex 项目属性:
    • order:改变项目的顺序。
    • flex-grow:控制项目扩展。
    • flex-shrink:控制项目收缩。
    • flex-basis:定义项目的初始尺寸。
    • flex:flex-grow、flex-shrink 和 flex-basis 的简写。
    • align-self:单个项目的交叉轴对齐。

      Flex 布局属性总结

      Flexbox(弹性盒子布局)提供了一套强大的布局工具,既适用于复杂的网页布局,又能处理响应式设计。其主要属性可以分为两类:

      • Flex 容器属性(控制容器的布局行为)
      • Flex 项目属性(控制容器内子元素的布局行为)
        一、Flex 容器属性
        1. display

          • 定义容器的布局为 flexbox。
          • display: flex; 或 display: inline-flex;(容器行为类似块级或行内元素)
            .container {
              display: flex;
            }
            
          • flex-direction

            • 控制主轴(主方向)上项目的排列方向。
            • row(默认):水平,从左到右排列。
            • row-reverse:水平,从右到左排列。
            • column:垂直,从上到下排列。
            • column-reverse:垂直,从下到上排列。
              .container {
                flex-direction: row;
              }
              
            • flex-wrap

              • 控制项目是否换行。
              • nowrap(默认):不换行,所有项目都在一行内。
              • wrap:换行,项目会换行并在多行中排列。
              • wrap-reverse:换行,但换行方向与 wrap 相反。
                .container {
                  flex-wrap: wrap;
                }
                
              • justify-content

                • 在主轴方向上对齐项目,控制项目之间的间隔。
                • flex-start(默认):项目靠容器的起始端对齐。
                • flex-end:项目靠容器的末尾对齐。
                • center:项目在主轴上居中对齐。
                • space-between:项目间的间隔相等,第一个项目靠近容器起始端,最后一个项目靠近容器末尾端。
                • space-around:项目之间的间隔相等,容器两侧的空白间隔也相等。
                • space-evenly:所有项目之间的间隔相等,包括容器两侧的空白。
                  .container {
                    justify-content: center;
                  }
                  
                • align-items

                  • 在交叉轴(垂直于主轴)上对齐项目。
                  • flex-start:项目靠交叉轴起始端对齐。
                  • flex-end:项目靠交叉轴末尾端对齐。
                  • center:项目在交叉轴上居中对齐。
                  • baseline:项目按文本基线对齐。
                  • stretch(默认):项目拉伸以填充容器。
                    .container {
                      align-items: center;
                    }
                    
                  • align-content

                    • 控制多行(有换行时)在交叉轴上的对齐方式。
                    • flex-start:行靠交叉轴的起始位置对齐。
                    • flex-end:行靠交叉轴的末尾位置对齐。
                    • center:行在交叉轴上居中对齐。
                    • space-between:行间隔相等,第一个和最后一个行与容器边缘对齐。
                    • space-around:行间隔相等,行与容器之间也有间隔。
                    • stretch(默认):行拉伸以填充容器。
                      .container {
                        align-content: space-between;
                      }
                      

        二、Flex 项目属性
        1. order

          • 控制项目的排列顺序,数字越小,排列越靠前,默认为 0。
            .item {
              order: 1;
            }
            
          • flex-grow

            • 定义项目如何在主轴方向上扩展,以填充容器中剩余的空间。默认为 0,表示不扩展。
            • 如果所有项目的 flex-grow 值相同,空间会均等分配。
              .item {
                flex-grow: 1;
              }
              
            • flex-shrink

              • 定义项目如何在容器空间不足时缩小。默认为 1,表示项目会缩小。
              • 如果设置为 0,则项目不会缩小。
                .item {
                  flex-shrink: 0;
                }
                
              • flex-basis

                • 定义项目在分配剩余空间之前的初始大小。默认值为 auto,即根据项目的内容或宽度来决定。
                • 可以设置为具体的像素值、百分比等。
                  .item {
                    flex-basis: 200px;
                  }
                  
                • flex

                  • flex 是 flex-grow、flex-shrink 和 flex-basis 的简写。
                  • 常见的值:
                    • flex: 1 等价于 flex-grow: 1; flex-shrink: 1; flex-basis: 0%,让项目在可用空间中均等分配。
                    • 5:3:2分->flex值分别设为5、3、2
                    • flex: auto 等价于 flex-grow: 1; flex-shrink: 1; flex-basis: auto。
                    • flex: none 等价于 flex-grow: 0; flex-shrink: 0; flex-basis: auto,不允许扩展或收缩,保持初始大小。
                      .item {
                        flex: 1;
                      }
                      
                    • align-self

                      • 控制单个项目在交叉轴上的对齐方式,覆盖 align-items 设置。
                      • 可选值:auto、flex-start、flex-end、center、baseline、stretch。
                        .item {
                          align-self: center;
                        }
                        

        Flexbox 为响应式设计提供了非常强大的支持,尤其在复杂布局或动态调整时,能够通过这些属性轻松控制元素的排列、对齐和间距。

        媒体查询

        媒体查询详解

        媒体查询(Media Queries)是 CSS3 提供的一种功能,用于根据设备的特性(如屏幕大小、分辨率、方向等)应用不同的样式,从而实现响应式设计。

        媒体查询主要用于适配不同的设备,如桌面、平板、手机等。


        1. 基本语法

        媒体查询的基本语法如下:

        @media media-type and (media-feature: value) {
          /* CSS规则 */
        }
        
        • media-type:媒体类型,例如 screen、print。
        • media-feature:媒体特性,例如屏幕宽度、分辨率。
        • value:具体值,用于定义某个媒体特性的范围或条件。

          2. 媒体类型

          媒体查询支持以下媒体类型:

          媒体类型描述
          all默认值,适用于所有设备。
          screen针对屏幕设备,例如电脑、平板、手机等。
          print针对打印设备。
          speech针对屏幕阅读器等语音设备。

          示例:

          @media screen {
            body {
              background-color: lightblue;
            }
          }
          

          3. 常用媒体特性

          媒体特性用于检测设备的具体属性,以下是常用媒体特性及其说明:

          特性描述
          width视口(viewport)的宽度。
          height视口的高度。
          min-width视口的最小宽度。
          max-width视口的最大宽度。
          min-height视口的最小高度。
          max-height视口的最大高度。
          aspect-ratio视口的宽高比,例如 16/9。
          orientation设备方向:portrait(竖屏)或 landscape(横屏)。
          resolution屏幕分辨率,例如 300dpi 或 2dppx。
          prefers-color-scheme用户的首选颜色模式:light 或 dark。

          4. 媒体查询的逻辑运算符

          媒体查询支持以下逻辑运算符,允许结合多个条件:

          4.1 and
          • 用于同时满足多个条件。
            @media screen and (min-width: 768px) and (orientation: landscape) {
              body {
                background-color: lightgreen;
              }
            }
            
            4.2 not
            • 用于排除某些条件。
              @media not screen and (max-width: 768px) {
                body {
                  background-color: pink;
                }
              }
              
              4.3 ,(逗号,等价于“or”)
              • 用于满足任一条件即可生效。
                @media (max-width: 768px), (orientation: landscape) {
                  body {
                    font-size: 14px;
                  }
                }
                

                5. 媒体查询的使用方式

                5.1 在 CSS 文件中

                直接在 CSS 文件中使用 @media:

                @media (max-width: 768px) {
                  body {
                    background-color: lightyellow;
                  }
                }
                
                5.2 在 标签中

                在 HTML 文件的 标签中使用:

                  @media (max-width: 768px) {
                    body {
                      background-color: lightyellow;
                    }
                  }
                
                
                5.3 在 HTML 的 标签中

                通过 media 属性为外部 CSS 文件指定条件:

                 
                

                6. 响应式设计中的常用断点

                响应式设计中,为不同设备设置“断点”是常见做法。以下是常见设备的屏幕宽度断点:

                设备类型常用断点范围
                超小屏幕(手机)max-width: 576px
                小屏幕(平板)min-width: 577px 和 max-width: 768px
                中等屏幕(桌面)min-width: 769px 和 max-width: 992px
                大屏幕(大桌面)min-width: 993px 和 max-width: 1200px
                超大屏幕min-width: 1201px

                示例:

                /* 手机样式 */
                @media (max-width: 576px) {
                  body {
                    font-size: 14px;
                  }
                }
                /* 平板样式 */
                @media (min-width: 577px) and (max-width: 768px) {
                  body {
                    font-size: 16px;
                  }
                }
                /* 桌面样式 */
                @media (min-width: 769px) {
                  body {
                    font-size: 18px;
                  }
                }
                

                7. 媒体查询的最佳实践

                1. 优先考虑移动优先设计(Mobile First)

                  • 先为小屏幕(如手机)编写样式,再为更大的屏幕覆盖样式。
                  • 使用 min-width 编写媒体查询:
                    body {
                      font-size: 14px; /* 默认样式 */
                    }
                    @media (min-width: 768px) {
                      body {
                        font-size: 16px; /* 平板样式 */
                      }
                    }
                    @media (min-width: 992px) {
                      body {
                        font-size: 18px; /* 桌面样式 */
                      }
                    }
                    
                  • 保持断点清晰

                    • 确保不同断点之间没有冲突,避免重复规则。
                    • 避免过多的媒体查询

                      • 尽量保持规则简单,并利用 flexbox、grid 等现代布局方法减少依赖媒体查询的需求。
                      • 测试多设备

                        • 使用浏览器的开发者工具测试不同的屏幕尺寸和方向,确保样式正常工作。

                8. 示例:完整的响应式布局

                /* 默认样式(移动优先) */
                body {
                  font-size: 14px;
                  background-color: lightblue;
                }
                /* 平板设备 */
                @media (min-width: 768px) {
                  body {
                    font-size: 16px;
                    background-color: lightgreen;
                  }
                }
                /* 桌面设备 */
                @media (min-width: 992px) {
                  body {
                    font-size: 18px;
                    background-color: lightcoral;
                  }
                }
                

                9. 新特性:容器查询(Container Queries)

                容器查询是媒体查询的补充(CSS Container Queries),它允许根据容器的大小而不是视口大小来应用样式。虽然媒体查询以设备为基础,但容器查询更关注组件的自适应。

                目前,容器查询还在发展中,部分现代浏览器已经支持。

                实现

                Pinia全局状态管理

                管理当前设备类型(deviceType)、导航条是否需折叠(isCollapse)

                Pinia

                import { ref, computed } from 'vue'
                import { defineStore } from 'pinia'
                export const useDeviceStore=defineStore('device',{
                  state:()=>({
                      deviceType:"desktop" as deviceType, //初始默认值
                      isCollapse:false,
                    // deviceType:DeviceTypeEnum.Desktop,
                  }),
                  actions:{
                    toggleDevice(type:deviceType){
                      this.deviceType=type;
                    },
                    toggleCollapse(flag: boolean){
                      this.isCollapse=flag;
                    }
                  }
                })
                

                监测设备变化

                监测视口变化,改变全局状态(deviceType、isCollapse)

                Vue2中借助mixin
                import store from '@/store'
                const { body } = document
                const WIDTH = 992 // refer to Bootstrap's responsive design
                export default {
                  watch: {
                    $route(route) {
                      if (this.device === 'mobile' && this.sidebar.opened) {
                        store.dispatch('app/closeSideBar', { withoutAnimation: false })
                      }
                    }
                  },
                  beforeMount() {
                    window.addEventListener('resize', this.$_resizeHandler)
                  },
                  beforeDestroy() {
                    window.removeEventListener('resize', this.$_resizeHandler)
                  },
                  mounted() {
                    const isMobile = this.$_isMobile()
                    if (isMobile) {
                      store.dispatch('app/toggleDevice', 'mobile')
                      store.dispatch('app/closeSideBar', { withoutAnimation: true })
                    }
                  },
                  methods: {
                    // use $_ for mixins properties
                    // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
                    $_isMobile() {
                      const rect = body.getBoundingClientRect()
                      return rect.width - 1  
                
                  mixins: [ResizeMixin],
                
                Vue3中借助组合式API
                import { onMounted, onBeforeUnmount, watch } from 'vue';
                import { useDeviceStore } from '@/stores/layout';  // 引入 Pinia store
                const WIDTH = 768;
                // 参考 Bootstrap 的响应式设计
                //常见断点:576mobile\768iPad\992MidDesktop\1200LargeDeasktop\
                export function useDevice() {
                  const deviceStore = useDeviceStore();  // 使用 Pinia store
                  const body = document.body;
                  // 判断当前屏幕是否为移动端
                  const isMobile = () => {
                    const rect = body.getBoundingClientRect();
                    return rect.width - 1  {
                    if (!document.hidden) {
                      const isMobileDevice = isMobile();
                      deviceStore.toggleDevice(isMobileDevice ? 'mobile' : 'desktop');
                    }
                  };
                  // 在组件挂载时进行初始化
                  onMounted(() => {
                    if (isMobile()) {
                      deviceStore.toggleDevice('mobile');
                      deviceStore.toggleCollapse(true);
                    }
                    window.addEventListener('resize', resizeHandler); // 监听窗口大小变化
                  });
                  // 在组件销毁时移除事件监听
                  onBeforeUnmount(() => {
                    window.removeEventListener('resize', resizeHandler);
                  });
                  // 监听设备类型变化,移动设备时关闭侧边栏
                  watch(() => deviceStore.deviceType, (newDevice) => {
                    if (newDevice === 'mobile' && !deviceStore.isCollapse) {
                      deviceStore.toggleCollapse(true);
                    }else {
                      deviceStore.toggleCollapse(false);
                    }
                  });
                  return {
                    isMobile,  // 返回判断当前是否为移动设备的方法
                  };
                }
                
                import {useDevice} from '@/layout/mixin/ResizeHandler'
                useDevice();
                
                

                媒体查询

                不同设备下布局样式调整,调整导航条布局

                设备为中小设备时,导航条就折叠且放在最右侧

                ///* 响应式布局 */
                @media (min-width: 769px) {
                  .logo {
                    font-size: 24px;
                    font-weight: bold;
                    flex:5;
                  }
                  .nav{
                    background-color: transparent;
                    border-bottom: none;
                    flex: 3.5;
                  }
                  .info{
                    flex:1.5;
                    margin-left: 20px;
                    //background-color: white;
                  }
                }
                @media (max-width: 768px) {
                  .logo {
                    font-size: 24px;
                    font-weight: bold;
                    flex:5;
                    order:0//排序顺序,order属性
                  }
                  .nav{
                    background-color: transparent;
                    border-bottom: none;
                    flex:1;
                    //设备为中小设备时,导航条就折叠且放在最右侧!
                    order:2
                  }
                  .info{
                    flex:4;
                    margin-left: 20px;
                    order:1
                  }
                }
                

                导航条状态绑定

                导航条绑定全局状态(isCollapse)

                  
                  
                  
                import {useDeviceStore} from '@/stores/layout'
                import { watch } from 'vue'
                //根据当前窗口大小,判断是否折叠导航条
                const deviceStore=useDeviceStore();
                watch(()=>deviceStore.isCollapse,(newValue)=>{
                  console.log(newValue)
                })
                
                
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码