【问题标题】:How to store nuxtjs dynamically generated routes in vuex store如何在 vuex 商店中存储 nuxtjs 动态生成的路由
【发布时间】:2021-03-30 01:08:50
【问题描述】:

我正在尝试通过创建一个静态网站来利用 nuxtjs SSG 功能,其中页面内容和导航是从 API 获取的。

我已经找到了如何通过定义一个模块来动态生成路由的方法,在该模块中我使用generate:before 挂钩来获取页面内容和路由。创建路由时,我将页面内容存储为路由有效负载。下面的代码就是这样做的,并按预期工作。

modules/dynamicRoutesGenerator.js

const generator = function () {
  //Before hook to generate our custom routes
  this.nuxt.hook('generate:before', async (generator, generatorOptions) => {
    generator.generateRoutes(await generateDynamicRoutes())
  })
}

let generateDynamicRoutes = async function() {
  //...
  return routes
}

export default generator

现在我面临的问题是我有一些导航组件需要生成的路线,我正在考虑将它们存储到 vuex 存储中。

我尝试了generate:done 钩子,但我不知道如何从那里获取 vuex 存储上下文。我最终使用的是 nuxtServerInit() 操作,因为如文档中所述:

If nuxt generate is ran, nuxtServerInit will be executed for every dynamic route generated.

这正是我需要的,所以我尝试将它与以下代码一起使用:

store/index.js

export const actions = {
  nuxtServerInit (context, nuxtContext) {
    context.commit("dynamicRoutes/addRoute", nuxtContext)
  }
}

store/dynamicRoutes.js

export const state = () => ({
  navMenuNivel0: {}
})

export const mutations = {
  addRoute (state, { ssrContext }) {
    //Ignore static generated routes
    if (!ssrContext.payload || !ssrContext.payload.entrada) return
    //If we match this condition then it's a nivel0 route
    if (!ssrContext.payload.navMenuNivel0) {
      console.log(JSON.stringify(state.navMenuNivel0, null, 2));
      //Store nivel0 route, we could use url only but only _id is guaranteed to be unique
      state.navMenuNivel0[ssrContext.payload._id] =  {
        url: ssrContext.url,
        entrada: ssrContext.payload.entrada,
        navMenuNivel1: []
      }
      console.log(JSON.stringify(state.navMenuNivel0, null, 2));
      //Nivel1 route
    } else { 
      //...
    }
  }
}

export const getters = {
  navMenuNivel0: state => state.navMenuNivel0
}

确实调用了该操作,并且我得到了所有预期值,但是似乎每次调用nuxtServerInit() 都会重置存储状态。我在控制台中打印了这些值(因为我不确定是否可以调试它),这就是它们的样子:

{}                                                                                                                                                                                                                     
{                                                                                                                                                                                                                      
  "5fc2f4f15a691a0fe8d6d7e5": {
    "url": "/A",
    "entrada": "A",
    "navMenuNivel1": []
  }
}
{}                                                                                                                                                                                                                     
{                                                                                                                                                                                                                     
  "5fc2f5115a691a0fe8d6d7e6": {
    "url": "/B",
    "entrada": "B",
    "navMenuNivel1": []
  }
}

我已经在这个主题上搜索了所有我能找到的东西,虽然我没有找到与我类似的例子,但我把所有我能找到的部分放在一起,这就是我想出的。

我的想法是只向 API 发出一个请求(在构建期间),将所有内容存储在 vuex 中,然后在组件和页面中使用该数据。

要么有更好的方法,要么我没有完全掌握nuxtServerInit() 操作。我被卡住了,不知道如何解决这个问题,也看不到其他解决方案。

如果您能做到这一点,感谢您的宝贵时间!

【问题讨论】:

    标签: javascript nuxt.js vuex ssg static-site-generation


    【解决方案1】:

    我想出了一个解决方案,但我觉得它不是很优雅。

    这个想法是将 API 请求数据存储在静态文件中。然后创建一个插件来拥有一个$staticAPI 对象,该对象公开 API 数据和一些函数。

    我使用了build:before 钩子,因为它在generate:beforebuilder:extendPlugins 之前运行,这意味着当路由生成或插件创建发生时,我们已经存储了API 数据。

    dynamicRoutesGenerator.js

    const generator = function () {
      //Add hook before build to create our static API files
      this.nuxt.hook('build:before', async (plugins) => {
        //Fetch the routes and pages from API
        let navMenuRoutes = await APIService.fetchQuery(QueryService.navMenuRoutesQuery())
        let pages = await APIService.fetchQuery(QueryService.paginasQuery())
        //Cache the queries results into staticAPI file
        APIService.saveStaticAPIData("navMenuRoutes", navMenuRoutes)
        APIService.saveStaticAPIData("pages", pages)
      })
      
      //Before hook to generate our custom routes
      this.nuxt.hook('generate:before', async (generator, generatorOptions) => {
        console.log('generate:before')
        generator.generateRoutes(await generateDynamicRoutes())
      })
    }
    
    //Here I can't find a way to access via $staticAPI
    let generateDynamicRoutes = async function() {
      let navMenuRoutes = APIService.getStaticAPIData("navMenuRoutes")
      //...
    }
    

    插件staticAPI.js:

    import APIService from '../services/APIService'
    
    let fetchPage = function(fetchUrl) {  
      return this.pages.find(p => { return p.url === fetchUrl})
    }
    
    export default async (context, inject) => {
      //Get routes and files from the files
      let navMenuRoutes = APIService.getStaticAPIData("navMenuRoutes")
      let pages = APIService.getStaticAPIData("pages")
      //Put the objects and functions in the $staticAPI property
      inject ('staticAPI', { navMenuRoutes, pages, fetchPage })
    }
    

    将数据保存/加载到文件的 APIService 助手:

    //...
    let fs = require('fs');
    
    let saveStaticAPIData = function (fileName = 'test', fileContent = '{}') {
      fs.writeFileSync("./static-api-data/" + fileName + ".json", JSON.stringify(fileContent, null, 2));
    }
    
    let getStaticAPIData = function (fileName = '{}') {
      let staticData = {};
    
      try {
          staticData = require("../static-api-data/" + fileName + ".json");
      } catch (ex) {}
    
      return staticData;
    }
    
    module.exports = { fetchQuery, apiUrl, saveStaticAPIData, getStaticAPIData }
    

    nuxt.config.js

    build: {
      //Enable 'fs' module
      extend (config, { isDev, isClient }) {
         config.node = { fs: 'empty' }
      }
    },
    plugins: [
      { src: '~/plugins/staticAPI.js', mode: 'server' }
    ],
    buildModules: [
      '@nuxtjs/style-resources',
      '@/modules/staticAPIGenerator',
      '@/modules/dynamicRoutesGenerator'
    ]
    

    【讨论】:

      猜你喜欢
      • 2019-04-28
      • 2021-06-03
      • 1970-01-01
      • 2020-09-10
      • 1970-01-01
      • 1970-01-01
      • 2020-07-05
      • 1970-01-01
      • 2020-06-05
      相关资源
      最近更新 更多