diff --git a/CHANGELOG.md b/CHANGELOG.md index bc98f138f33..3ccae2540a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,40 @@ +## [2.7.10](https://github.com/vuejs/vue/compare/v2.7.9...v2.7.10) (2022-08-23) + + +### Bug Fixes + +* **compiler-sfc:** avoid deindent when lang is jsx/tsx ([46ca7bc](https://github.com/vuejs/vue/commit/46ca7bcddc06c50796ccff82d8c45693f1f14f47)), closes [#12755](https://github.com/vuejs/vue/issues/12755) +* fix parent of multi-nested HOC $el not updating ([#12757](https://github.com/vuejs/vue/issues/12757)) ([e0b26c4](https://github.com/vuejs/vue/commit/e0b26c483a1ba407a818b1fcba1a439df24e84a8)), closes [#12589](https://github.com/vuejs/vue/issues/12589) +* **types:** Add missing type parameter constraints ([#12754](https://github.com/vuejs/vue/issues/12754)) ([810f6d1](https://github.com/vuejs/vue/commit/810f6d12edea47cde7f39eaf7ec3ae1b7300d40c)) + + + +## [2.7.9](https://github.com/vuejs/vue/compare/v2.7.8...v2.7.9) (2022-08-19) + + +### Bug Fixes + +* **compiler-sfc:** allow full hostnames in asset url base ([#12732](https://github.com/vuejs/vue/issues/12732)) ([5c742eb](https://github.com/vuejs/vue/commit/5c742eb2e0d8dad268fb29ed4f92d286b5e0f4b5)), closes [#12731](https://github.com/vuejs/vue/issues/12731) +* **compiler-sfc:** rewriteDefault for class with decorators ([#12747](https://github.com/vuejs/vue/issues/12747)) ([5221d4d](https://github.com/vuejs/vue/commit/5221d4d3b6049c87d196d99dbb64bcd3f3b07279)) +* directives shorthand normalize error ([#12744](https://github.com/vuejs/vue/issues/12744)) ([2263948](https://github.com/vuejs/vue/commit/2263948c249e7486403bc5880712e6d9fd15c17f)), closes [#12743](https://github.com/vuejs/vue/issues/12743) +* ensure render watcher of manually created instance is correctly tracked in owner scope ([bd89ce5](https://github.com/vuejs/vue/commit/bd89ce53a9de417a9372630bb5d433a40acc1a53)), closes [#12701](https://github.com/vuejs/vue/issues/12701) +* fix effect scope tracking for manually created instances ([7161176](https://github.com/vuejs/vue/commit/7161176cd0dff10d65ab58e266018aff2660610f)), closes [#12705](https://github.com/vuejs/vue/issues/12705) +* **ssr:** fix on-component directives rendering ([#12661](https://github.com/vuejs/vue/issues/12661)) ([165a14a](https://github.com/vuejs/vue/commit/165a14a6c6c406176037465d2961259c5c980399)), closes [#10733](https://github.com/vuejs/vue/issues/10733) +* **types:** allow attaching unknown options to defined component ([b4bf4c5](https://github.com/vuejs/vue/commit/b4bf4c52ad31e02307cfd4d643dc5610c893e3ba)), closes [#12742](https://github.com/vuejs/vue/issues/12742) +* **types:** fix missing error for accessing undefined instance properties ([8521f9d](https://github.com/vuejs/vue/commit/8521f9d3f63d26bde99b747f0cb14d0ac5ba5971)), closes [#12718](https://github.com/vuejs/vue/issues/12718) +* **types:** fix options suggestions when using defineComponent ([4b37b56](https://github.com/vuejs/vue/commit/4b37b568c7c3fd238aa61fcc956f882223f8e87f)), closes [#12736](https://github.com/vuejs/vue/issues/12736) +* **types:** Make SetupBindings optional on ExtendedVue and CombinedVueInstance ([#12727](https://github.com/vuejs/vue/issues/12727)) ([00458cd](https://github.com/vuejs/vue/commit/00458cd38d209410d3c675729230a42a0a34a4b9)), closes [#12726](https://github.com/vuejs/vue/issues/12726) [#12717](https://github.com/vuejs/vue/issues/12717) +* **watch:** avoid pre watcher firing on unmount ([f0057b1](https://github.com/vuejs/vue/commit/f0057b101e6451d5095cdb7fd6308fd31ac0450c)), closes [#12703](https://github.com/vuejs/vue/issues/12703) + + +### Features + +* **types:** enhance type for onErrorCaptured ([#12735](https://github.com/vuejs/vue/issues/12735)) ([bba6b3d](https://github.com/vuejs/vue/commit/bba6b3d6b4e3e26d28abbf20e74ec2f3e64f1a92)) +* **types:** export DefineComponent ([80d1baf](https://github.com/vuejs/vue/commit/80d1baf92050da411fb1bfe714401c498001dd36)), closes [#12748](https://github.com/vuejs/vue/issues/12748) +* **types:** support mixins inference for new Vue() ([#12737](https://github.com/vuejs/vue/issues/12737)) ([89a6b5e](https://github.com/vuejs/vue/commit/89a6b5e8658a6e3ae2cf649829901784ac9deb3c)), closes [#12730](https://github.com/vuejs/vue/issues/12730) + + + ## [2.7.8](https://github.com/vuejs/vue/compare/v2.7.7...v2.7.8) (2022-07-22) diff --git a/README.md b/README.md index 5a3f576d716..5eef53d3fa0 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ Vue.js supports all browsers that are [ES5-compliant](https://kangax.github.io/c ## Documentation -To check out [live examples](https://vuejs.org/v2/examples/) and docs, visit [vuejs.org](https://vuejs.org). +To check out [live examples](https://v2.vuejs.org/v2/examples/) and docs, visit [vuejs.org](https://v2.vuejs.org). ## Questions diff --git a/package.json b/package.json index 039c8882375..e8750ff7385 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue", - "version": "2.7.8", + "version": "2.7.10", "packageManager": "pnpm@7.1.0", "description": "Reactive, component-oriented view layer for modern web interfaces.", "main": "dist/vue.runtime.common.js", diff --git a/packages/compiler-sfc/package.json b/packages/compiler-sfc/package.json index 6a6037a3111..115ae6e775b 100644 --- a/packages/compiler-sfc/package.json +++ b/packages/compiler-sfc/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compiler-sfc", - "version": "2.7.8", + "version": "2.7.10", "description": "compiler-sfc for Vue 2", "main": "dist/compiler-sfc.js", "types": "dist/compiler-sfc.d.ts", diff --git a/packages/compiler-sfc/src/parseComponent.ts b/packages/compiler-sfc/src/parseComponent.ts index 65b858c9fc0..05489280e63 100644 --- a/packages/compiler-sfc/src/parseComponent.ts +++ b/packages/compiler-sfc/src/parseComponent.ts @@ -179,11 +179,11 @@ export function parseComponent( let text = source.slice(currentBlock.start, currentBlock.end) if ( options.deindent === true || - // by default, deindent unless it's script with default lang or ts + // by default, deindent unless it's script with default lang or (j/t)sx? (options.deindent !== false && !( currentBlock.type === 'script' && - (!currentBlock.lang || currentBlock.lang === 'ts') + (!currentBlock.lang || /^(j|t)sx?$/.test(currentBlock.lang)) )) ) { text = deindent(text) diff --git a/packages/compiler-sfc/src/rewriteDefault.ts b/packages/compiler-sfc/src/rewriteDefault.ts index ced9f56d8a9..e61cf691bba 100644 --- a/packages/compiler-sfc/src/rewriteDefault.ts +++ b/packages/compiler-sfc/src/rewriteDefault.ts @@ -42,7 +42,12 @@ export function rewriteDefault( }).program.body ast.forEach(node => { if (node.type === 'ExportDefaultDeclaration') { - s.overwrite(node.start!, node.declaration.start!, `const ${as} = `) + if (node.declaration.type === 'ClassDeclaration') { + s.overwrite(node.start!, node.declaration.id.start!, `class `) + s.append(`\nconst ${as} = ${node.declaration.id.name}`) + } else { + s.overwrite(node.start!, node.declaration.start!, `const ${as} = `) + } } if (node.type === 'ExportNamedDeclaration') { for (const specifier of node.specifiers) { diff --git a/packages/compiler-sfc/src/templateCompilerModules/utils.ts b/packages/compiler-sfc/src/templateCompilerModules/utils.ts index 3e635b00207..8a2d19c6ce7 100644 --- a/packages/compiler-sfc/src/templateCompilerModules/utils.ts +++ b/packages/compiler-sfc/src/templateCompilerModules/utils.ts @@ -24,10 +24,15 @@ export function urlToRequire( // does not apply to absolute urls or urls that start with `@` // since they are aliases if (firstChar === '.' || firstChar === '~') { + // Allow for full hostnames provided in options.base + const base = parseUriParts(transformAssetUrlsOption.base) + const protocol = base.protocol || '' + const host = base.host ? protocol + '//' + base.host : '' + const basePath = base.path || '/' // when packaged in the browser, path will be using the posix- // only version provided by rollup-plugin-node-builtins. - return `"${(path.posix || path).join( - transformAssetUrlsOption.base, + return `"${host}${(path.posix || path).join( + basePath, uriParts.path + (uriParts.hash || '') )}"` } @@ -64,7 +69,7 @@ function parseUriParts(urlString: string): UrlWithStringQuery { // @see https://nodejs.org/api/url.html#url_url_parse_urlstring_parsequerystring_slashesdenotehost if ('string' === typeof urlString) { // check is an uri - return uriParse(urlString) // take apart the uri + return uriParse(urlString, false, true) // take apart the uri } } return returnValue diff --git a/packages/compiler-sfc/test/rewriteDefault.spec.ts b/packages/compiler-sfc/test/rewriteDefault.spec.ts new file mode 100644 index 00000000000..9fb4c64bbb3 --- /dev/null +++ b/packages/compiler-sfc/test/rewriteDefault.spec.ts @@ -0,0 +1,245 @@ +import { rewriteDefault } from '../src' + +describe('compiler sfc: rewriteDefault', () => { + test('without export default', () => { + expect(rewriteDefault(`export a = {}`, 'script')).toMatchInlineSnapshot(` + "export a = {} + const script = {}" + `) + }) + + test('rewrite export default', () => { + expect( + rewriteDefault(`export default {}`, 'script') + ).toMatchInlineSnapshot(`"const script = {}"`) + }) + + test('rewrite export named default', () => { + expect( + rewriteDefault( + `const a = 1 \n export { a as b, a as default, a as c}`, + 'script' + ) + ).toMatchInlineSnapshot(` + "const a = 1 + export { a as b, a as c} + const script = a" + `) + + expect( + rewriteDefault( + `const a = 1 \n export { a as b, a as default , a as c}`, + 'script' + ) + ).toMatchInlineSnapshot(` + "const a = 1 + export { a as b, a as c} + const script = a" + `) + }) + + test('w/ comments', async () => { + expect(rewriteDefault(`// export default\nexport default {}`, 'script')) + .toMatchInlineSnapshot(` + "// export default + const script = {}" + `) + }) + + test('export named default multiline', () => { + expect( + rewriteDefault(`let App = {}\n export {\nApp as default\n}`, '_sfc_main') + ).toMatchInlineSnapshot(` + "let App = {} + export { + + } + const _sfc_main = App" + `) + }) + + test('export named default multiline /w comments', () => { + expect( + rewriteDefault( + `const a = 1 \n export {\n a as b,\n a as default,\n a as c}\n` + + `// export { myFunction as default }`, + 'script' + ) + ).toMatchInlineSnapshot(` + "const a = 1 + export { + a as b, + + a as c} + // export { myFunction as default } + const script = a" + `) + + expect( + rewriteDefault( + `const a = 1 \n export {\n a as b,\n a as default ,\n a as c}\n` + + `// export { myFunction as default }`, + 'script' + ) + ).toMatchInlineSnapshot(` + "const a = 1 + export { + a as b, + + a as c} + // export { myFunction as default } + const script = a" + `) + }) + + test(`export { default } from '...'`, async () => { + expect( + rewriteDefault(`export { default, foo } from './index.js'`, 'script') + ).toMatchInlineSnapshot(` + "import { default as __VUE_DEFAULT__ } from './index.js' + export { foo } from './index.js' + const script = __VUE_DEFAULT__" + `) + + expect( + rewriteDefault(`export { default , foo } from './index.js'`, 'script') + ).toMatchInlineSnapshot(` + "import { default as __VUE_DEFAULT__ } from './index.js' + export { foo } from './index.js' + const script = __VUE_DEFAULT__" + `) + + expect( + rewriteDefault(`export { foo, default } from './index.js'`, 'script') + ).toMatchInlineSnapshot(` + "import { default as __VUE_DEFAULT__ } from './index.js' + export { foo, } from './index.js' + const script = __VUE_DEFAULT__" + `) + + expect( + rewriteDefault( + `export { foo as default, bar } from './index.js'`, + 'script' + ) + ).toMatchInlineSnapshot(` + "import { foo } from './index.js' + export { bar } from './index.js' + const script = foo" + `) + + expect( + rewriteDefault( + `export { foo as default , bar } from './index.js'`, + 'script' + ) + ).toMatchInlineSnapshot(` + "import { foo } from './index.js' + export { bar } from './index.js' + const script = foo" + `) + + expect( + rewriteDefault( + `export { bar, foo as default } from './index.js'`, + 'script' + ) + ).toMatchInlineSnapshot(` + "import { foo } from './index.js' + export { bar, } from './index.js' + const script = foo" + `) + }) + + test('export default class', async () => { + expect(rewriteDefault(`export default class Foo {}`, 'script')) + .toMatchInlineSnapshot(` + "class Foo {} + const script = Foo" + `) + }) + + test('export default class w/ comments', async () => { + expect( + rewriteDefault(`// export default\nexport default class Foo {}`, 'script') + ).toMatchInlineSnapshot(` + "// export default + class Foo {} + const script = Foo" + `) + }) + + test('export default class w/ comments 2', async () => { + expect( + rewriteDefault( + `export default {}\n` + `// export default class Foo {}`, + 'script' + ) + ).toMatchInlineSnapshot(` + "const script = {} + // export default class Foo {}" + `) + }) + + test('export default class w/ comments 3', async () => { + expect( + rewriteDefault( + `/*\nexport default class Foo {}*/\n` + `export default class Bar {}`, + 'script' + ) + ).toMatchInlineSnapshot(` + "/* + export default class Foo {}*/ + class Bar {} + const script = Bar" + `) + }) + + test('@Component\nexport default class', async () => { + expect(rewriteDefault(`@Component\nexport default class Foo {}`, 'script')) + .toMatchInlineSnapshot(` + "@Component + class Foo {} + const script = Foo" + `) + }) + + test('@Component\nexport default class w/ comments', async () => { + expect( + rewriteDefault(`// export default\n@Component\nexport default class Foo {}`, 'script') + ).toMatchInlineSnapshot(` + "// export default + @Component + class Foo {} + const script = Foo" + `) + }) + + test('@Component\nexport default class w/ comments 2', async () => { + expect( + rewriteDefault( + `export default {}\n` + `// @Component\n// export default class Foo {}`, + 'script' + ) + ).toMatchInlineSnapshot(` + "const script = {} + // @Component + // export default class Foo {}" + `) + }) + + test('@Component\nexport default class w/ comments 3', async () => { + expect( + rewriteDefault( + `/*\n@Component\nexport default class Foo {}*/\n` + `export default class Bar {}`, + 'script' + ) + ).toMatchInlineSnapshot(` + "/* + @Component + export default class Foo {}*/ + class Bar {} + const script = Bar" + `) + }) +}) diff --git a/packages/server-renderer/package.json b/packages/server-renderer/package.json index 5e8adfd83f6..5470ebfaca3 100644 --- a/packages/server-renderer/package.json +++ b/packages/server-renderer/package.json @@ -1,6 +1,6 @@ { "name": "vue-server-renderer", - "version": "2.7.8", + "version": "2.7.10", "description": "server renderer for Vue 2.0", "main": "index.js", "types": "types/index.d.ts", diff --git a/packages/server-renderer/src/render.ts b/packages/server-renderer/src/render.ts index 907b795d797..b1116840ed5 100644 --- a/packages/server-renderer/src/render.ts +++ b/packages/server-renderer/src/render.ts @@ -206,6 +206,11 @@ function renderComponentInner(node, isRoot, context) { type: 'Component', prevActive }) + if (isDef(node.data) && isDef(node.data.directives)) { + childNode.data = childNode.data || {} + childNode.data.directives = node.data.directives + childNode.isComponentRootElement = true + } renderNode(childNode, isRoot, context) } @@ -372,7 +377,10 @@ function renderStartingTag(node: VNode, context) { if (dirRenderer) { // directives mutate the node's data // which then gets rendered by modules - dirRenderer(node, dirs[i]) + dirRenderer( + node.isComponentRootElement ? node.parent : node, + dirs[i] + ) } } } diff --git a/packages/server-renderer/test/ssr-string.spec.ts b/packages/server-renderer/test/ssr-string.spec.ts index 35810c8ed58..391671c1e52 100644 --- a/packages/server-renderer/test/ssr-string.spec.ts +++ b/packages/server-renderer/test/ssr-string.spec.ts @@ -1086,7 +1086,7 @@ describe('SSR: renderToString', () => { ) }) - it('custom directives', done => { + it('custom directives on raw element', done => { const renderer = createRenderer({ directives: { 'class-prefixer': (node, dir) => { @@ -1129,6 +1129,98 @@ describe('SSR: renderToString', () => { ) }) + it('custom directives on component', done => { + const Test = { + template: 'hello world' + } + const renderer = createRenderer({ + directives: { + 'class-prefixer': (node, dir) => { + if (node.data.class) { + node.data.class = `${dir.value}-${node.data.class}` + } + if (node.data.staticClass) { + node.data.staticClass = `${dir.value}-${node.data.staticClass}` + } + } + } + }) + renderer.renderToString( + new Vue({ + template: + '
hello world
' + ) + done() + } + ) + }) + + it('custom directives on element root of a component', done => { + const Test = { + template: + 'hello world' + } + const renderer = createRenderer({ + directives: { + 'class-prefixer': (node, dir) => { + if (node.data.class) { + node.data.class = `${dir.value}-${node.data.class}` + } + if (node.data.staticClass) { + node.data.staticClass = `${dir.value}-${node.data.staticClass}` + } + } + } + }) + renderer.renderToString( + new Vue({ + template: 'hello world
' + ) + done() + } + ) + }) + + it('custom directives on element with parent element', done => { + const renderer = createRenderer({ + directives: { + 'class-prefixer': (node, dir) => { + if (node.data.class) { + node.data.class = `${dir.value}-${node.data.class}` + } + if (node.data.staticClass) { + node.data.staticClass = `${dir.value}-${node.data.staticClass}` + } + } + } + }) + renderer.renderToString( + new Vue({ + template: + 'hello world
' + }), + (err, result) => { + expect(err).toBeNull() + expect(result).toContain( + 'hello world
' + ) + done() + } + ) + }) + it('should not warn for custom directives that do not have server-side implementation', done => { renderToString( new Vue({ diff --git a/packages/template-compiler/package.json b/packages/template-compiler/package.json index d1be678cdfb..75285bc0e85 100644 --- a/packages/template-compiler/package.json +++ b/packages/template-compiler/package.json @@ -1,6 +1,6 @@ { "name": "vue-template-compiler", - "version": "2.7.8", + "version": "2.7.10", "description": "template compiler for Vue 2.0", "main": "index.js", "unpkg": "browser.js", diff --git a/src/core/instance/init.ts b/src/core/instance/init.ts index 876c9ddbf96..91456c21920 100644 --- a/src/core/instance/init.ts +++ b/src/core/instance/init.ts @@ -34,6 +34,7 @@ export function initMixin(Vue: typeof Component) { vm.__v_skip = true // effect scope vm._scope = new EffectScope(true /* detached */) + vm._scope._vm = true // merge options if (options && options._isComponent) { // optimize internal component instantiation diff --git a/src/core/instance/lifecycle.ts b/src/core/instance/lifecycle.ts index df70b7113fd..94f42e27eb5 100644 --- a/src/core/instance/lifecycle.ts +++ b/src/core/instance/lifecycle.ts @@ -83,8 +83,15 @@ export function lifecycleMixin(Vue: typeof Component) { vm.$el.__vue__ = vm } // if parent is an HOC, update its $el as well - if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) { - vm.$parent.$el = vm.$el + let wrapper: Component | undefined = vm + while ( + wrapper && + wrapper.$vnode && + wrapper.$parent && + wrapper.$vnode === wrapper.$parent._vnode + ) { + wrapper.$parent.$el = wrapper.$el + wrapper = wrapper.$parent } // updated hook is called by the scheduler to ensure that children are // updated in a parent's updated hook. diff --git a/src/core/instance/proxy.ts b/src/core/instance/proxy.ts index 3543d74954a..685d9651fcc 100644 --- a/src/core/instance/proxy.ts +++ b/src/core/instance/proxy.ts @@ -19,7 +19,7 @@ if (__DEV__) { 'referenced during render. Make sure that this property is reactive, ' + 'either in the data option, or for class-based components, by ' + 'initializing the property. ' + - 'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.', + 'See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.', target ) } @@ -29,7 +29,7 @@ if (__DEV__) { `Property "${key}" must be accessed with "$data.${key}" because ` + 'properties starting with "$" or "_" are not proxied in the Vue instance to ' + 'prevent conflicts with Vue internals. ' + - 'See: https://vuejs.org/v2/api/#data', + 'See: https://v2.vuejs.org/v2/api/#data', target ) } diff --git a/src/core/instance/state.ts b/src/core/instance/state.ts index e22ec6705fb..aedb72555c9 100644 --- a/src/core/instance/state.ts +++ b/src/core/instance/state.ts @@ -127,7 +127,7 @@ function initData(vm: Component) { __DEV__ && warn( 'data functions should return an object:\n' + - 'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function', + 'https://v2.vuejs.org/v2/guide/components.html#data-Must-Be-a-Function', vm ) } diff --git a/src/core/observer/watcher.ts b/src/core/observer/watcher.ts index b1f491acb33..b2989b53772 100644 --- a/src/core/observer/watcher.ts +++ b/src/core/observer/watcher.ts @@ -71,11 +71,18 @@ export default class Watcher implements DepTarget { options?: WatcherOptions | null, isRenderWatcher?: boolean ) { - recordEffectScope(this, activeEffectScope || (vm ? vm._scope : undefined)) - if ((this.vm = vm)) { - if (isRenderWatcher) { - vm._watcher = this - } + recordEffectScope( + this, + // if the active effect scope is manually created (not a component scope), + // prioritize it + activeEffectScope && !activeEffectScope._vm + ? activeEffectScope + : vm + ? vm._scope + : undefined + ) + if ((this.vm = vm) && isRenderWatcher) { + vm._watcher = this } // options if (options) { diff --git a/src/core/vdom/modules/directives.ts b/src/core/vdom/modules/directives.ts index 9e4a87f7f6e..853b20021e7 100644 --- a/src/core/vdom/modules/directives.ts +++ b/src/core/vdom/modules/directives.ts @@ -103,7 +103,15 @@ function normalizeDirectives( } res[getRawDirName(dir)] = dir if (vm._setupState && vm._setupState.__sfc) { - dir.def = dir.def || resolveAsset(vm, '_setupState', 'v-' + dir.name) + const setupDef = dir.def || resolveAsset(vm, '_setupState', 'v-' + dir.name) + if (typeof setupDef === 'function') { + dir.def = { + bind: setupDef, + update: setupDef, + } + } else { + dir.def = setupDef + } } dir.def = dir.def || resolveAsset(vm.$options, 'directives', dir.name, true) } diff --git a/src/core/vdom/vnode.ts b/src/core/vdom/vnode.ts index 80f784167ba..3b57f9aca0c 100644 --- a/src/core/vdom/vnode.ts +++ b/src/core/vdom/vnode.ts @@ -33,6 +33,7 @@ export default class VNode { fnOptions?: ComponentOptions | null // for SSR caching devtoolsMeta?: Object | null // used to store functional render context for devtools fnScopeId?: string | null // functional scope id support + isComponentRootElement?: boolean | null // for SSR directives constructor( tag?: string, diff --git a/src/v3/apiLifecycle.ts b/src/v3/apiLifecycle.ts index dc47bc4652b..31e0542920c 100644 --- a/src/v3/apiLifecycle.ts +++ b/src/v3/apiLifecycle.ts @@ -42,7 +42,6 @@ export const onBeforeUpdate = createLifeCycle('beforeUpdate') export const onUpdated = createLifeCycle('updated') export const onBeforeUnmount = createLifeCycle('beforeDestroy') export const onUnmounted = createLifeCycle('destroyed') -export const onErrorCaptured = createLifeCycle('errorCaptured') export const onActivated = createLifeCycle('activated') export const onDeactivated = createLifeCycle('deactivated') export const onServerPrefetch = createLifeCycle('serverPrefetch') @@ -51,3 +50,19 @@ export const onRenderTracked = createLifeCycle<(e: DebuggerEvent) => any>('renderTracked') export const onRenderTriggered = createLifeCycle<(e: DebuggerEvent) => any>('renderTriggered') + +export type ErrorCapturedHook