Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: vuejs/core
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v3.4.10
Choose a base ref
...
head repository: vuejs/core
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v3.4.11
Choose a head ref
  • 5 commits
  • 24 files changed
  • 4 contributors

Commits on Jan 12, 2024

  1. Copy the full SHA
    08b60f5 View commit details
  2. Copy the full SHA
    8d04205 View commit details
  3. Copy the full SHA
    d35b877 View commit details
  4. Copy the full SHA
    c604791 View commit details
  5. release: v3.4.11

    yyx990803 committed Jan 12, 2024
    Copy the full SHA
    fd337dd View commit details
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## [3.4.11](https://github.com/vuejs/core/compare/v3.4.10...v3.4.11) (2024-01-12)


### Bug Fixes

* **hydration:** improve mismatch when client valut is null or undefined ([#10086](https://github.com/vuejs/core/issues/10086)) ([08b60f5](https://github.com/vuejs/core/commit/08b60f5d0d5b57fcf3347ef66cbeab472c475a88))
* **reactivity:** correct dirty assign in render function ([#10091](https://github.com/vuejs/core/issues/10091)) ([8d04205](https://github.com/vuejs/core/commit/8d042050411fdf04d9d1d6c153287164b12e0255)), closes [#10082](https://github.com/vuejs/core/issues/10082)
* **runtime-core:** filter single root for nested DEV_ROOT_FRAGMENT ([#8593](https://github.com/vuejs/core/issues/8593)) ([d35b877](https://github.com/vuejs/core/commit/d35b87725ab3e2bdc86fb5781ab34939f7ec1029)), closes [#5203](https://github.com/vuejs/core/issues/5203) [#8581](https://github.com/vuejs/core/issues/8581) [#10087](https://github.com/vuejs/core/issues/10087)



## [3.4.10](https://github.com/vuejs/core/compare/v3.4.9...v3.4.10) (2024-01-11)


2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"private": true,
"version": "3.4.10",
"version": "3.4.11",
"packageManager": "pnpm@8.14.0",
"type": "module",
"scripts": {
2 changes: 1 addition & 1 deletion packages/compiler-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue/compiler-core",
"version": "3.4.10",
"version": "3.4.11",
"description": "@vue/compiler-core",
"main": "index.js",
"module": "dist/compiler-core.esm-bundler.js",
2 changes: 1 addition & 1 deletion packages/compiler-core/src/babelUtils.ts
Original file line number Diff line number Diff line change
@@ -50,7 +50,7 @@ export function walkIdentifiers(
}
} else if (
node.type === 'ObjectProperty' &&
parent!.type === 'ObjectPattern'
parent?.type === 'ObjectPattern'
) {
// mark property in destructure pattern
;(node as any).inPattern = true
2 changes: 1 addition & 1 deletion packages/compiler-dom/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue/compiler-dom",
"version": "3.4.10",
"version": "3.4.11",
"description": "@vue/compiler-dom",
"main": "index.js",
"module": "dist/compiler-dom.esm-bundler.js",
32 changes: 32 additions & 0 deletions packages/compiler-sfc/__tests__/compileScript.spec.ts
Original file line number Diff line number Diff line change
@@ -953,6 +953,38 @@ describe('SFC compile <script setup>', () => {
</script>`).content,
)
})

test('defineModel() referencing local var', () => {
expect(() =>
compile(`<script setup>
let bar = 1
defineModel({
default: () => bar
})
</script>`),
).toThrow(`cannot reference locally declared variables`)

// allow const
expect(() =>
compile(`<script setup>
const bar = 1
defineModel({
default: () => bar
})
</script>`),
).not.toThrow(`cannot reference locally declared variables`)

// allow in get/set
expect(() =>
compile(`<script setup>
let bar = 1
defineModel({
get: () => bar,
set: () => bar
})
</script>`),
).not.toThrow(`cannot reference locally declared variables`)
})
})
})

2 changes: 1 addition & 1 deletion packages/compiler-sfc/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue/compiler-sfc",
"version": "3.4.10",
"version": "3.4.11",
"description": "@vue/compiler-sfc",
"main": "dist/compiler-sfc.cjs.js",
"module": "dist/compiler-sfc.esm-browser.js",
5 changes: 5 additions & 0 deletions packages/compiler-sfc/src/compileScript.ts
Original file line number Diff line number Diff line change
@@ -671,6 +671,11 @@ export function compileScript(
checkInvalidScopeReference(ctx.propsDestructureDecl, DEFINE_PROPS)
checkInvalidScopeReference(ctx.emitsRuntimeDecl, DEFINE_EMITS)
checkInvalidScopeReference(ctx.optionsRuntimeDecl, DEFINE_OPTIONS)
for (const { runtimeOptionNodes } of Object.values(ctx.modelDecls)) {
for (const node of runtimeOptionNodes) {
checkInvalidScopeReference(node, DEFINE_MODEL)
}
}

// 5. remove non-script content
if (script) {
5 changes: 5 additions & 0 deletions packages/compiler-sfc/src/script/defineModel.ts
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@ export interface ModelDecl {
type: TSType | undefined
options: string | undefined
identifier: string | undefined
runtimeOptionNodes: Node[]
}

export function processDefineModel(
@@ -48,6 +49,7 @@ export function processDefineModel(

let optionsString = options && ctx.getString(options)
let optionsRemoved = !options
const runtimeOptionNodes: Node[] = []

if (
options &&
@@ -75,6 +77,8 @@ export function processDefineModel(
// remove prop options from runtime options
removed++
ctx.s.remove(ctx.startOffset! + start, ctx.startOffset! + end)
// record prop options for invalid scope var reference check
runtimeOptionNodes.push(p)
}
}
if (removed === options.properties.length) {
@@ -89,6 +93,7 @@ export function processDefineModel(
ctx.modelDecls[modelName] = {
type,
options: optionsString,
runtimeOptionNodes,
identifier:
declId && declId.type === 'Identifier' ? declId.name : undefined,
}
2 changes: 1 addition & 1 deletion packages/compiler-ssr/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue/compiler-ssr",
"version": "3.4.10",
"version": "3.4.11",
"description": "@vue/compiler-ssr",
"main": "dist/compiler-ssr.cjs.js",
"types": "dist/compiler-ssr.d.ts",
32 changes: 32 additions & 0 deletions packages/reactivity/__tests__/effect.spec.ts
Original file line number Diff line number Diff line change
@@ -3,16 +3,19 @@ import {
type ReactiveEffectRunner,
TrackOpTypes,
TriggerOpTypes,
computed,
effect,
markRaw,
reactive,
readonly,
ref,
shallowReactive,
stop,
toRaw,
} from '../src/index'
import { pauseScheduling, resetScheduling } from '../src/effect'
import { ITERATE_KEY, getDepFromReactive } from '../src/reactiveEffect'
import { h, nextTick, nodeOps, render, serialize } from '@vue/runtime-test'

describe('reactivity/effect', () => {
it('should run the passed function once (wrapped by a effect)', () => {
@@ -1011,6 +1014,35 @@ describe('reactivity/effect', () => {
expect(counterSpy).toHaveBeenCalledTimes(1)
})

// #10082
it('should set dirtyLevel when effect is allowRecurse and is running', async () => {
const s = ref(0)
const n = computed(() => s.value + 1)

const Child = {
setup() {
s.value++
return () => n.value
},
}

const renderSpy = vi.fn()
const Parent = {
setup() {
return () => {
renderSpy()
return [n.value, h(Child)]
}
},
}

const root = nodeOps.createElement('div')
render(h(Parent), root)
await nextTick()
expect(serialize(root)).toBe('<div>22</div>')
expect(renderSpy).toHaveBeenCalledTimes(2)
})

describe('empty dep cleanup', () => {
it('should remove the dep when the effect is stopped', () => {
const obj = reactive({ prop: 1 })
2 changes: 1 addition & 1 deletion packages/reactivity/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue/reactivity",
"version": "3.4.10",
"version": "3.4.11",
"description": "@vue/reactivity",
"main": "index.js",
"module": "dist/reactivity.esm-bundler.js",
4 changes: 3 additions & 1 deletion packages/reactivity/src/effect.ts
Original file line number Diff line number Diff line change
@@ -295,7 +295,9 @@ export function triggerEffects(
}
if (
effect._dirtyLevel < dirtyLevel &&
(!effect._runnings || dirtyLevel !== DirtyLevels.ComputedValueDirty)
(!effect._runnings ||
effect.allowRecurse ||
dirtyLevel !== DirtyLevels.ComputedValueDirty)
) {
const lastDirtyLevel = effect._dirtyLevel
effect._dirtyLevel = dirtyLevel
10 changes: 10 additions & 0 deletions packages/runtime-core/__tests__/hydration.spec.ts
Original file line number Diff line number Diff line change
@@ -1512,6 +1512,16 @@ describe('SSR hydration', () => {
expect(`Hydration attribute mismatch`).not.toHaveBeenWarned()
})

test('client value is null or undefined', () => {
mountWithHydration(`<div></div>`, () =>
h('div', { draggable: undefined }),
)
expect(`Hydration attribute mismatch`).not.toHaveBeenWarned()

mountWithHydration(`<input />`, () => h('input', { type: null }))
expect(`Hydration attribute mismatch`).not.toHaveBeenWarned()
})

test('should not warn against object values', () => {
mountWithHydration(`<input />`, () => h('input', { from: {} }))
expect(`Hydration attribute mismatch`).not.toHaveBeenWarned()
54 changes: 54 additions & 0 deletions packages/runtime-core/__tests__/rendererAttrsFallthrough.spec.ts
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@ import {
type FunctionalComponent,
createBlock,
createCommentVNode,
createElementBlock,
createElementVNode,
defineComponent,
h,
mergeProps,
@@ -673,6 +675,58 @@ describe('attribute fallthrough', () => {
expect(click).toHaveBeenCalled()
})

it('should support fallthrough for nested dev root fragments', async () => {
const toggle = ref(false)

const Child = {
setup() {
return () => (
openBlock(),
createElementBlock(
Fragment,
null,
[
createCommentVNode(' comment A '),
toggle.value
? (openBlock(), createElementBlock('span', { key: 0 }, 'Foo'))
: (openBlock(),
createElementBlock(
Fragment,
{ key: 1 },
[
createCommentVNode(' comment B '),
createElementVNode('div', null, 'Bar'),
],
PatchFlags.STABLE_FRAGMENT | PatchFlags.DEV_ROOT_FRAGMENT,
)),
],
PatchFlags.STABLE_FRAGMENT | PatchFlags.DEV_ROOT_FRAGMENT,
)
)
},
}

const Root = {
setup() {
return () => (openBlock(), createBlock(Child, { class: 'red' }))
},
}

const root = document.createElement('div')
document.body.appendChild(root)
render(h(Root), root)

expect(root.innerHTML).toBe(
`<!-- comment A --><!-- comment B --><div class="red">Bar</div>`,
)

toggle.value = true
await nextTick()
expect(root.innerHTML).toBe(
`<!-- comment A --><span class=\"red\">Foo</span>`,
)
})

// #1989
it('should not fallthrough v-model listeners with corresponding declared prop', () => {
let textFoo = ''
58 changes: 58 additions & 0 deletions packages/runtime-core/__tests__/scopeId.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
import {
Fragment,
createBlock,
createCommentVNode,
createVNode,
defineComponent,
h,
nextTick,
nodeOps,
openBlock,
popScopeId,
pushScopeId,
ref,
render,
renderSlot,
serializeInner,
withScopeId,
} from '@vue/runtime-test'
import { withCtx } from '../src/componentRenderContext'
import { PatchFlags } from '@vue/shared'

describe('scopeId runtime support', () => {
test('should attach scopeId', () => {
@@ -184,6 +193,55 @@ describe('scopeId runtime support', () => {

expect(serializeInner(root)).toBe(`<div parent></div>`)
})

test('should inherit scopeId through nested DEV_ROOT_FRAGMENT with inheritAttrs: false', async () => {
const Parent = {
__scopeId: 'parent',
render() {
return h(Child, { class: 'foo' })
},
}

const ok = ref(true)
const Child = defineComponent({
inheritAttrs: false,
render() {
return (
openBlock(),
createBlock(
Fragment,
null,
[
createCommentVNode('comment1'),
ok.value
? (openBlock(), createBlock('div', { key: 0 }, 'div1'))
: (openBlock(),
createBlock(
Fragment,
{ key: 1 },
[
createCommentVNode('comment2'),
createVNode('div', null, 'div2'),
],
PatchFlags.STABLE_FRAGMENT | PatchFlags.DEV_ROOT_FRAGMENT,
)),
],
PatchFlags.STABLE_FRAGMENT | PatchFlags.DEV_ROOT_FRAGMENT,
)
)
},
})

const root = nodeOps.createElement('div')
render(h(Parent), root)
expect(serializeInner(root)).toBe(`<!--comment1--><div parent>div1</div>`)

ok.value = false
await nextTick()
expect(serializeInner(root)).toBe(
`<!--comment1--><!--comment2--><div parent>div2</div>`,
)
})
})

describe('backwards compat with <=3.0.7', () => {
2 changes: 1 addition & 1 deletion packages/runtime-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue/runtime-core",
"version": "3.4.10",
"version": "3.4.11",
"description": "@vue/runtime-core",
"main": "index.js",
"module": "dist/runtime-core.esm-bundler.js",
Loading