( {fooRef.value = el as HTMLElement}} />)
+
expectType(
{
diff --git a/types/vnode.d.ts b/types/vnode.d.ts
index 7a543f0a39b..29bdb398c1c 100644
--- a/types/vnode.d.ts
+++ b/types/vnode.d.ts
@@ -1,5 +1,7 @@
import { Vue } from './vue'
import { DirectiveFunction, DirectiveOptions } from './options'
+import { Ref } from './v3-generated'
+import { ComponentPublicInstance } from './v3-component-public-instance'
/**
* For extending allowed non-declared props on components in TSX
@@ -65,11 +67,19 @@ export interface VNodeComponentOptions {
tag?: string
}
+export type VNodeRef =
+ | string
+ | Ref
+ | ((
+ ref: Element | ComponentPublicInstance | null,
+ refs: Record
+ ) => void)
+
export interface VNodeData {
key?: string | number
slot?: string
scopedSlots?: { [key: string]: ScopedSlot | undefined }
- ref?: string
+ ref?: VNodeRef
refInFor?: boolean
tag?: string
staticClass?: string
From fb1393009660b38046b1f6dfb532b481cc53b3b7 Mon Sep 17 00:00:00 2001
From: Evan You
Date: Tue, 11 Oct 2022 14:09:10 +0800
Subject: [PATCH 08/15] fix(sfc): prune returned bindings for non-TS as well
In Vue 3, pruning is only done for TS to produce valid code and
tree-shaking is done by inlining the template for production.
In Vue 2 we do not inline the template in production, so return binding
pruning is needed in all cases.
fix #12765
---
packages/compiler-sfc/src/compileScript.ts | 36 +++++++++----------
.../__snapshots__/compileScript.spec.ts.snap | 2 +-
2 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts
index 094120c38f7..7d171a9b78a 100644
--- a/packages/compiler-sfc/src/compileScript.ts
+++ b/packages/compiler-sfc/src/compileScript.ts
@@ -284,11 +284,9 @@ export function compileScript(
userImportAlias[imported] = local
}
- // template usage check is only needed in non-inline mode, so we can skip
- // the work if inlineTemplate is true.
let isUsedInTemplate = true
- if (isTS && sfc.template && !sfc.template.src && !sfc.template.lang) {
- isUsedInTemplate = isImportUsed(local, sfc)
+ if (sfc.template && !sfc.template.src && !sfc.template.lang) {
+ isUsedInTemplate = isImportUsed(local, sfc, isTS)
}
userImports[local] = {
@@ -1782,7 +1780,7 @@ function getObjectOrArrayExpressionKeys(value: Node): string[] {
const templateUsageCheckCache = new LRU(512)
-function resolveTemplateUsageCheckString(sfc: SFCDescriptor) {
+function resolveTemplateUsageCheckString(sfc: SFCDescriptor, isTS: boolean) {
const { content } = sfc.template!
const cached = templateUsageCheckCache.get(content)
if (cached) {
@@ -1809,7 +1807,7 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) {
code += `,v${capitalize(camelize(baseName))}`
}
if (value) {
- code += `,${processExp(value, baseName)}`
+ code += `,${processExp(value, isTS, baseName)}`
}
}
}
@@ -1817,7 +1815,7 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) {
chars(text) {
const res = parseText(text)
if (res) {
- code += `,${processExp(res.expression)}`
+ code += `,${processExp(res.expression, isTS)}`
}
}
})
@@ -1829,8 +1827,8 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) {
const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/
-function processExp(exp: string, dir?: string): string {
- if (/ as\s+\w|<.*>|:/.test(exp)) {
+function processExp(exp: string, isTS: boolean, dir?: string): string {
+ if (isTS && / as\s+\w|<.*>|:/.test(exp)) {
if (dir === 'slot') {
exp = `(${exp})=>{}`
} else if (dir === 'on') {
@@ -1839,7 +1837,7 @@ function processExp(exp: string, dir?: string): string {
const inMatch = exp.match(forAliasRE)
if (inMatch) {
const [, LHS, RHS] = inMatch
- return processExp(`(${LHS})=>{}`) + processExp(RHS)
+ return processExp(`(${LHS})=>{}`, true) + processExp(RHS, true)
}
}
let ret = ''
@@ -1867,36 +1865,38 @@ function stripTemplateString(str: string): string {
return ''
}
-function isImportUsed(local: string, sfc: SFCDescriptor): boolean {
+function isImportUsed(
+ local: string,
+ sfc: SFCDescriptor,
+ isTS: boolean
+): boolean {
return new RegExp(
// #4274 escape $ since it's a special char in regex
// (and is the only regex special char that is valid in identifiers)
`[^\\w$_]${local.replace(/\$/g, '\\$')}[^\\w$_]`
- ).test(resolveTemplateUsageCheckString(sfc))
+ ).test(resolveTemplateUsageCheckString(sfc, isTS))
}
/**
* Note: this comparison assumes the prev/next script are already identical,
- * and only checks the special case where