Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在vuex存储中存储nuxtjs动态生成的路由_Javascript_Nuxt.js_Vuex_Ssg_Static Site Generation - Fatal编程技术网

Javascript 如何在vuex存储中存储nuxtjs动态生成的路由

Javascript 如何在vuex存储中存储nuxtjs动态生成的路由,javascript,nuxt.js,vuex,ssg,static-site-generation,Javascript,Nuxt.js,Vuex,Ssg,Static Site Generation,我正试图通过创建一个静态网站来利用nuxtjs SSG功能,其中页面内容和导航是从API获取的 我已经找到了如何通过定义一个模块来动态生成路由的方法,在这个模块中,我使用generate:beforehook获取页面内容和路由。创建路由时,我将页面内容存储为路由负载。下面的代码就是这样做的,并按预期工作 modules/dynamicRoutesGenerator.js const generator = function () { //Before hook to generate ou

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

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

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
hook,但我不知道如何从那里获取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()
操作。我陷入困境,不知道如何解决这个问题,也看不到其他解决方案


如果你能做到这一点,谢谢你的时间

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

其思想是将API请求数据存储在静态文件中。然后创建一个插件,使其具有一个公开API数据和一些函数的
$staticAPI
对象

我使用了
build:before
钩子,因为它在
generate:before
builder:extendedplugins
之前运行,这意味着在生成路由或插件时,我们已经存储了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")
  //...
}
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'
]
插件
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 helper:

//...
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 }
numxt.config.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")
  //...
}
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'
]