Merge branch 'minor' into edison/feat/fowardedSlots
ci / test (push) Waiting to run Details
ci / continuous-release (push) Waiting to run Details

This commit is contained in:
edison 2025-07-21 21:07:02 +08:00 committed by GitHub
commit f5a8fc50aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 283 additions and 144 deletions

View File

@ -1,3 +1,20 @@
# [3.6.0-alpha.2](https://github.com/vuejs/core/compare/v3.6.0-alpha.1...v3.6.0-alpha.2) (2025-07-18)
### Bug Fixes
* **compiler-vapor:** handle empty interpolation ([#13592](https://github.com/vuejs/core/issues/13592)) ([d1f2915](https://github.com/vuejs/core/commit/d1f2915cfe7915fa73624485ff3dd443176a31a9))
* **compiler-vapor:** handle special characters in cached variable names ([#13626](https://github.com/vuejs/core/issues/13626)) ([a5e106d](https://github.com/vuejs/core/commit/a5e106d96eb17d73c8673e826393c910d5594a2f))
* **compiler-vapor:** selectors was not initialized in time when the initial value of createFor source was not empty ([#13642](https://github.com/vuejs/core/issues/13642)) ([f04c9c3](https://github.com/vuejs/core/commit/f04c9c342d398c11111c873143dc437f588578ee))
* **reactivity:** allow collect effects in EffectScope ([#13657](https://github.com/vuejs/core/issues/13657)) ([b9fb79a](https://github.com/vuejs/core/commit/b9fb79a1fd099b67e01c5fe5941551c0da3a0cae)), closes [#13656](https://github.com/vuejs/core/issues/13656)
* **reactivity:** remove link check to align with 3.5 ([#13654](https://github.com/vuejs/core/issues/13654)) ([3cb27d1](https://github.com/vuejs/core/commit/3cb27d156f6a30e8f950616a53a3726519eaf216)), closes [#13620](https://github.com/vuejs/core/issues/13620)
* **runtime-core:** use __vapor instead of vapor to identify Vapor components ([#13652](https://github.com/vuejs/core/issues/13652)) ([ad21b1b](https://github.com/vuejs/core/commit/ad21b1b7e96bc894f5df0d95fbd77c9ba6b15c2e))
* **runtime-vapor:** component emits vdom interop ([#13498](https://github.com/vuejs/core/issues/13498)) ([d95fc18](https://github.com/vuejs/core/commit/d95fc186c26e81345cd75037c3c1304b0eae13b4))
* **runtime-vapor:** handle v-model vdom interop error ([#13643](https://github.com/vuejs/core/issues/13643)) ([2be828a](https://github.com/vuejs/core/commit/2be828a0c165c7f1533ace0bd81fba43a2af16d6))
* **runtime-vapor:** remove access globalProperties warning ([#13609](https://github.com/vuejs/core/issues/13609)) ([fca74b0](https://github.com/vuejs/core/commit/fca74b00a86c6039aa05591618539a77aaa72daf))
# [3.6.0-alpha.1](https://github.com/vuejs/core/compare/v3.5.17...v3.6.0-alpha.1) (2025-07-12)
### Features

View File

@ -1,6 +1,6 @@
{
"private": true,
"version": "3.6.0-alpha.1",
"version": "3.6.0-alpha.2",
"packageManager": "pnpm@10.12.4",
"type": "module",
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "@vue/compiler-core",
"version": "3.6.0-alpha.1",
"version": "3.6.0-alpha.2",
"description": "@vue/compiler-core",
"main": "index.js",
"module": "dist/compiler-core.esm-bundler.js",

View File

@ -1,6 +1,6 @@
{
"name": "@vue/compiler-dom",
"version": "3.6.0-alpha.1",
"version": "3.6.0-alpha.2",
"description": "@vue/compiler-dom",
"main": "index.js",
"module": "dist/compiler-dom.esm-bundler.js",

View File

@ -1,6 +1,6 @@
{
"name": "@vue/compiler-sfc",
"version": "3.6.0-alpha.1",
"version": "3.6.0-alpha.2",
"description": "@vue/compiler-sfc",
"main": "dist/compiler-sfc.cjs.js",
"module": "dist/compiler-sfc.esm-browser.js",

View File

@ -1,6 +1,6 @@
{
"name": "@vue/compiler-ssr",
"version": "3.6.0-alpha.1",
"version": "3.6.0-alpha.2",
"description": "@vue/compiler-ssr",
"main": "dist/compiler-ssr.cjs.js",
"types": "dist/compiler-ssr.d.ts",

View File

@ -11,6 +11,53 @@ export function render(_ctx) {
}"
`;
exports[`compiler: expression > empty interpolation 1`] = `
"import { template as _template } from 'vue';
const t0 = _template(" ")
export function render(_ctx) {
const n0 = t0()
return n0
}"
`;
exports[`compiler: expression > empty interpolation 2`] = `
"import { template as _template } from 'vue';
const t0 = _template(" ")
export function render(_ctx) {
const n0 = t0()
return n0
}"
`;
exports[`compiler: expression > empty interpolation 3`] = `
"import { template as _template } from 'vue';
const t0 = _template("<div></div>", true)
export function render(_ctx) {
const n0 = t0()
return n0
}"
`;
exports[`compiler: expression > empty interpolation 4`] = `
"import { child as _child, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("<div> </div>", true)
export function render(_ctx) {
const n1 = t0()
const n0 = _child(n1)
const x1 = _child(n1)
_renderEffect(() => {
const _foo = _ctx.foo
_setText(n0, _toDisplayString(_foo))
_setText(x1, _toDisplayString(_foo))
})
return n1
}"
`;
exports[`compiler: expression > props 1`] = `
"import { toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template(" ")

View File

@ -43,7 +43,7 @@ export function render(_ctx) {
const n2 = t0()
_setTemplateRef(n2, "foo", void 0, true)
return n2
}, null, 4)
}, undefined, 4)
return n0
}"
`;

View File

@ -93,7 +93,7 @@ export function render(_ctx) {
const x4 = _child(n4)
_renderEffect(() => _setText(x4, _toDisplayString(_for_item1.value+_for_item0.value)))
return n4
}, null, 1)
}, undefined, 1)
return n5
})
return n0
@ -150,6 +150,7 @@ exports[`compiler: v-for > selector pattern 1`] = `
const t0 = _template("<tr> </tr>", true)
export function render(_ctx) {
let _selector0_0
const n0 = _createFor(() => (_ctx.rows), (_for_item0) => {
const n2 = t0()
const x2 = _child(n2)
@ -157,8 +158,9 @@ export function render(_ctx) {
_setText(x2, _toDisplayString(_ctx.selected === _for_item0.value.id ? 'danger' : ''))
})
return n2
}, (row) => (row.id))
const _selector0_0 = n0.useSelector(() => _ctx.selected)
}, (row) => (row.id), undefined, ({ createSelector }) => {
_selector0_0 = createSelector(() => _ctx.selected)
})
return n0
}"
`;
@ -168,14 +170,16 @@ exports[`compiler: v-for > selector pattern 2`] = `
const t0 = _template("<tr></tr>", true)
export function render(_ctx) {
let _selector0_0
const n0 = _createFor(() => (_ctx.rows), (_for_item0) => {
const n2 = t0()
_selector0_0(() => {
_setClass(n2, _ctx.selected === _for_item0.value.id ? 'danger' : '')
})
return n2
}, (row) => (row.id))
const _selector0_0 = n0.useSelector(() => _ctx.selected)
}, (row) => (row.id), undefined, ({ createSelector }) => {
_selector0_0 = createSelector(() => _ctx.selected)
})
return n0
}"
`;
@ -202,14 +206,16 @@ exports[`compiler: v-for > selector pattern 4`] = `
const t0 = _template("<tr></tr>", true)
export function render(_ctx) {
let _selector0_0
const n0 = _createFor(() => (_ctx.rows), (_for_item0) => {
const n2 = t0()
_selector0_0(() => {
_setClass(n2, { danger: _for_item0.value.id === _ctx.selected })
})
return n2
}, (row) => (row.id))
const _selector0_0 = n0.useSelector(() => _ctx.selected)
}, (row) => (row.id), undefined, ({ createSelector }) => {
_selector0_0 = createSelector(() => _ctx.selected)
})
return n0
}"
`;

View File

@ -12,6 +12,21 @@ export function render(_ctx) {
}"
`;
exports[`v-on > component event with special characters 1`] = `
"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback } from 'vue';
export function render(_ctx) {
const _component_Foo = _resolveComponent("Foo")
const _on_update_model = () => {}
const _on_update_model1 = () => {}
const n0 = _createComponentWithFallback(_component_Foo, {
"onUpdate:model": () => _on_update_model,
"onUpdate-model": () => _on_update_model1
}, null, true)
return n0
}"
`;
exports[`v-on > dynamic arg 1`] = `
"import { on as _on, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("<div></div>", true)

View File

@ -68,7 +68,7 @@ export function render(_ctx) {
const n0 = _createFor(() => (_ctx.list), (_for_item0) => {
const n2 = t0()
return n2
}, null, 4)
}, undefined, 4)
return n0
}"
`;

View File

@ -47,4 +47,25 @@ describe('compiler: expression', () => {
expect(code).toMatchSnapshot()
expect(code).contains(`_String(_foo.id++)`)
})
test('empty interpolation', () => {
const { code } = compileWithExpression(`{{}}`)
const { code: code2 } = compileWithExpression(`{{ }}`)
const { code: code3 } = compileWithExpression(`<div>{{ }}</div>`)
const { code: code4 } = compileWithExpression(`<div>{{ foo }}{{ }}</div>`)
expect(code).toMatchSnapshot()
expect(code).not.toContain(`_toDisplayString`)
expect(code).not.toContain(`_setText`)
expect(code2).toMatchSnapshot()
expect(code2).not.toContain(`_toDisplayString`)
expect(code2).not.toContain(`_setText`)
expect(code3).toMatchSnapshot()
expect(code3).not.toContain(`_toDisplayString`)
expect(code3).not.toContain(`_setText`)
expect(code4).toMatchSnapshot()
})
})

View File

@ -695,4 +695,16 @@ describe('v-on', () => {
expect(code).matchSnapshot()
expect(code).include('n0.$evtclick = e => _ctx.handleClick(e)')
})
test('component event with special characters', () => {
const { code } = compileWithVOn(
`<Foo @update:model="() => {}" @update-model="() => {}" />`,
)
expect(code).matchSnapshot()
expect(code).contains('const _on_update_model = () => {}')
expect(code).contains('const _on_update_model1 = () => {}')
expect(code).contains('"onUpdate:model": () => _on_update_model')
expect(code).contains('"onUpdate-model": () => _on_update_model1')
})
})

View File

@ -1,6 +1,6 @@
{
"name": "@vue/compiler-vapor",
"version": "3.6.0-alpha.1",
"version": "3.6.0-alpha.2",
"description": "@vue/compiler-vapor",
"main": "dist/compiler-vapor.cjs.js",
"module": "dist/compiler-vapor.esm-bundler.js",

View File

@ -26,7 +26,7 @@ import {
genCall,
genMulti,
} from './utils'
import { genExpression } from './expression'
import { genExpression, genVarName } from './expression'
import { genPropKey, genPropValue } from './prop'
import {
type SimpleExpressionNode,
@ -102,6 +102,7 @@ export function genCreateComponent(
function getUniqueHandlerName(context: CodegenContext, name: string): string {
const { seenInlineHandlerNames } = context
name = genVarName(name)
const count = seenInlineHandlerNames[name] || 0
seenInlineHandlerNames[name] = count + 1
return count === 0 ? name : `${name}${count}`

View File

@ -647,7 +647,7 @@ function parseExp(context: CodegenContext, content: string): Node {
return parseExpression(`(${content})`, options)
}
function genVarName(exp: string): string {
export function genVarName(exp: string): string {
return `${exp
.replace(/[^a-zA-Z0-9]/g, '_')
.replace(/_+/g, '_')

View File

@ -99,19 +99,27 @@ export function genFor(
keyProp,
idMap,
)
const patternFrag: CodeFragment[] = []
const selectorDeclarations: CodeFragment[] = []
const selectorSetup: CodeFragment[] = []
for (let i = 0; i < selectorPatterns.length; i++) {
const { selector } = selectorPatterns[i]
const selectorName = `_selector${id}_${i}`
patternFrag.push(
selectorDeclarations.push(`let ${selectorName}`, NEWLINE)
if (i === 0) {
selectorSetup.push(`({ createSelector }) => {`, INDENT_START)
}
selectorSetup.push(
NEWLINE,
`const ${selectorName} = `,
...genCall(`n${id}.useSelector`, [
`${selectorName} = `,
...genCall(`createSelector`, [
`() => `,
...genExpression(selector, context),
]),
)
if (i === selectorPatterns.length - 1) {
selectorSetup.push(INDENT_END, NEWLINE, '}')
}
}
const blockFn = context.withId(() => {
@ -165,16 +173,17 @@ export function genFor(
return [
NEWLINE,
...selectorDeclarations,
`const n${id} = `,
...genCall(
helper('createFor'),
[helper('createFor'), 'undefined'],
sourceExpr,
blockFn,
genCallback(keyProp),
flags ? String(flags) : undefined,
selectorSetup.length ? selectorSetup : undefined,
// todo: hydrationNode
),
...patternFrag,
]
// construct a id -> accessor path map.

View File

@ -87,7 +87,8 @@ export const transformText: NodeTransform = (node, context) => {
}
function processInterpolation(context: TransformContext<InterpolationNode>) {
const children = context.parent!.node.children
const parentNode = context.parent!.node
const children = parentNode.children
const nexts = children.slice(context.index)
const idx = nexts.findIndex(n => !isTextLike(n))
const nodes = (idx > -1 ? nexts.slice(0, idx) : nexts) as Array<TextLike>
@ -97,10 +98,18 @@ function processInterpolation(context: TransformContext<InterpolationNode>) {
if (prev && prev.type === NodeTypes.TEXT) {
nodes.unshift(prev)
}
const values = processTextLikeChildren(nodes, context)
if (values.length === 0 && parentNode.type !== NodeTypes.ROOT) {
return
}
context.template += ' '
const id = context.reference()
const values = nodes.map(node => createTextLikeExpression(node, context))
if (values.length === 0) {
return
}
const nonConstantExps = values.filter(v => !isConstantExpression(v))
const isStatic =
@ -129,8 +138,10 @@ function processTextContainer(
children: TextLike[],
context: TransformContext<ElementNode>,
) {
const values = children.map(child => createTextLikeExpression(child, context))
const values = processTextLikeChildren(children, context)
const literals = values.map(getLiteralExpressionValue)
if (literals.every(l => l != null)) {
context.childrenTemplate = literals.map(l => String(l))
} else {
@ -149,13 +160,22 @@ function processTextContainer(
}
}
function createTextLikeExpression(node: TextLike, context: TransformContext) {
markNonTemplate(node, context)
if (node.type === NodeTypes.TEXT) {
return createSimpleExpression(node.content, true, node.loc)
} else {
return node.content as SimpleExpressionNode
function processTextLikeChildren(nodes: TextLike[], context: TransformContext) {
const exps: SimpleExpressionNode[] = []
for (const node of nodes) {
let exp: SimpleExpressionNode
markNonTemplate(node, context)
if (node.type === NodeTypes.TEXT) {
exp = createSimpleExpression(node.content, true, node.loc)
} else {
exp = node.content as SimpleExpressionNode
}
if (exp.content) exps.push(exp)
}
return exps
}
function isTextLike(node: TemplateChildNode): node is TextLike {

View File

@ -1,6 +1,6 @@
{
"name": "@vue/reactivity",
"version": "3.6.0-alpha.1",
"version": "3.6.0-alpha.2",
"description": "@vue/reactivity",
"main": "index.js",
"module": "dist/reactivity.esm-bundler.js",

View File

@ -1,11 +1,5 @@
import { EffectFlags, cleanup } from './effect'
import {
type Link,
type ReactiveNode,
link,
setActiveSub,
unlink,
} from './system'
import { type Link, type ReactiveNode, link, unlink } from './system'
import { warn } from './warning'
export let activeEffectScope: EffectScope | undefined
@ -65,14 +59,12 @@ export class EffectScope implements ReactiveNode {
}
run<T>(fn: () => T): T | undefined {
const prevSub = setActiveSub()
const prevScope = activeEffectScope
try {
activeEffectScope = this
return fn()
} finally {
activeEffectScope = prevScope
setActiveSub(prevSub)
}
}

View File

@ -77,14 +77,8 @@ export function link(dep: ReactiveNode, sub: ReactiveNode): void {
return
}
}
// TODO: maybe can find a good way to check duplicate link
const prevSub = dep.subsTail
if (
prevSub !== undefined &&
prevSub.sub === sub &&
(!recursedCheck || isValidLink(prevSub, sub))
) {
return
}
const newLink =
(sub.depsTail =
dep.subsTail =

View File

@ -1,6 +1,6 @@
{
"name": "@vue/runtime-core",
"version": "3.6.0-alpha.1",
"version": "3.6.0-alpha.2",
"description": "@vue/runtime-core",
"main": "index.js",
"module": "dist/runtime-core.esm-bundler.js",

View File

@ -119,7 +119,7 @@ function reload(id: string, newComp: HMRComponent): void {
// create a snapshot which avoids the set being mutated during updates
const instances = [...record.instances]
if (newComp.vapor) {
if (newComp.__vapor) {
for (const instance of instances) {
instance.hmrReload!(newComp)
}

View File

@ -1,6 +1,6 @@
{
"name": "@vue/runtime-dom",
"version": "3.6.0-alpha.1",
"version": "3.6.0-alpha.2",
"description": "@vue/runtime-dom",
"main": "index.js",
"module": "dist/runtime-dom.esm-bundler.js",

View File

@ -1,12 +1,11 @@
import { ref } from '@vue/reactivity'
import { makeRender } from './_utils'
// @ts-expect-error
import { createFor, createSelector, renderEffect } from '../src'
import { createFor } from '../src'
import { nextTick } from '@vue/runtime-dom'
const define = makeRender()
describe.todo('api: createSelector', () => {
describe('api: createSelector', () => {
test('basic', async () => {
let calledTimes = 0
let expectedCalledTimes = 0
@ -15,19 +14,23 @@ describe.todo('api: createSelector', () => {
const index = ref(0)
const { host } = define(() => {
const isSleected = createSelector(index)
let selector: (cb: () => void) => void
return createFor(
() => list.value,
item => {
const span = document.createElement('li')
renderEffect(() => {
selector(() => {
calledTimes += 1
const { id } = item.value
span.textContent = `${id}.${isSleected(id) ? 't' : 'f'}`
span.textContent = `${id}.${id === index.value ? 't' : 'f'}`
})
return span
},
item => item.id,
undefined,
({ createSelector }) => {
selector = createSelector(() => index.value)
},
)
}).render()
@ -50,66 +53,11 @@ describe.todo('api: createSelector', () => {
)
expect(calledTimes).toBe((expectedCalledTimes += 2))
list.value[2].id = 3
await nextTick()
expect(host.innerHTML).toBe(
'<li>0.f</li><li>1.f</li><li>3.f</li><!--for-->',
)
expect(calledTimes).toBe((expectedCalledTimes += 1))
})
test('custom compare', async () => {
let calledTimes = 0
let expectedCalledTimes = 0
const list = ref([{ id: 1 }, { id: 2 }, { id: 3 }])
const index = ref(0)
const { host } = define(() => {
const isSleected = createSelector(
index,
// @ts-expect-error
(key, value) => key === value + 1,
)
return createFor(
() => list.value,
item => {
const span = document.createElement('li')
renderEffect(() => {
calledTimes += 1
const { id } = item.value
span.textContent = `${id}.${isSleected(id) ? 't' : 'f'}`
})
return span
},
item => item.id,
)
}).render()
expect(host.innerHTML).toBe(
'<li>1.t</li><li>2.f</li><li>3.f</li><!--for-->',
)
expect(calledTimes).toBe((expectedCalledTimes += 3))
index.value = 1
await nextTick()
expect(host.innerHTML).toBe(
'<li>1.f</li><li>2.t</li><li>3.f</li><!--for-->',
)
expect(calledTimes).toBe((expectedCalledTimes += 2))
index.value = 2
await nextTick()
expect(host.innerHTML).toBe(
'<li>1.f</li><li>2.f</li><li>3.t</li><!--for-->',
)
expect(calledTimes).toBe((expectedCalledTimes += 2))
list.value[2].id = 4
await nextTick()
expect(host.innerHTML).toBe(
'<li>1.f</li><li>2.f</li><li>4.f</li><!--for-->',
)
expect(calledTimes).toBe((expectedCalledTimes += 1))
// list.value[2].id = 3
// await nextTick()
// expect(host.innerHTML).toBe(
// '<li>0.f</li><li>1.f</li><li>3.f</li><!--for-->',
// )
// expect(calledTimes).toBe((expectedCalledTimes += 1))
})
})

View File

@ -341,7 +341,7 @@ describe('api: createVaporApp', () => {
})
})
test('config.globalProperty', () => {
test.todo('config.globalProperty', () => {
const { app } = define({
setup() {
return []
@ -351,7 +351,7 @@ describe('api: createVaporApp', () => {
app.config.globalProperties.msg = 'hello world'
} catch (e) {}
expect(
`app.config.globalProperties is not supported in vapor mode`,
`app.config.globalProperties is not supported in vapor mode components`,
).toHaveBeenWarned()
})
})

View File

@ -1,6 +1,23 @@
import { createVNode, defineComponent, h, renderSlot } from '@vue/runtime-dom'
import {
createVNode,
defineComponent,
h,
nextTick,
ref,
renderSlot,
toDisplayString,
useModel,
} from '@vue/runtime-dom'
import { makeInteropRender } from './_utils'
import { createComponent, defineVaporComponent } from '../src'
import {
applyTextModel,
child,
createComponent,
defineVaporComponent,
renderEffect,
setText,
template,
} from '../src'
const define = makeInteropRender()
@ -26,6 +43,54 @@ describe('vdomInterop', () => {
})
})
describe('v-model', () => {
test('basic work', async () => {
const VaporChild = defineVaporComponent({
props: {
modelValue: {},
modelModifiers: {},
},
emits: ['update:modelValue'],
setup(__props) {
const modelValue = useModel(__props, 'modelValue')
const n0 = template('<h1> </h1>')() as any
const n1 = template('<input>')() as any
const x0 = child(n0) as any
applyTextModel(
n1,
() => modelValue.value,
_value => (modelValue.value = _value),
)
renderEffect(() => setText(x0, toDisplayString(modelValue.value)))
return [n0, n1]
},
})
const { html, host } = define({
setup() {
const msg = ref('foo')
return () =>
h(VaporChild as any, {
modelValue: msg.value,
'onUpdate:modelValue': (value: string) => {
msg.value = value
},
})
},
}).render()
expect(html()).toBe('<h1>foo</h1><input>')
const inputEl = host.querySelector('input')!
inputEl.value = 'bar'
inputEl.dispatchEvent(new Event('input'))
await nextTick()
expect(html()).toBe('<h1>bar</h1><input>')
})
})
describe('emit', () => {
test('emit from vapor child to vdom parent', () => {
const VaporChild = defineVaporComponent({

View File

@ -1,6 +1,6 @@
{
"name": "@vue/runtime-vapor",
"version": "3.6.0-alpha.1",
"version": "3.6.0-alpha.2",
"description": "@vue/runtime-vapor",
"main": "index.js",
"module": "dist/runtime-vapor.esm-bundler.js",

View File

@ -88,18 +88,6 @@ function prepareApp() {
}
function postPrepareApp(app: App) {
if (__DEV__) {
app.config.globalProperties = new Proxy(
{},
{
set() {
warn(`app.config.globalProperties is not supported in vapor mode.`)
return false
},
},
)
}
app.vapor = true
const mount = app.mount
app.mount = (container, ...args: any[]) => {

View File

@ -74,6 +74,9 @@ export const createFor = (
) => Block,
getKey?: (item: any, key: any, index?: number) => any,
flags = 0,
setup?: (_: {
createSelector: (source: () => any) => (cb: () => void) => void
}) => void,
): VaporFragment => {
const _insertionParent = insertionParent
const _insertionAnchor = insertionAnchor
@ -402,6 +405,10 @@ export const createFor = (
}
}
if (setup) {
setup({ createSelector })
}
if (flags & VaporVForFlags.ONCE) {
renderList()
} else {
@ -412,12 +419,9 @@ export const createFor = (
insert(frag, _insertionParent, _insertionAnchor)
}
// @ts-expect-error
frag.useSelector = useSelector
return frag
function useSelector(source: () => any): (key: any, cb: () => void) => void {
function createSelector(source: () => any): (cb: () => void) => void {
let operMap = new Map<any, (() => void)[]>()
let activeKey = source()
let activeOpers: (() => void)[] | undefined

View File

@ -1,6 +1,6 @@
{
"name": "@vue/server-renderer",
"version": "3.6.0-alpha.1",
"version": "3.6.0-alpha.2",
"description": "@vue/server-renderer",
"main": "index.js",
"module": "dist/server-renderer.esm-bundler.js",

View File

@ -1,6 +1,6 @@
{
"name": "@vue/shared",
"version": "3.6.0-alpha.1",
"version": "3.6.0-alpha.2",
"description": "internal utils shared across @vue packages",
"main": "index.js",
"module": "dist/shared.esm-bundler.js",

View File

@ -1,6 +1,6 @@
{
"name": "@vue/compat",
"version": "3.6.0-alpha.1",
"version": "3.6.0-alpha.2",
"description": "Vue 3 compatibility build for Vue 2",
"main": "index.js",
"module": "dist/vue.runtime.esm-bundler.js",

View File

@ -1,6 +1,6 @@
{
"name": "vue",
"version": "3.6.0-alpha.1",
"version": "3.6.0-alpha.2",
"description": "The progressive JavaScript framework for building modern web UI.",
"main": "index.js",
"module": "dist/vue.runtime.esm-bundler.js",