为什么捐赠
API 资源管理器
useRenderCache 组合式函数
Quasar v2.15+

当您处理 Vue 渲染函数(尽管不限于此)时,useRenderCache() 组合式函数特别有用。当您通过迭代构建节点时,此组合式函数可以帮助您内联代码,同时(出于性能原因)也受益于缓存。

在处理 SSR 时,在服务器端您不希望缓存任何内容,因为渲染只会针对每个客户端发生一次(并且您不希望您的内存占用量无谓地增加)。因此,useRenderCache 组合式函数实际上不会在服务器端使用任何缓存,而是使用每次调用时提供的默认值。

您可以直接缓存您想要的任何类型的值。一些例子

  • 您可以缓存一些监听器,以便 Vue 不需要在每次重新渲染时删除和重新附加它们。
  • 您可以缓存一些 Vue 渲染的节点,尽管在这种情况下您必须小心,因为它们的内容不应依赖于任何“反应式”内容(refs、计算属性等)。

语法

import { useRenderCache } from 'quasar'

setup () {
  const {
    getCache,
    setCache,
    hasCache,
    clearCache
  } = useRenderCache()

  // ...
}
function useRenderCache(): {
  getCache: <T = any>(key: string, defaultValue?: T | (() => T)) => T;
  setCache: <T = any>(key: string, value: T) => void;
  hasCache: (key: string) => boolean;
  clearCache: (key?: string) => void;
};

示例

下一个示例缓存了一些监听器,以避免 Vue 在每个渲染周期中删除和重新附加它们

import { h } from 'vue'
import { useRenderCache } from 'quasar'

export default {
  setup () {
    const { getCache } = useRenderCache()

    function getNode (i) {
      return h('div', {
        onClick: getCache(
          `click#${ i }`,
          () => { console.log(`clicked on node ${ i }`) }
        )
      })
    }

    function getContent () {
      const acc = []
      for (let i = 0; i < 10; i++) {
        acc.push(
          getNode(i)
        )
      }
      return acc
    }

    return () => {
      h('div', getContent)
    }
  }
}

以下示例缓存了一些值并调用第二个参数(它是函数)仅在缓存中尚不存在此键时生成默认值。这样,即使缓存已设置,我们也避免了不必要地运行该函数

const { getCache } = useRenderCache()

getCache('my-key', () => {
  // some computation which is only run
  // when the cache does NOT have "my-key" set
  return { some: 'object' }
})

要避免的陷阱

不要直接在 Vue h() 函数的第二个参数上缓存。这将干扰 Vue 的 DOM diff 算法。

// DON'T cache like this:
h(
  'div',
  getCache(`node#${ i }`, () => {
    return {
      onClick () => { console.log(`clicked on node ${ i }`) }
    }
  })
)

// ..rather, do it like this:
h(
  'div',
  { // new such object needs to be created on each
    // render, even if the content is cached
    ...getCache(`node#${ i }`, () => {
      return {
        onClick () => { console.log(`clicked on node ${ i }`) }
      }
    })
  }
})