]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip(vapor): custom directives
authorEvan You <evan@vuejs.org>
Sat, 8 Feb 2025 13:32:16 +0000 (21:32 +0800)
committerEvan You <evan@vuejs.org>
Sat, 8 Feb 2025 13:32:16 +0000 (21:32 +0800)
packages/compiler-vapor/src/generators/directive.ts
packages/runtime-vapor/src/directives/custom.ts [new file with mode: 0644]
packages/runtime-vapor/src/directives/vModel.ts
packages/runtime-vapor/src/index.ts

index 6321ad216f8f74a35a03728c0284ffd7701a8be3..7ed4624c1f8a540d260509386ad5c0dc4392f0c4 100644 (file)
@@ -57,7 +57,6 @@ function genCustomDirectives(
 
   return [
     NEWLINE,
-    // @ts-expect-error
     ...genCall(helper('withVaporDirectives'), element, directives),
   ]
 
diff --git a/packages/runtime-vapor/src/directives/custom.ts b/packages/runtime-vapor/src/directives/custom.ts
new file mode 100644 (file)
index 0000000..06a5a99
--- /dev/null
@@ -0,0 +1,36 @@
+import type { DirectiveModifiers } from '@vue/runtime-dom'
+import type { VaporComponentInstance } from '../component'
+import { renderEffect } from '../renderEffect'
+
+// !! vapor directive is different from vdom directives
+export type VaporDirective = (
+  node: Element | VaporComponentInstance,
+  value?: () => any,
+  argument?: string,
+  modifiers?: DirectiveModifiers,
+) => (() => void) | void
+
+type DirectiveArguments = Array<
+  | [VaporDirective | undefined]
+  | [VaporDirective | undefined, () => any]
+  | [VaporDirective | undefined, () => any, argument: string]
+  | [
+      VaporDirective | undefined,
+      value: () => any,
+      argument: string,
+      modifiers: DirectiveModifiers,
+    ]
+>
+
+export function withVaporDirectives(
+  node: Element | VaporComponentInstance,
+  dirs: DirectiveArguments,
+): void {
+  // TODO handle custom directive on component
+  for (const [dir, value, argument, modifiers] of dirs) {
+    if (dir) {
+      const ret = dir(node, value, argument, modifiers)
+      if (ret) renderEffect(ret)
+    }
+  }
+}
index 12dfb81ff1fdcb390d4507e022600184c1038308..0c32b24bf4a8aec62ecc65006c7f07eeeee6873d 100644 (file)
@@ -1,4 +1,5 @@
 import {
+  currentInstance,
   onMounted,
   vModelCheckboxInit,
   vModelCheckboxUpdate,
@@ -26,12 +27,20 @@ type VaporModelDirective<
   modifiers?: { [key in Modifiers]?: true },
 ) => void
 
+function ensureMounted(cb: () => void) {
+  if (currentInstance!.isMounted) {
+    cb()
+  } else {
+    onMounted(cb)
+  }
+}
+
 export const applyTextModel: VaporModelDirective<
   HTMLInputElement | HTMLTextAreaElement,
   'trim' | 'number' | 'lazy'
 > = (el, get, set, { trim, number, lazy } = {}) => {
   vModelTextInit(el, trim, number, lazy, set)
-  onMounted(() => {
+  ensureMounted(() => {
     let value: any
     renderEffect(() => {
       vModelTextUpdate(el, value, (value = get()), trim, number, lazy)
@@ -45,7 +54,7 @@ export const applyCheckboxModel: VaporModelDirective<HTMLInputElement> = (
   set,
 ) => {
   vModelCheckboxInit(el, set)
-  onMounted(() => {
+  ensureMounted(() => {
     let value: any
     renderEffect(() => {
       vModelCheckboxUpdate(
@@ -64,7 +73,7 @@ export const applyRadioModel: VaporModelDirective<HTMLInputElement> = (
   set,
 ) => {
   addEventListener(el, 'change', () => set(vModelGetValue(el)))
-  onMounted(() => {
+  ensureMounted(() => {
     let value: any
     renderEffect(() => {
       if (value !== (value = get())) {
@@ -79,7 +88,7 @@ export const applySelectModel: VaporModelDirective<
   'number'
 > = (el, get, set, modifiers) => {
   vModelSelectInit(el, get(), modifiers && modifiers.number, set)
-  onMounted(() => {
+  ensureMounted(() => {
     renderEffect(() => vModelSetSelected(el, traverse(get())))
   })
 }
index 808a5f46e4592182ae7e60c812fa72369e77860a..85f1bc5eacee3380ca7bccdfa1fbf56860773a44 100644 (file)
@@ -2,6 +2,7 @@
 export { createVaporApp } from './apiCreateApp'
 export { defineVaporComponent } from './apiDefineComponent'
 export { vaporInteropPlugin } from './vdomInterop'
+export type { VaporDirective } from './directives/custom'
 
 // compiler-use only
 export { insert, prepend, remove } from './block'
@@ -39,3 +40,4 @@ export {
   applySelectModel,
   applyDynamicModel,
 } from './directives/vModel'
+export { withVaporDirectives } from './directives/custom'