Nuxt开放链接到模式

我正在构建具有产品列表的Nuxt应用程序,然后单击其中一个打开产品的专用页面。一切正常。

结构是:

/pages/featured // directory of products
/pages/product/:id/:slug // Dedicated product page

现在,我想添加一个新功能:

  • 如果从非产品目录的页面中单击或人们直接登陆该产品,我希望保留该产品的专用页面;
  • 如果希望从目录中单击,我希望在目录顶部打开一个几乎全屏的产品对话框。
  • 在对话框上保留路由更改。

我希望实现的一个很好的例子是Youpic的照片目录

“产品”列表,在带有内部导航的对话框中完全可见。

我正在查看各种nuxt-routingvue-router文档以尝试进行开发,但距离解决方案还差得远。

我在这里看到的一小部分代码看起来与我所需的代码非常相似,但我不明白如何正确实现它以及如何创建nuxt自定义路由:

export default {
  router: {
    extendRoutes (routes, resolve) {
      routes.push({
        path: '/users/:id',
        components: {
          default: resolve(__dirname, 'pages/users'), // or routes[index].component
          modal: resolve(__dirname, 'components/modal.vue')
        },
        chunkNames: {
          modal: 'components/modal'
        }
      })
    }
  }
}
Pro伽罗2020/03/24 15:56:01

我对您的要求的理解是,查看https://youpic.com/explore是您要的https://www.example.com/featured (directory of products)路线,然后单击要打开的产品对话框,该对话框将全屏显示为https://www.example.com/product/:id/:slug (Details page)

如果我错了,请纠正我!

现在,您可以通过两种方式实现

1)点击每个产品(即https://www.example.com/featured (directory of products)路线),并使用nuxt-link重定向到https://www.example.com/product/:id/:slug (Details page)路线

2)在单击每个产品(即https://www.example.com/featured (directory of products)路线)后,手动使用来更新路线router.push并打开对话框

现在,如果我们看到https://youpic.com/explore,让我们以此为Nuxt代码结构将是pages/explore他们手动更新路由router.pushhttps://youpic.com/image/16660875/steffi-by-fs22photography但是当你共享/接受它URL(https://youpic.com/image/16660875/steffi-by-fs22photography)并尝试打开它,因此,如果您直接看到https://youpic.com/image/16660875/steffi-by-fs22photography,则Nuxt code structure必须保留pages/image/:id/:slug实际上将是一页的页面

希望对你有帮助!!

如果您有任何疑问,我们可以讨论更多!

ItachiGreen2020/03/24 15:56:01

在面对几乎相同的情况后,我最近实现了此功能。至少就我而言,我真的过分考虑了。

我所做的只是获取单个资源页面(在您的情况下为/ pages / product /:id /:slug),默认情况下将其设为模式页面。我正在使用vuetify,而v-dialog是模态。nuxt项目层次结构没有改变。相当于slug.vue页面。

<template>
<v-dialog v-model="drawer" fullscreen hide-overlay transition="dialog-bottom-transition">
    <v-card height="100vh">
        <div class="flex">
            <v-toolbar dark color="primary darken-2">
                <v-btn icon dark @click="close">
                    <v-icon>close</v-icon>
                </v-btn>
                <v-toolbar-title>{{member.alias}}</v-toolbar-title>
                <v-spacer></v-spacer>
                <v-toolbar-items>
                    <v-btn text nuxt :to="`/members/${member.id}/notes`">Notes</v-btn>
                    <v-btn text nuxt :to="`/members/${member.id}/edit`">Edit</v-btn>
                    <v-btn text nuxt :to="`/members/${member.id}/payments`">Payments</v-btn>

                </v-toolbar-items>
            </v-toolbar>
            <v-row no-gutters>
            </v-row>
        </div>
    </v-card>
</v-dialog>
</template>

<script>
import { mapGetters } from "vuex";
export default {
watchQuery: ["id"],
transition(to, from) {
    if (!from) {
        return "slide-left";
    }
    return +to.query.id < +from.query.id ? "slide-right" : "slide-left";
},
data() {
    return {
        id: this.$route.params.id,
        drawer: true
    };
},
fetch({ store, params }) {
    store.commit("members/active", params.id);
},
computed: {
    member: {
        get() {
            return this.$store.getters["members/active"];
        },
        set(member) {
            this.$store.commit("members/update", {
                id: member.id,
                member: member
            });
        }
    }
},
methods: {
    async close() {
        await this.$nuxt.$router.go(-1);
        this.drawer = false;
    }
}
};
小哥斯丁2020/03/24 15:56:01

我在这里为您构建了一个沙箱解决方案:https : //codesandbox.io/s/reverent-leftpad-xj81p

很抱歉,我不坚持确切的文件夹结构,但是此沙箱不允许我使用:其名称创建文件夹

解决方案说明:

该解决方案使用的beforeRouteLeave()功能vue-router默认情况下可用于您的nuxt页面:

beforeRouteLeave(to, from, next) {
  if (to.name === "product-id") {
    this.displayProductModal(to);
  } else {
    next();
  }
},

此功能会在特征页面上的任何路线更改发生之前中断它们,如果目标路线是产品详细信息的路线(这意味着有人单击了产品链接),则会改为打开模式对话框。

要处理打开和关闭模式时的url更改,请使用window.history对象:

displayProductModal(route) {
  this.activeModal = route.params.id
  window.history.pushState({}, null, route.path)
},
hideProductModal() {
  this.activeModal = null
  window.history.pushState({}, null, this.$route.path)
}

尝试玩一下,它应该与您提供的youpic示例完全一样。

注意:示例中没有使用真正的“模态”,为简单起见,整个示例尽可能基本。