vue3.5新特性

vue在2024.09.03发布了3.5正式版本,其中包含多方面的升级和优化

性能优化

响应式系统重构优化,在内存占用、性能方面均有收益

Memory Usage Improvements

Given a test case with 1000 refs + 2000 computeds (1000 chained pairs) + 1000 effects subscribing to the last computed, comparing the total memory used by these class instances:

  • Before (3.4.19): 1426k
  • After (this PR): 631k (-56%)

Performance Comparison

Reasonable gains across the board, most notably for single ref invoking multiple effects (+118%~185%) and reading multiple invalidated computeds (+176%~244%).

  • 单个 ref 调用多个 effects:当一个 ref(Vue 中的响应式数据)被多次使用并触发多个副作用(effects)时,性能提升了118%到185%。这意味着在 Vue 的新优化下,相同的操作现在比以前快了将近两倍。
  • 读取多个无效的计算属性:计算属性是基于响应式数据的缓存值。当这些计算属性由于依赖的数据改变而变得无效时,重新读取这些属性的性能提升了176%到244%。这表明在处理多次读取失效的计算属性时,性能有了非常明显的提升

响应式相关

defnieProps支持解构

  • 之前defineProps不支持解构,相比之前,支持解构后,不失响应式特性
const { count } = defineProps(['count'])

watch onWatcherCleanup支持注册清理函数

  • Watch api中,监听对象发生变化后,清理副作用不再使用的引用,避免内存泄漏
watch(id, async (newId, oldId) => {
  const { response, cancel } = doAsyncWork(newId)
  // `cancel` will be called if `id` changes, cancelling
  // the previous request if it hasn't completed yet
  onWatcherCleanup(cancel)
  data.value = await response
})
function doAsyncWork(id: string) {
  const source = new AbortController();
  const { signal } = source;

  const response = fetch(`/api/data?id=${id}`, { signal });

  return { response, cancel: () => source.abort() };
}
  • 和onEffectCleanup的区别,不在watch中用,就不会被注册生效
<script setup>
watchEffect(async () => {
  data1.value = await queryAsyncData('api1', id.value)
  data2.value = await queryAsyncData('api2', id.value)
})

// When getting called outside of the scope of Watch API,
// since there is no active effect scope,
// therefore the cleanup callback for cancel will not be registered
async function pull() {
  data3.value = await queryAsyncData('api3', id.value)
}
pull()
</script>

watch deep支持数字

// infinite depth
watch(src, () => {}, { deep: true })

// explicit depth
watch(src, () => {}, { deep: 1 })

新增pause/resume方法 控制effect执行

  • 主要是为了避免一些不必要的副作用执行以提升性能,比如keep-alive组件,暂停deactive非激活状态下的副作用执行,或者结合IntersectionObserver延迟执行副作用场景
const { stop, resume, pause } = watch(refs,callback)

stop()

resume()

pause()

onEffectCleanup支持注册清理函数

  • 利用副作用,清除监听、定时器等不再使用的引用,避免内存泄漏
export function queryAsyncData(api, id) {
  const { response, cancel } = doAsyncWork(api, id)
  // `cancel` will be called if this function get called in Watch API and the effect source changed
  // so that previous pending request will be cancelled
  // if not yet completed
  if (getCurrentEffect()) {
    onEffectCleanup(cancel)
  }
  return response
}
// in component setup or vapor render
watchEffect(() => {
  on(el1, eventName.value, handler)
  on(el2, eventName.value, handler)
})

// in runtime-vapor pkg
function on(el, event, handler) {
  el.addEventListener(event, handler)
  if (getCurrentEffect()) {
    onEffectCleanup(() => {
      el.removeEventListener(event, handler)
    })
  }
}

add failSilently argument for onScopeDispose

  • onScopeDispose 用于在组件销毁时自动清除定时器,避免内存泄漏
import { ref, onScopeDispose } from 'vue';

export default {
  setup() {
    const timer = ref(null);

    function startTimer() {
      timer.value = setInterval(() => {
        console.log('Timer is running');
      }, 1000);
    }

    // 当作用域销毁时,清除定时器
    onScopeDispose(() => {
      clearInterval(timer.value);
    },true);

    startTimer();

    return {
      timer,
    };
  },
};
  • 新增参数,支持静默告警
    • 其实就是提供了屏蔽告警日志的参数

其他新特性

useId

  • 主要是为了创建唯一的id用在dom属性上,每次调用 useId()都会创建唯一的id
<script setup>
import { useId } from 'vue'

const id = useId()
</script>

<template>
  <form>
    <label :for="id">Name:</label>
    <input :id="id" type="text" />
  </form>
</template>

useTemplateRef

  • 以往用ref既是用于响应式数据的,又用在dom上,就会会造成疑惑,所以专门有这个处理dom
<script setup>
import { useTemplateRef, onMounted } from 'vue'

const inputRef = useTemplateRef('input')

onMounted(() => {
  inputRef.value.focus()
})
</script>

<template>
  <input ref="input" />
</template>
app.onUnmount()
  • 卸载时一些处理,比如清理不必要的引用等
function install(app: App) {
  function cleanupSomeSideeffect() {
    /* ...*/
  }
  //清理
  app.onUnmount(cleanupSomeSideffect);
}

app.config.throwUnhandledErrorInProduction
- 主要为了生产环境下抛出错误
app.config.throwUnhandledErrorInProduction = true

自定义元素

  • Vue对Web Components的支持,使得开发者可以创建自定义元素,这些元素可以跨框架使用,甚至在不使用Vue.js的项目中也可以使用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值