You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vue中根据视口宽度调整显示的条目数量?

动态根据视口调整Vue列表显示条数的最优方案

方案一:计算属性 + window.matchMedia(Vue 2/3通用)

这种方式直接利用浏览器原生的媒体查询监听API,比手动监听resize事件更精准,代码简洁且无需自己处理宽度判断逻辑:

<template>
  <div>
    <!-- 直接使用计算后的列表 -->
    <div v-for="item in displayedItems" :key="item.id">{{ item.content }}</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [], // 你的数据源
      displayCount: 10,
      mediaQuery: null
    };
  },
  computed: {
    displayedItems() {
      // 统一通过displayCount控制截取数量
      return this.items.slice(0, this.displayCount);
    }
  },
  mounted() {
    // 定义移动端分界的媒体查询(可根据需求修改断点)
    this.mediaQuery = window.matchMedia('(max-width: 768px)');
    // 初始化显示数量
    this.displayCount = this.mediaQuery.matches ? 5 : 10;
    // 监听媒体查询变化
    this.mediaQuery.addEventListener('change', this.handleMediaChange);
  },
  beforeUnmount() {
    // 组件销毁前移除监听,避免内存泄漏
    this.mediaQuery?.removeEventListener('change', this.handleMediaChange);
  },
  methods: {
    handleMediaChange(e) {
      // 根据视口切换显示数量
      this.displayCount = e.matches ? 5 : 10;
    }
  }
};
</script>

方案二:Vue 3组合式API + 可复用组合函数(推荐)

如果使用Vue 3,把逻辑封装成组合式函数,可在多个组件中复用,扩展性更强:

第一步:封装组合式函数

// composables/useMediaDisplayCount.js
import { ref, onMounted, onUnmounted } from 'vue';

export function useMediaDisplayCount(
  breakpoint = '(max-width: 768px)',
  mobileCount = 5,
  desktopCount = 10
) {
  const displayCount = ref(desktopCount);

  const handleMediaChange = (e) => {
    displayCount.value = e.matches ? mobileCount : desktopCount;
  };

  onMounted(() => {
    const mediaQuery = window.matchMedia(breakpoint);
    displayCount.value = mediaQuery.matches ? mobileCount : desktopCount;
    mediaQuery.addEventListener('change', handleMediaChange);
    // 临时存储实例用于销毁
    window.__mediaQueryInstance__ = mediaQuery;
  });

  onUnmounted(() => {
    window.__mediaQueryInstance__?.removeEventListener('change', handleMediaChange);
    delete window.__mediaQueryInstance__;
  });

  return displayCount;
}

第二步:在组件中使用

<template>
  <div>
    <div v-for="item in displayedItems" :key="item.id">{{ item.content }}</div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';
import { useMediaDisplayCount } from '@/composables/useMediaDisplayCount';

const items = ref([]); // 你的数据源
// 调用组合函数,可自定义断点和显示数量
const displayCount = useMediaDisplayCount('(max-width: 768px)', 5, 10);

const displayedItems = computed(() => {
  return items.value.slice(0, displayCount.value);
});
</script>

为什么这些方案更好?

  • 避免了重复编写两个列表的冗余代码,所有逻辑统一通过displayCount变量控制
  • 原生matchMediaAPI比手动监听resize更高效,只会在视口跨越断点时触发回调,而非每次 resize 都执行
  • 组合式函数的方式支持多组件复用,后续修改断点或显示数量只需调整参数,扩展性拉满

内容的提问来源于stack exchange,提问作者hnrd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 18:55:23