Nuxt3 - 如何创建一个单页作品集网站,其中帖子在 div 弹出窗口中打开(无需重新加载页面),但每个项目都有唯一的 url?

问题描述 投票:0回答:1

我正在使用 nuxt3、tailwindcss 和 Wordpress REST API 制作一个作品集网站。

作品集网站总体布局如下:

<body>
  <div id="page-wrapper">
    <section id="landing-image" class="w-screen h-screen">...</section>
    <section id="about">...</section>
    <section id="projects-grid">...</section>
  </div>
</body>

目标:

我希望网站感觉只有一页,但支持从项目网格中单击项目来阅读有关该项目的更多信息。单击项目时,内容应该加载,而无需(可见)重新加载页面。请参阅此作品集网站作为项目网格的示例,其中包含我尝试实现的项目弹出窗口:https://www.tessarosejacksoncomposer.com/

我尝试过的:

1.)我想到的一种方法是向包含被 tailwind 隐藏的帖子内容的页面添加一个 div,并且 nuxt 跟踪状态。当帖子需要查看或不查看并且加载正确的项目内容时,Nuxt 有条件地设置“隐藏”类。

app.vue

<template>
  <div id="page-wrapper">
    <section id="landing-image" class="w-screen h-screen">...</section>
    <section id="about">...</section>
    <section id="projects-grid">...</section>
  </div>
  <div id="project-content-wrapper" class="absolute h-screen w-screen" :class="{'hidden': postHidden }">
    ... (dynamically load project content and unhide by nuxt state management) ...
  </div>
</template>

这是一个很好且简单的实现,但我的主要问题是每个项目没有唯一的 url。当我想分享一个特定的项目时,我想发送一个立即打开该项目的网址。现在该网址始终保留在主页上。第二个问题是使用该网站时没有 url 历史记录,我认为这不直观。

2.)因此,我找到了第二种方法,使用嵌套的 nuxt 页面和

<NuxtPage />
组件(参考:https://v2.nuxt.com/examples/routing/nested-pages/ )。我的想法是将
<NuxtPage />
标签放在项目内容 div 中,然后有一个根据 url 进行更改的嵌套页面,但不会重新加载整个页面(明显)。在
pages/
目录中,我创建了一个
project/
目录、
project.vue
文件,并在
project/
目录中添加了一个
[...slug].vue
文件,其中包含项目布局并呈现内容。这样我的项目就有了 url
example.com/project/project-slug
project.vue
文件只是获得漂亮 url 的传递,并且仅包含带有
<NuxtPage />
的模板来嵌套项目子项。

app.vue

<template>
  <div id="page-wrapper">
    <section id="landing-image" class="w-screen h-screen">...</section>
    <section id="about">...</section>
    <section id="projects-grid">...</section>
  </div>
  <div id="project-content-wrapper" class="absolute h-screen w-screen" :class="{'hidden': postHidden }">
    <NuxtPage />
  </div>
</template>

第二种方法解决了url问题,但是页面明显重新加载并破坏了单页效果。这是因为页面可以滚动,当使用

<NuxtLink>
转到项目时,站点会滚动到顶部。当我添加一个跨 UI 元素来关闭项目弹出窗口并返回主页时,这成为一个问题。单击十字时,页面位于顶部,迫使用户再次向下滚动回到项目网格。我想要这样的错觉:弹出窗口在网站上打开,当单击十字时,用户会从上次中断的地方继续。

问题:

有谁知道一种方法来实现这个项目网格弹出效果,每个项目都有唯一的网址,同时保持留在同一个页面上的感觉?

nuxt.js single-page-application nuxtjs3 wordpress-rest-api dynamic-content
1个回答
0
投票

你可以尝试这样的事情(注意:你应该有一个根元素):

<template>
        <main>
        <div v-if="project_list">
        <div id="project-wrapper" v-for="item,index in project_list" :key="'project'+index" @click="handle(item)">
                    <section id="landing-image" class="w-screen h-screen">...</section>
                    <section id="about">...</section>
                    <section id="projects-grid">...</section>
                  </div>
        </div>
        
            
              <div id="project-content-wrapper" class="absolute h-screen w-screen" :class="{'hidden': postHidden }">
                ... (dynamically load project content and unhide by nuxt state management) ...
              </div>
        </main>
                
</template>
        
<script setup>
    import {ref,onMounted} from 'vue'
    
    const route = useRoute()    
    const postHidden = ref(true)
    const postContent = ref(null)
        const { data: project_list} = await useFetch('/path/to/myapi')//return an array of projects
    
    const handle = (item)=>{
    if(!window)return
    window.history.pushState(null,'',`?p=${item.slug}`)
    postHidden.value = false
    postContent.value = item
    }
    
    onMounted(()=>{
    if(route.query.p){
     const post = route.query.p
    const {data,error} = 
     postHidden.value = false
    project_list.forEach(item=>{
     if (item.slug == p) postContent.value = item
    
    }) 
    }
    })
    
</script>

这是一个粗略的实现,例如不支持错误。这个想法是使用“window.history.pushState”通过查询字符串修改 url,并在页面加载时使用此查询字符串(如果存在)

© www.soinside.com 2019 - 2024. All rights reserved.