Vue 组件使用 Redis 进行缓存 - 无法将组件解析为字符串

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

我正在尝试让组件缓存在 Vue 2(使用 Nuxt 2)中工作。

现在我们有来自 nuxt-multi-cache 的典型 LRU 实现,但我们想过渡到使用 Redis(这样它就在 Pod 之外,我们可以轻松地使其失效)。我已经准备好基本设置,组件保存在 Redis 中并由 Vue 读取。但是在解析Redis返回的数据的时候就崩溃了。

vue-server-renderer
中有一段接收Redis输出的代码:

// node_modules/vue-server-renderer/build.dev.js:8399:26
get(key, function (res) {
  console.log({vsr_res_components: res?.components});
  if (isDef(res)) {
    if (isDef(registerComponent)) {
      registerComponent(userContext);
    }
    res.components.forEach(function (register) { return register(userContext); });
    write(res.html, next);
  } else {
    renderComponentWithCache(node, isRoot, key, context);
  }
});

它正在突破这条线:

res.components.forEach(function (register) { return register(userContext); });

这么说

res.components.forEach is not a function

所以我的实现看起来像这样。

cache: {
  get: (key, cb) => {
    redisClient.get(key, (err, res) => {
      console.log(res)
      cb(res)
    })
  },
  set: (key, val) => {
    console.log(val)
    redisClient.set(key, val)
  }
}

遵循 Vue 文档中的类型声明:

type RenderCache = {
  get: (key: string, cb?: Function) => string | void;
  set: (key: string, val: string) => void;
  has?: (key: string, cb?: Function) => boolean | void;
};

经过一番调查,我发现问题是在我们将数据保存到 Redis 时发生的。它解析它并删除部分数据。 我控制台我们在

set
方法中获得的记录数据(我们从 Vue 获得的渲染组件应该进入缓存以供将来使用)。 我得到了这个:

{
    html: '<some loong rendered html>',
    components: Set(8) {
        [Function: hook],
        [Function: hook],
        [Function: hook],
        [Function: hook],
        [Function: hook],
        [Function: hook],
        [Function: hook],
        [Function: hook]
    }
}

因此,Vue 似乎破坏了自己的类型声明,我们得到的不是简单的字符串,而是一些带有组件的奇怪对象,其中包含带有函数的 Set。

显然这不能解析为字符串,所以 Redis 客户端只是将其删除:

{
    html: '<some loong rendered html>',
    components: {}
}

但现在的问题是——我该如何克服这个问题?我找不到将它们保存到 Redis 中的方法,但应该有一种方法可以使用 Redis 实现组件缓存。甚至 Vue 文档也说这应该是可能的: https://v2.ssr.vuejs.org/api/#cache。 但有关它的文档和资源确实很少。尤其是这个 Vue 版本即将结束生命。

请发送帮助

vue.js caching vuejs2 redis nuxt.js
1个回答
0
投票

只需将

component
属性设置为对我有用的数组:

cache: {
  set: (key, val) => {
    val.components = [];
    redisClient.set(key, JSON.stringify(val))
  }
}

我认为发生这种情况是因为 JSON.stringify 将

Set
转换为对象而不是数组:

const componentMock = {
    html: "<html>...</html>",
  components: new Set([function foo() {}, function bar() {}])
}

console.log("Wrong, as object", JSON.parse(JSON.stringify(componentMock)));
console.log("Correct, as array", JSON.parse(JSON.stringify({...componentMock, components: []})));

还有一些方法可以指定 JSON.stringify 应如何以更通用的方式处理编码规则这里

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