40 v-once的使用场景有哪些

分析

v-onceVue中内置指令,很有用的API,在优化方面经常会用到

体验

仅渲染元素和组件一次,并且跳过未来更新

    <!-- single element -->
    <span v-once>This will never change: {{msg}}</span>
    <!-- the element have children -->
    <div v-once>
      <h1>comment</h1>
      <p>{{msg}}</p>
    </div>
    <!-- component -->
    <my-component v-once :comment="msg"></my-component>
    <!-- `v-for` directive -->
    <ul>
      <li v-for="i in list" v-once>{{i}}</li>
    </ul>

回答范例

  • v-oncevue的内置指令,作用是仅渲染指定组件或元素一次,并跳过未来对其更新
  • 如果我们有一些元素或者组件在初始化渲染之后不再需要变化,这种情况下适合使用v-once,这样哪怕这些数据变化,vue也会跳过更新,是一种代码优化手段
  • 我们只需要作用的组件或元素上加上v-once即可
  • vue3.2之后,又增加了v-memo指令,可以有条件缓存部分模板并控制它们的更新,可以说控制力更强了
  • 编译器发现元素上面有v-once时,会将首次计算结果存入缓存对象,组件再次渲染时就会从缓存获取,从而避免再次计算

原理

下面例子使用了v-once

    <script setup>
    import { ref } from 'vue'

    const msg = ref('Hello World!')
    </script>

    <template>
      <h1 v-once>{{ msg }}</h1>
      <input v-model="msg">
    </template>

我们发现v-once出现后,编译器会缓存作用元素或组件,从而避免以后更新时重新计算这一部分:

    // ...
    return (_ctx, _cache) => {
      return (_openBlock(), _createElementBlock(_Fragment, null, [
        // 从缓存获取vnode
        _cache[0] || (
          _setBlockTracking(-1),
          _cache[0] = _createElementVNode("h1", null, [
            _createTextVNode(_toDisplayString(msg.value), 1 /* TEXT */)
          ]),
          _setBlockTracking(1),
          _cache[0]
        ),
    // ...
Last Updated:
Contributors: leeguooooo