From: 三咲智子 Kevin Deng Date: Fri, 15 Nov 2024 22:58:26 +0000 (+0800) Subject: feat(vapor): support more magic vars X-Git-Tag: v3.6.0-alpha.1~16^2~269 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3f6ce964c7a08aeef1f94bac1d66519a689ab2fa;p=thirdparty%2Fvuejs%2Fcore.git feat(vapor): support more magic vars --- diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap index b583325434..efb33e64d7 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap @@ -4,7 +4,7 @@ exports[`compile > bindings 1`] = ` "import { renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor'; const t0 = _template("
") -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("
") -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("
") -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("
") -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("
") -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("
") -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("
") -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("
") -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("
{{ bar }}
") -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("
{{ bar }}
") const t1 = _template("
") -export function render(_ctx, $props) { +export function render(_ctx, $props, $emit, $attrs, $slots) { const _component_Comp = _resolveComponent("Comp") const n0 = t0() const n3 = t1() diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/expression.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/expression.spec.ts.snap index 410acfd9bc..077e98dbdc 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/expression.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/expression.spec.ts.snap @@ -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 }" diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap index d06052b813..79b8fffbb1 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap @@ -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 }" diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap index c01b6431c9..a5ee792e2d 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vHtml.spec.ts.snap @@ -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("
") -export function render(_ctx, $props) { +export function render(_ctx, $props, $emit, $attrs, $slots) { const n0 = t0() _renderEffect(() => _setHtml(n0, _ctx.code)) return n0 diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap index 87bc349f41..04ceb3c5ac 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap @@ -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("") -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() diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap index be0649ee1b..cbd195b83e 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap @@ -65,7 +65,7 @@ const t2 = _template("
") const t3 = _template("") _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("
") _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 diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap index 70c9e35ab9..5957dae880 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap @@ -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("
") -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, " "]) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap index 26a5d6bf52..622966ba8d 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vText.spec.ts.snap @@ -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("
") -export function render(_ctx, $props) { +export function render(_ctx, $props, $emit, $attrs, $slots) { const n0 = t0() _renderEffect(() => _setText(n0, _ctx.str)) return n0 diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts index db9f5bff64..58cae3b884 100644 --- a/packages/compiler-vapor/src/generate.ts +++ b/packages/compiler-vapor/src/generate.ts @@ -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( ', ', diff --git a/packages/compiler-vapor/src/generators/expression.ts b/packages/compiler-vapor/src/generators/expression.ts index ad40584652..d13a664121 100644 --- a/packages/compiler-vapor/src/generators/expression.ts +++ b/packages/compiler-vapor/src/generators/expression.ts @@ -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 } diff --git a/packages/runtime-vapor/src/apiRender.ts b/packages/runtime-vapor/src/apiRender.ts index dc661fb2e6..fe06beb655 100644 --- a/packages/runtime-vapor/src/apiRender.ts +++ b/packages/runtime-vapor/src/apiRender.ts @@ -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() diff --git a/packages/runtime-vapor/src/component.ts b/packages/runtime-vapor/src/component.ts index 788108bde7..94f4a19d6f 100644 --- a/packages/runtime-vapor/src/component.ts +++ b/packages/runtime-vapor/src/component.ts @@ -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, {