為何捐款
API 瀏覽器
useRenderCache composable
Quasar v2.15+

useRenderCache() 組合式函式在處理 Vue 渲染函式時特別有用 (但不限於此)。當您透過迭代建構節點時,此組合式函式可以幫助您內聯程式碼,同時 (基於效能考量) 也受益於快取。

在處理 SSR 時,在伺服器端您不會想要快取任何東西,因為渲染只會針對每個客戶端發生一次 (而且您不希望記憶體佔用空間不必要地增加)。因此,useRenderCache 組合式函式實際上不會在伺服器端使用任何快取,而是使用每次呼叫時提供的預設值。

您可以直接快取您想要的任何類型的值。一些範例

  • 您可以快取一些監聽器,這樣 Vue 就不需要在每次重新渲染時移除並重新附加它們。
  • 您可以快取一些 Vue 渲染的節點,但在此情境中您必須小心,因為它們的內容不應依賴任何「響應式」內容 (refs、computed 等)。

語法

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)
    }
  }
}

以下範例快取了一些值,並呼叫第二個參數 (它是 Function) 以僅在快取尚未設定此鍵時產生預設值。這樣,即使已設定快取,我們也可以避免不必要地執行函式

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 差異演算法。

// 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 }`) }
      }
    })
  }
})