]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(vapor): support more magic vars
author三咲智子 Kevin Deng <sxzz@sxzz.moe>
Fri, 15 Nov 2024 22:58:26 +0000 (06:58 +0800)
committer三咲智子 Kevin Deng <sxzz@sxzz.moe>
Fri, 15 Nov 2024 22:58:26 +0000 (06:58 +0800)
12 files changed:
packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/__snapshots__/expression.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap
packages/compiler-vapor/src/generate.ts
packages/compiler-vapor/src/generators/expression.ts
packages/runtime-vapor/src/apiRender.ts
packages/runtime-vapor/src/component.ts

index b5833254342c45510b1a19d9720770332288700a..efb33e64d754c296f9a4ef2f2d599d8a4d4f022a 100644 (file)
@@ -4,7 +4,7 @@ exports[`compile > bindings 1`] = `
 "import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor';
 const t0 = _template("<div></div>")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = t0()
   _renderEffect(() => _setText(n0, "count is ", _ctx.count, "."))
   return n0
@@ -56,7 +56,7 @@ exports[`compile > directives > custom directive > basic 1`] = `
 "import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
 const t0 = _template("<div></div>")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = t0()
   _withDirectives(n0, [[_ctx.vExample]])
   return n0
@@ -67,7 +67,7 @@ exports[`compile > directives > custom directive > binding value 1`] = `
 "import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
 const t0 = _template("<div></div>")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = t0()
   _withDirectives(n0, [[_ctx.vExample, () => _ctx.msg]])
   return n0
@@ -78,7 +78,7 @@ exports[`compile > directives > custom directive > dynamic parameters 1`] = `
 "import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
 const t0 = _template("<div></div>")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = t0()
   _withDirectives(n0, [[_ctx.vExample, () => _ctx.msg, _ctx.foo]])
   return n0
@@ -89,7 +89,7 @@ exports[`compile > directives > custom directive > modifiers 1`] = `
 "import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
 const t0 = _template("<div></div>")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = t0()
   _withDirectives(n0, [[_ctx.vExample, () => _ctx.msg, void 0, { bar: true }]])
   return n0
@@ -100,7 +100,7 @@ exports[`compile > directives > custom directive > modifiers w/o binding 1`] = `
 "import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
 const t0 = _template("<div></div>")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = t0()
   _withDirectives(n0, [[_ctx.vExample, void 0, void 0, { "foo-bar": true }]])
   return n0
@@ -111,7 +111,7 @@ exports[`compile > directives > custom directive > static parameters 1`] = `
 "import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
 const t0 = _template("<div></div>")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = t0()
   _withDirectives(n0, [[_ctx.vExample, () => _ctx.msg, "foo"]])
   return n0
@@ -122,7 +122,7 @@ exports[`compile > directives > custom directive > static parameters and modifie
 "import { withDirectives as _withDirectives, template as _template } from 'vue/vapor';
 const t0 = _template("<div></div>")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = t0()
   _withDirectives(n0, [[_ctx.vExample, () => _ctx.msg, "foo", { bar: true }]])
   return n0
@@ -143,7 +143,7 @@ exports[`compile > directives > v-pre > basic 1`] = `
 "import { setInheritAttrs as _setInheritAttrs, template as _template } from 'vue/vapor';
 const t0 = _template("<div :id=\\"foo\\"><Comp></Comp>{{ bar }}</div>")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = t0()
   _setInheritAttrs(false)
   return n0
@@ -155,7 +155,7 @@ exports[`compile > directives > v-pre > should not affect siblings after it 1`]
 const t0 = _template("<div :id=\\"foo\\"><Comp></Comp>{{ bar }}</div>")
 const t1 = _template("<div></div>")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const _component_Comp = _resolveComponent("Comp")
   const n0 = t0()
   const n3 = t1()
index 410acfd9bcc00f0a81673cb31fbe1089ae4ffb37..077e98dbdc5b3c9930d0fb4677832fe68edf542d 100644 (file)
@@ -12,7 +12,7 @@ export function render(_ctx) {
 exports[`compiler: expression > props 1`] = `
 "import { createTextNode as _createTextNode } from 'vue/vapor';
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = _createTextNode(() => [$props.foo])
   return n0
 }"
@@ -21,7 +21,7 @@ export function render(_ctx, $props) {
 exports[`compiler: expression > props aliased 1`] = `
 "import { createTextNode as _createTextNode } from 'vue/vapor';
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = _createTextNode(() => [$props['bar']])
   return n0
 }"
index d06052b81309a7da34bfc566fd54db2e0abfcfc7..79b8fffbb1889042d49773713a487e83e488e7cd 100644 (file)
@@ -3,7 +3,7 @@
 exports[`compiler: element transform > component > do not resolve component from non-script-setup bindings 1`] = `
 "import { resolveComponent as _resolveComponent, createComponent as _createComponent } from 'vue/vapor';
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const _component_Example = _resolveComponent("Example")
   const n0 = _createComponent(_component_Example, null, null, true)
   return n0
@@ -14,7 +14,7 @@ exports[`compiler: element transform > component > generate multi root component
 "import { createComponent as _createComponent, template as _template } from 'vue/vapor';
 const t0 = _template("123")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n1 = t0()
   const n0 = _createComponent(_ctx.Comp)
   return [n0, n1]
@@ -24,7 +24,7 @@ export function render(_ctx, $props) {
 exports[`compiler: element transform > component > generate single root component 1`] = `
 "import { createComponent as _createComponent } from 'vue/vapor';
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = _createComponent(_ctx.Comp, null, null, true)
   return n0
 }"
@@ -57,7 +57,7 @@ exports[`compiler: element transform > component > resolve component from setup
 exports[`compiler: element transform > component > resolve component from setup bindings 1`] = `
 "import { createComponent as _createComponent } from 'vue/vapor';
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = _createComponent(_ctx.Example, null, null, true)
   return n0
 }"
@@ -73,7 +73,7 @@ exports[`compiler: element transform > component > resolve namespaced component
 exports[`compiler: element transform > component > resolve namespaced component from props bindings (non-inline) 1`] = `
 "import { createComponent as _createComponent } from 'vue/vapor';
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = _createComponent(_ctx.Foo.Example, null, null, true)
   return n0
 }"
@@ -89,7 +89,7 @@ exports[`compiler: element transform > component > resolve namespaced component
 exports[`compiler: element transform > component > resolve namespaced component from setup bindings 1`] = `
 "import { createComponent as _createComponent } from 'vue/vapor';
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = _createComponent(_ctx.Foo.Example, null, null, true)
   return n0
 }"
index c01b6431c92813746b4da8fc6d0cad32a52cbdb8..a5ee792e2d1b7d63e9144b2e0d7b7964a20fcb7e 100644 (file)
@@ -4,7 +4,7 @@ exports[`v-html > should convert v-html to innerHTML 1`] = `
 "import { renderEffect as _renderEffect, setHtml as _setHtml, template as _template } from 'vue/vapor';
 const t0 = _template("<div></div>")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = t0()
   _renderEffect(() => _setHtml(n0, _ctx.code))
   return n0
index 87bc349f41038efd6a94286e88b0d3f9cfc7528f..04ceb3c5ac1d484cf225200760b9dc04cc17f057 100644 (file)
@@ -180,7 +180,7 @@ exports[`compiler: vModel transform > should support member expression 1`] = `
 "import { vModelText as _vModelText, withDirectives as _withDirectives, delegate as _delegate, template as _template } from 'vue/vapor';
 const t0 = _template("<input>")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = t0()
   _withDirectives(n0, [[_vModelText, () => _ctx.setupRef.child]])
   const n1 = t0()
index be0649ee1b1369110dda8ea20d26dce91f9c659a..cbd195b83e3fe52873138888852b01735abcfbfe 100644 (file)
@@ -65,7 +65,7 @@ const t2 = _template("<div></div>")
 const t3 = _template("<input>")
 _delegateEvents("click", "contextmenu", "mouseup", "keyup")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = t0()
   const n1 = t1()
   const n2 = t0()
@@ -493,7 +493,7 @@ exports[`v-on > simple expression 1`] = `
 const t0 = _template("<div></div>")
 _delegateEvents("click")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = t0()
   _delegate(n0, "click", () => _ctx.handleClick)
   return n0
index 70c9e35ab91c0c7f1b46623af4d2d93ffe72f552..5957dae88099c8d523b7b2c8e583e6ee99ed6b83 100644 (file)
@@ -16,7 +16,7 @@ exports[`compiler: v-once > basic 1`] = `
 "import { createTextNode as _createTextNode, setClass as _setClass, prepend as _prepend, template as _template } from 'vue/vapor';
 const t0 = _template("<div><span></span></div>")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n2 = t0()
   const n1 = n2.firstChild
   const n0 = _createTextNode([_ctx.msg, " "])
index 26a5d6bf52113723837a3b64681811858a560fb6..622966ba8d9f010a70f654605d4de6908a17cd27 100644 (file)
@@ -4,7 +4,7 @@ exports[`v-text > should convert v-text to textContent 1`] = `
 "import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor';
 const t0 = _template("<div></div>")
 
-export function render(_ctx, $props) {
+export function render(_ctx, $props, $emit, $attrs, $slots) {
   const n0 = t0()
   _renderEffect(() => _setText(n0, _ctx.str))
   return n0
index db9f5bff64ad4bdc096ca7cbc54cc06257d7258e..58cae3b884190c3fbbc8c78d30f00b925dc88d90 100644 (file)
@@ -110,7 +110,7 @@ export function generate(
   const args = ['_ctx']
   if (bindingMetadata && !inline) {
     // binding optimization args
-    args.push('$props')
+    args.push('$props', '$emit', '$attrs', '$slots')
   }
   const signature = (options.isTS ? args.map(arg => `${arg}: any`) : args).join(
     ', ',
index ad40584652cc2777c309318b5af429c9fa1c1a2b..d13a6641218055a1740cdf1522f236c05aa24ef2 100644 (file)
@@ -192,9 +192,14 @@ function canPrefix(name: string) {
   if (isGloballyAllowed(name)) {
     return false
   }
-  // special case for webpack compilation
-  if (name === 'require') {
+  if (
+    // special case for webpack compilation
+    name === 'require' ||
+    name === '$props' ||
+    name === '$emit' ||
+    name === '$attrs' ||
+    name === '$slots'
+  )
     return false
-  }
   return true
 }
index dc661fb2e69f931f71aef65446b3bcde04ae7821..fe06beb65521500b8b2d30f916f8d5237435bf36 100644 (file)
@@ -2,6 +2,8 @@ import {
   type ComponentInternalInstance,
   componentKey,
   createSetupContext,
+  getAttrsProxy,
+  getSlotsProxy,
   setCurrentInstance,
   validateComponentName,
 } from './component'
@@ -73,6 +75,9 @@ export function setupComponent(instance: ComponentInternalInstance): void {
         [
           instance.setupState, // _ctx
           __DEV__ ? shallowReadonly(props) : props, // $props
+          instance.emit, // $emit
+          __DEV__ ? getAttrsProxy(instance) : instance.attrs, // $attrs
+          __DEV__ ? getSlotsProxy(instance) : instance.slots, // $slots
         ],
       )
       resetTracking()
index 788108bde75499e11f6bb40d337d78e4c40783cf..94f4a19d6f7f8852df66634bbeda744082115ecb 100644 (file)
@@ -93,9 +93,7 @@ export function createSetupContext(
     })
   } else {
     return {
-      get attrs() {
-        return getAttrsProxy(instance)
-      },
+      attrs: instance.attrs,
       emit: instance.emit,
       slots: instance.slots,
       expose,
@@ -390,38 +388,34 @@ export function validateComponentName(
   }
 }
 
-function getAttrsProxy(instance: ComponentInternalInstance): Data {
+/**
+ * Dev-only
+ */
+export function getAttrsProxy(instance: ComponentInternalInstance): Data {
   return (
     instance.attrsProxy ||
-    (instance.attrsProxy = new Proxy(
-      instance.attrs,
-      __DEV__
-        ? {
-            get(target, key: string) {
-              return target[key]
-            },
-            set() {
-              warn(`setupContext.attrs is readonly.`)
-              return false
-            },
-            deleteProperty() {
-              warn(`setupContext.attrs is readonly.`)
-              return false
-            },
-          }
-        : {
-            get(target, key: string) {
-              return target[key]
-            },
-          },
-    ))
+    (instance.attrsProxy = new Proxy(instance.attrs, {
+      get(target, key: string) {
+        return target[key]
+      },
+      set() {
+        warn(`setupContext.attrs is readonly.`)
+        return false
+      },
+      deleteProperty() {
+        warn(`setupContext.attrs is readonly.`)
+        return false
+      },
+    }))
   )
 }
 
 /**
  * Dev-only
  */
-function getSlotsProxy(instance: ComponentInternalInstance): StaticSlots {
+export function getSlotsProxy(
+  instance: ComponentInternalInstance,
+): StaticSlots {
   return (
     instance.slotsProxy ||
     (instance.slotsProxy = new Proxy(instance.slots, {