You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Nuxt.js实现动态分页页面,自动加载Three.js场景组件

Got it, let's solve this dynamic pagination problem for your Three.js scenes in Nuxt.js! This approach will let you add new scene components anytime without having to manually update page structures—here's how to do it step by step:

1. First, organize your scene components

Start by moving all your SceneX.vue components into a dedicated directory, like components/scenes/. This makes it easy to auto-import them later:

components/
└── scenes/
    ├── Scene1.vue
    ├── Scene2.vue
    ├── Scene3.vue
    ├── Scene4.vue
    ├── Scene5.vue
    └── ... (add more scenes here anytime)

2. Create a dynamic pagination page template

Make a dynamic page at pages/scenes/_page.vue—this will handle loading the correct set of scenes for each page:

<template>
  <div class="scene-page">
    <main class="main">
      <!-- Render the current page's scenes -->
      <component 
        :is="scene.component" 
        v-for="(scene, index) in currentScenes" 
        :key="scene.name" 
      />
    </main>
    <!-- Pagination navigation -->
    <Pagination 
      :current-page="currentPage" 
      :total-pages="totalPages" 
    />
  </div>
</template>

<script>
import Pagination from '~/components/Pagination.vue'

// Auto-import all scene components from the scenes directory
const sceneImporter = require.context('~/components/scenes/', false, /Scene\d+\.vue$/)
const allScenes = sceneImporter.keys().map(filePath => {
  // Extract component name (e.g., "Scene1" from "./Scene1.vue")
  const componentName = filePath.match(/Scene(\d+)\.vue$/)[0].replace('.vue', '')
  return {
    name: componentName,
    component: sceneImporter(filePath).default
  }
})

const ITEMS_PER_PAGE = 4

export default {
  components: {
    Pagination,
    // Dynamically register all scene components
    ...allScenes.reduce((acc, scene) => {
      acc[scene.name] = scene.component
      return acc
    }, {})
  },
  async asyncData({ params }) {
    const currentPage = parseInt(params.page) || 1
    // Calculate which scenes belong to this page
    const startIndex = (currentPage - 1) * ITEMS_PER_PAGE
    const endIndex = startIndex + ITEMS_PER_PAGE
    const currentScenes = allScenes.slice(startIndex, endIndex)
    const totalPages = Math.ceil(allScenes.length / ITEMS_PER_PAGE)

    return {
      currentScenes,
      currentPage,
      totalPages
    }
  }
}
</script>

<style scoped>
.main {
  display: grid;
  grid-template-columns: 50% 50%;
  gap: 1rem;
  padding: 1rem;
}

.scene-page {
  max-width: 1200px;
  margin: 0 auto;
}
</style>

3. Build a reusable pagination component

Create components/Pagination.vue to let users navigate between pages:

<template>
  <div class="pagination">
    <button 
      :disabled="currentPage === 1"
      @click="$router.push(`/scenes/${currentPage - 1}`)"
      class="pagination-btn"
    >
      ← Previous
    </button>
    <span class="pagination-text">
      Page {{ currentPage }} / {{ totalPages }}
    </span>
    <button 
      :disabled="currentPage === totalPages"
      @click="$router.push(`/scenes/${currentPage + 1}`)"
      class="pagination-btn"
    >
      Next →
    </button>
  </div>
</template>

<script>
export default {
  props: {
    currentPage: {
      type: Number,
      required: true
    },
    totalPages: {
      type: Number,
      required: true
    }
  }
}
</script>

<style scoped>
.pagination {
  display: flex;
  gap: 1.5rem;
  justify-content: center;
  align-items: center;
  margin: 2rem 0;
}

.pagination-btn {
  padding: 0.6rem 1.2rem;
  border: none;
  border-radius: 4px;
  background: #2c3e50;
  color: white;
  cursor: pointer;
}

.pagination-btn:disabled {
  background: #bdc3c7;
  cursor: not-allowed;
}

.pagination-text {
  font-size: 1.1rem;
}
</style>

4. Configure Nuxt to pre-generate all pages (for static sites)

If you're deploying a static site, update nuxt.config.js to tell Nuxt to generate all pagination pages during build:

export default {
  // ... other configs
  generate: {
    async routes() {
      // Count total scenes to calculate how many pages we need
      const sceneImporter = require.context('./components/scenes/', false, /Scene\d+\.vue$/)
      const totalScenes = sceneImporter.keys().length
      const ITEMS_PER_PAGE = 4
      const totalPages = Math.ceil(totalScenes / ITEMS_PER_PAGE)

      // Generate routes for each page (e.g., /scenes/1, /scenes/2)
      return Array.from({ length: totalPages }, (_, index) => `/scenes/${index + 1}`)
    }
  }
}

How this works:

  • Auto-import: require.context scans your scenes/ directory and imports all matching components automatically—no more manual import statements.
  • Dynamic page logic: The _page.vue template calculates which scenes to show based on the URL parameter (e.g., /scenes/2 shows scenes 5-8).
  • Static generation: Nuxt pre-builds all pagination pages so your static site loads quickly without server-side processing.

To add a new scene:

Just drop a new SceneX.vue file into components/scenes/, then run nuxt dev or nuxt generate—the pagination will update automatically to include the new scene in the correct page.

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

火山引擎 最新活动