欢迎加入QQ群一起探讨交流:581902292

vue3.6.0-beta.1 公测版本已发布 ,Vapor Mode 、Alien Signals 新特性

vue 3.6 + 版本还基于alien-signals对@vue/reactivity进行了重大重构,显著提升了响应式系统的性能和内存使用效率;同时完成了Vapor Mode预期功能集成!这里不对 Vapor Mode 、Alien Signals 基本介绍和使用,主要 Vapor Mode 与 VDom 的API使用差异记录:

1.生态兼容性:
	虽然支持混用,但如果你在 Vapor 组件里使用依赖虚拟 DOM 的第三方组件库(比如现在的 Element Plus 或 Ant Design Vue),可能会遇到边缘 BUG。官方建议尽量保持“分区治理”,不要过度混用。
	
2.API 差异
	1.选项式API不支持
		Vapor Mode 是为 Composition API (<script setup>) 而生的。如果你还在坚持用 data(), methods() 这种 Options API 写法,Vapor Mode 暂时不支持,可能永远也不会支持。
		
	1.app.config.globalProperties 不支持
	
	2.getCurrentInstance() 在 Vapor 组件中会返回 null
	
	3.Suspense 组件在 Vapor Mode 暂不支持
	
	4.在 Vapor 模式下的模板里,不能像以前那样直接使用组件实例上“自动提供”的一些属性。
		在 【传统 VDOM 模式(Vue 2 / Vue 3 默认模式)】中,Vue 会在模板里自动注入一些来自组件实例的属性,比如:$props、$slots、$attrs、$emit、$refs,因此你可以在模板中直接这样写:
			<div>{{ $props.title }}</div>
			<div v-if="$slots.default">有默认插槽</div>
			
		Vapor 模式【不再创建传统的组件实例(component instance)】,或者说不再暴露这个实例给模板使用。
			模板中 【不会自动存在 $props、$slots、$attrs、$emit、$refs】 等变量
			模板表达式只能访问【显式提供的数据】
				<!-- ❌ Vapor 模式下不可用 -->
				<div>{{ $props.title }}</div>
				<div v-if="$slots.default">...</div>
				
	5.@vue:xxx 按元素级别触发的生命周期事件不支持
		@vue:xxx 是 Vue 在 VDOM 模式下提供的一组“内部/底层生命周期事件”,可以直接绑定在某个 DOM 元素或组件上,用于监听这个“虚拟节点(VNode)”的生命周期。
		VDOM 模式
			<template>
              <div
                @vue:mounted="onMounted"
                @vue:updated="onUpdated"
                @vue:unmounted="onUnmounted"
              >
                这个 div 元素对应的 VNode 被挂载 / 更新 / 卸载时,触发回调
              </div>
            </template>
	
	6.Vapor 模式下,自定义指令(custom directive)的“函数签名”和用法,和传统 VDOM 模式不一样。
		type VaporDirective = (
		  // 指令作用的目标:普通 DOM 元素 | 组件
          node: Element | VaporComponentInstance,
          // 指令的值:在 Vapor 里你不会直接拿到 value, 而是拿到一个函数value()
          value?: () => any,
          // 指令参数(: 后面的部分): <div v-my-directive:params />
          argument?: string,
          // 指令修饰符 (. 后面的部分): <div v-my-directive.foo.bar />
          modifiers?: DirectiveModifiers,
        ) => (() => void) | void
		
		// vopar mode 自定义指令
		const MyDirective = (el, source) => {
		  // 初始化逻辑
          watchEffect(() => {
            el.textContent = source()
          })
          return () => {
          	// 清理函数
          	console.log('cleanup')
          }
		}
		
		特点:Vapor 指令是一个“接收节点 + 可读取值函数”的普通函数,返回值(如果有)就是卸载时的清理逻辑,不再有一堆生命周期钩子。
			一个函数
			一次初始化
			一个清理函数: 当节点存在时做事,节点销毁时撤销事
			没有 updated 钩子: 没有 diff / update 阶段
		
		// vdom 自定义指令
        const myDirective = {
            created(el, binding, vnode, prevVnode) { },
            beforeMount(el, binding, vnode, prevVnode) {},
            mounted(el, binding, vnode, prevVnode) {},
            beforeUpdate(el, binding, vnode, prevVnode) {},
            updated(el, binding, vnode, prevVnode) {},
            beforeUnmount(el, binding, vnode, prevVnode) {},
            unmounted(el, binding, vnode, prevVnode) {}
        }

        app.directive('directiveName', myDirective )
 

注意:当 Vapor 和传统 VDOM 组件混合使用时,目前是“有限支持”,不是完全无缝。
	1.Vapor 组件可以嵌套 VDOM 组件;VDOM 组件也可以嵌套 Vapor 组件;
	
	2.目前只保证这些是可靠的:props、events、slots(基础用法),但一些极端/复杂场景还没完全处理好。
		如果你在 Vapor Mode 里用:Element Plus、Ant Design Vue、Vuetify 这些库强依赖 VDOM,那你【大概率会遇到奇怪问题】(不是设计目标场景);
		例如:在 VDOM 组件里:slots.default();
		当 slots.default() 实际来自 【Vapor 组件】 时:【不能正常渲染】,是一个已知 bug / 限制;按照如下写法:
			import { renderSlot } from 'vue'
			// 必须使用 Vue 的 renderSlot 辅助函数
			// slots.default() 是 VDOM slot 函数调用;Vapor slot 不是传统的 VNode 函数;interop 层没法完全模拟这种调用方式;renderSlot 是 Vue 内部“官方桥接入口”
		renderSlot(slots, 'default')
	
	3.项目中如何使用:把应用按区域隔离使用
		一块区域:全 Vapor; 另一块区域:全 VDOM,如下:
            App
             ├─ LegacyLayout   (VDOM)
             │   ├─ ElementPlusComponents (VDOM)
             │
             └─ VaporLayout    (Vapor)
                 ├─ VaporList
                 ├─ VaporChart
                 
		而不是:Vapor → VDOM → Vapor → VDOM (❌ 不推荐)
posted @ 2025-12-31 10:54  £AP︶ㄣOL◢◤LO  阅读(46)  评论(0)    收藏  举报