diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 7bda056185..21f32de041 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -24,7 +24,7 @@ If yes, please describe the impact and migration path for existing applications:
**The PR fulfills these requirements:**
-- [ ] It's submitted to the `dev` branch for v2.x (or to a previous version branch), _not_ the `master` branch
+- [ ] It's submitted to the `main` branch for v2.x (or to a previous version branch)
- [ ] When resolving a specific issue, it's referenced in the PR's title (e.g. `fix #xxx[,#xxx]`, where "xxx" is the issue number)
- [ ] All tests are passing: https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md#development-setup
- [ ] New/updated tests are included
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4c75474b8d..05577cb11d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,16 @@
+## [2.7.14](https://github.com/vuejs/vue/compare/v2.7.13...v2.7.14) (2022-11-09)
+
+
+### Bug Fixes
+
+* **compiler-sfc:** fix template usage check edge case for v-slot destructured default value ([#12842](https://github.com/vuejs/vue/issues/12842)) ([5e3d4e9](https://github.com/vuejs/vue/commit/5e3d4e90cdf92ec0a72bbb2bd44125f1faafae1d)), closes [#12841](https://github.com/vuejs/vue/issues/12841)
+* **provide/inject:** do not mutate original provide options during merge ([d1899ca](https://github.com/vuejs/vue/commit/d1899caf688de961e63e7a0d56f806fc4a12efd9)), closes [#12854](https://github.com/vuejs/vue/issues/12854)
+* **reactivity:** avoid using WeakMap for IE compatibility ([29b5f58](https://github.com/vuejs/vue/commit/29b5f588032600baae9854ac9a4105916a5aa648)), closes [#12837](https://github.com/vuejs/vue/issues/12837)
+* **types:** fix spreading VNodeData in tsx ([#12789](https://github.com/vuejs/vue/issues/12789)) ([f7db7f3](https://github.com/vuejs/vue/commit/f7db7f361b6356591781b9f33abbb0d5b7f9b97c)), closes [#12778](https://github.com/vuejs/vue/issues/12778)
+* **types:** stricter type condition for `EventHandlers` ([#12840](https://github.com/vuejs/vue/issues/12840)) ([0b3cf7d](https://github.com/vuejs/vue/commit/0b3cf7dda9ac605b2b9f799acacd2793e974f225)), closes [#12832](https://github.com/vuejs/vue/issues/12832)
+
+
+
## [2.7.13](https://github.com/vuejs/vue/compare/v2.7.12...v2.7.13) (2022-10-14)
@@ -888,7 +901,7 @@ In addition:
- **compiler:** wrap scoped slots v-if conditions in parens ([#9119](https://github.com/vuejs/vue/issues/9119)) ([ef8524a](https://github.com/vuejs/vue/commit/ef8524ab7db8d64ac449ce74f5858aa9d91357ad)), closes [#9114](https://github.com/vuejs/vue/issues/9114)
- **compiler:** maybeComponent should return true when "is" attribute exists ([#8114](https://github.com/vuejs/vue/issues/8114)) ([aef2a5f](https://github.com/vuejs/vue/commit/aef2a5f3dbd5e52ec9d5ce026d7b858539057186)), closes [#8101](https://github.com/vuejs/vue/issues/8101)
- **compiler:** normalize potential functional component children in v-for ([#8558](https://github.com/vuejs/vue/issues/8558)) ([d483a49](https://github.com/vuejs/vue/commit/d483a49c86874b2e75863b661f81feecd46ae721)), closes [#8468](https://github.com/vuejs/vue/issues/8468)
-- **compiler:** should keep newline after unary tags in
([#8965](https://github.com/vuejs/vue/issues/8965)) ([05001e6](https://github.com/vuejs/vue/commit/05001e695ebd0b0504d664197a4771463a0f5328)), closes [#8950](https://github.com/vuejs/vue/issues/8950)
+- **compiler:** should keep newline after unary tags in `` ([#8965](https://github.com/vuejs/vue/issues/8965)) ([05001e6](https://github.com/vuejs/vue/commit/05001e695ebd0b0504d664197a4771463a0f5328)), closes [#8950](https://github.com/vuejs/vue/issues/8950)
- **compiler:** templates inside v-pre should be rendered to HTML ([#8146](https://github.com/vuejs/vue/issues/8146)) ([ecac831](https://github.com/vuejs/vue/commit/ecac831691d27cf7a10ec73a004d3fbad7623d1a)), closes [#8041](https://github.com/vuejs/vue/issues/8041)
- **component:** clean up memory leak after loading async component completes (fix [#8740](https://github.com/vuejs/vue/issues/8740)) ([#8755](https://github.com/vuejs/vue/issues/8755)) ([2e472c5](https://github.com/vuejs/vue/commit/2e472c5e5e559a7a4083b4164ffe0c3911ce0651))
- **core:** avoid mutating original children when cloning vnode ([097f622](https://github.com/vuejs/vue/commit/097f6229dffc34af452b106ad2a3b58845588807)), closes [#7975](https://github.com/vuejs/vue/issues/7975)
@@ -1176,7 +1189,7 @@ In addition:
- properly mark slot rendered flag in production mode ([4fe1a95](https://github.com/vuejs/vue/commit/4fe1a95d2953ecf765e27677fa70ebadb176d4c3)), closes [#6997](https://github.com/vuejs/vue/issues/6997)
- **slots:** properly handle nested named slot passing ([5a9da95](https://github.com/vuejs/vue/commit/5a9da95b8a865416f082952a48416ffc091e4078)), closes [#6996](https://github.com/vuejs/vue/issues/6996)
- special case for static muted attribute in firefox ([f2e00f7](https://github.com/vuejs/vue/commit/f2e00f756fb540fb09ce3414289c652ce172d85c)), closes [#6887](https://github.com/vuejs/vue/issues/6887)
-- **ssr:** properly render initial state ([e1657fd](https://github.com/vuejs/vue/commit/e1657fd7ce49bff3c3ecad3c56ae527347505c34)), closes [#6986](https://github.com/vuejs/vue/issues/6986)
+- **ssr:** properly render `` initial state ([e1657fd](https://github.com/vuejs/vue/commit/e1657fd7ce49bff3c3ecad3c56ae527347505c34)), closes [#6986](https://github.com/vuejs/vue/issues/6986)
- **ssr:** properly render textarea value ([79c0d7b](https://github.com/vuejs/vue/commit/79c0d7bcfbcd1ac492e7ceb77f5024d09efdc6b3)), closes [#6986](https://github.com/vuejs/vue/issues/6986)
- **ssr:** should not optimize root if conditions ([4ad9a56](https://github.com/vuejs/vue/commit/4ad9a56b229b156e633f3d575cd0e99ba5e474d9)), closes [#6907](https://github.com/vuejs/vue/issues/6907)
- **types:** improve typing for better completion ([#6886](https://github.com/vuejs/vue/issues/6886)) ([98ea0a3](https://github.com/vuejs/vue/commit/98ea0a3b48e37719f278c10a8ee5fb94d7d5db4e))
@@ -1213,14 +1226,14 @@ In addition:
- fallback to Promise in non-DOM environments ([6d1f4cb](https://github.com/vuejs/vue/commit/6d1f4cb89a156bf5f84942b1031354aa93916cb7))
- fix scoped CSS for nested nodes in functional components ([4216588](https://github.com/vuejs/vue/commit/421658884f7ca786747abf9b89e00925fdfdfba8))
- handle errors in errorHandler ([2b5c83a](https://github.com/vuejs/vue/commit/2b5c83af6d8b15510424af4877d58c261ea02e16)), closes [#6714](https://github.com/vuejs/vue/issues/6714)
-- perperly handle v-if on scoped slot ([68bdbf5](https://github.com/vuejs/vue/commit/68bdbf508b915872627676d6bf987bdac9e5fe97)), closes [#6725](https://github.com/vuejs/vue/issues/6725)
+- properly handle v-if on `` scoped slot ([68bdbf5](https://github.com/vuejs/vue/commit/68bdbf508b915872627676d6bf987bdac9e5fe97)), closes [#6725](https://github.com/vuejs/vue/issues/6725)
- prevent memory leak due to circular reference in vnodes ([405d8e9](https://github.com/vuejs/vue/commit/405d8e9f4c3201db2ae0e397d9191d9b94edc219)), closes [#6759](https://github.com/vuejs/vue/issues/6759)
-- properly render value on in IE/Edge ([c64f9ae](https://github.com/vuejs/vue/commit/c64f9ae1649175ee8cac1c7ecf3283897c948202)), closes [#6666](https://github.com/vuejs/vue/issues/6666)
+- properly render value on `` in IE/Edge ([c64f9ae](https://github.com/vuejs/vue/commit/c64f9ae1649175ee8cac1c7ecf3283897c948202)), closes [#6666](https://github.com/vuejs/vue/issues/6666)
- **ref:** preserve ref on components after removing root element ([#6718](https://github.com/vuejs/vue/issues/6718)) ([6ad44e1](https://github.com/vuejs/vue/commit/6ad44e13e990951ff152a0fd7042613c5a87f1c0)), closes [#6632](https://github.com/vuejs/vue/issues/6632) [#6641](https://github.com/vuejs/vue/issues/6641)
- resolve async component default for native dynamic import ([2876ed8](https://github.com/vuejs/vue/commit/2876ed870c5368a1767fbeddf06e94b55ebd6234)), closes [#6751](https://github.com/vuejs/vue/issues/6751)
- **ssr:** fix hydration mismatch with adjacent text node from slots ([b080a14](https://github.com/vuejs/vue/commit/b080a14138262f0f274d0888555a11bd7387d576)), closes [vuejs/vue-loader#974](https://github.com/vuejs/vue-loader/issues/974)
- **ssr:** handle inline template compilation error ([dff85b2](https://github.com/vuejs/vue/commit/dff85b230abda63839ed6b80d56ccfc6068b9ae0)), closes [#6766](https://github.com/vuejs/vue/issues/6766)
-- use correct ns inside as root node ([cf1ff5b](https://github.com/vuejs/vue/commit/cf1ff5b0dc3d15c1e16821cb5e4fc984c74f07c1)), closes [#6642](https://github.com/vuejs/vue/issues/6642)
+- use correct ns inside `` as root node ([cf1ff5b](https://github.com/vuejs/vue/commit/cf1ff5b0dc3d15c1e16821cb5e4fc984c74f07c1)), closes [#6642](https://github.com/vuejs/vue/issues/6642)
- use MessageChannel for nextTick ([6e41679](https://github.com/vuejs/vue/commit/6e41679a96582da3e0a60bdbf123c33ba0e86b31)), closes [#6566](https://github.com/vuejs/vue/issues/6566) [#6690](https://github.com/vuejs/vue/issues/6690)
- warn slot-scope when used as a prop ([8295f71](https://github.com/vuejs/vue/commit/8295f716657ffe516f30e84f29ca94f4a0aefabf))
- work around old Chrome bug ([0f2cb09](https://github.com/vuejs/vue/commit/0f2cb09444e8b2a5fa41aaf8c94e6f2f43e00c2f)), closes [#6601](https://github.com/vuejs/vue/issues/6601)
@@ -1271,12 +1284,12 @@ In addition:
- do not use MutationObserver in IE11 ([844a540](https://github.com/vuejs/vue/commit/844a540c647dfa93dc714540953524830dd3475a)), closes [#6466](https://github.com/vuejs/vue/issues/6466)
- ensure $attrs and $listeners are always objects ([#6441](https://github.com/vuejs/vue/issues/6441)) ([59dbd4a](https://github.com/vuejs/vue/commit/59dbd4a414394a3ce581f9fbd9554da9af9e4b1d)), closes [#6263](https://github.com/vuejs/vue/issues/6263)
- ensure outer bindings on nested HOC are properly re-applied on inner root element change ([a744497](https://github.com/vuejs/vue/commit/a7444975343f7828004d90bfb0deeb98db0f46e7))
-- handle special case for allowfullscreen on ([d77b953](https://github.com/vuejs/vue/commit/d77b95317cedae299605fb692e2c7c67796b17cb)), closes [#6202](https://github.com/vuejs/vue/issues/6202)
+- handle special case for allowfullscreen on `` ([d77b953](https://github.com/vuejs/vue/commit/d77b95317cedae299605fb692e2c7c67796b17cb)), closes [#6202](https://github.com/vuejs/vue/issues/6202)
- inherit SVG ns on component root node ([#6511](https://github.com/vuejs/vue/issues/6511)) ([89f0d29](https://github.com/vuejs/vue/commit/89f0d29f2d541aa5a1ac9690258cd7c7ee576ef6)), closes [#6506](https://github.com/vuejs/vue/issues/6506)
- **inject:** exclude not enumerable keys of inject object ([#6346](https://github.com/vuejs/vue/issues/6346)) ([3ee62fd](https://github.com/vuejs/vue/commit/3ee62fd59e20030dd63c08c2390e803d034928fe)), closes [#6574](https://github.com/vuejs/vue/issues/6574)
- preserve slot attribute if not resolved by Vue ([684cd7d](https://github.com/vuejs/vue/commit/684cd7d21aa7cb9a40fb4a8542c4e08fb3801a86)), closes [#6553](https://github.com/vuejs/vue/issues/6553)
- **provide:** provide should default to parentVal during merging ([#6473](https://github.com/vuejs/vue/issues/6473)) ([3c21675](https://github.com/vuejs/vue/commit/3c216755f6eb656c6d864265a8dc7b51b3ae971b)), closes [#6436](https://github.com/vuejs/vue/issues/6436)
-- set value as domProp for ([7116af4](https://github.com/vuejs/vue/commit/7116af4e07520040ed7328c39d0a456808bfe1e1)), closes [#6561](https://github.com/vuejs/vue/issues/6561)
+- set value as domProp for `` ([7116af4](https://github.com/vuejs/vue/commit/7116af4e07520040ed7328c39d0a456808bfe1e1)), closes [#6561](https://github.com/vuejs/vue/issues/6561)
- **ssr:** address possible xss vector ([5091e2c](https://github.com/vuejs/vue/commit/5091e2c9847601e329ac36d17eae90bb5cb77a91))
- **ssr:** better handle v-html hydration ([0f00f8f](https://github.com/vuejs/vue/commit/0f00f8fc2b83b964bb929b729a7c9e3675b52106)), closes [#6519](https://github.com/vuejs/vue/issues/6519)
- **ssr:** expose context.styles when no lifecycle styles are injected ([1f52a2a](https://github.com/vuejs/vue/commit/1f52a2a9f433452c15715131ed74433a43d5cfb7)), closes [#6353](https://github.com/vuejs/vue/issues/6353)
@@ -1319,12 +1332,12 @@ In addition:
- **compile:** properly generate comments with special character ([#6156](https://github.com/vuejs/vue/issues/6156)) ([d03fa26](https://github.com/vuejs/vue/commit/d03fa26687605a43d9a0c3f395d1d32375f7eaee)), closes [#6150](https://github.com/vuejs/vue/issues/6150)
- ensure looseEqual is not dependant on key enumeration order ([a8ac129](https://github.com/vuejs/vue/commit/a8ac129a5876a7eeae0137bf2f1b0968d4d6ffad)), closes [#5908](https://github.com/vuejs/vue/issues/5908)
- include boolean in isPrimitive check ([#6127](https://github.com/vuejs/vue/issues/6127)) ([be3dc9c](https://github.com/vuejs/vue/commit/be3dc9c6e923248bcf81eb8240dd4f3c168fac59)), closes [#6126](https://github.com/vuejs/vue/issues/6126)
-- **parser:** only ignore the first newline in ([082fc39](https://github.com/vuejs/vue/commit/082fc3967db4d3290e901a38504dcd9bb698e561)), closes [#6146](https://github.com/vuejs/vue/issues/6146)
+- **parser:** only ignore the first newline in `` ([082fc39](https://github.com/vuejs/vue/commit/082fc3967db4d3290e901a38504dcd9bb698e561)), closes [#6146](https://github.com/vuejs/vue/issues/6146)
- **provide/inject:** merge provide properly from mixins ([3036551](https://github.com/vuejs/vue/commit/303655116f8ec78f3b0ac99569637ad868dfe246)), closes [#6175](https://github.com/vuejs/vue/issues/6175)
- **provide/inject:** resolve inject properly from mixins ([#6107](https://github.com/vuejs/vue/issues/6107)) ([b0f00e3](https://github.com/vuejs/vue/commit/b0f00e31e7d06edfdc733e2e7f24d5ca448759f9)), closes [#6093](https://github.com/vuejs/vue/issues/6093)
- **transition:** should trigger transition hooks for v-show in ie9 ([9b4dbba](https://github.com/vuejs/vue/commit/9b4dbba384bc81a99abe429476729f80cb06d19a)), closes [#5525](https://github.com/vuejs/vue/issues/5525)
- **v-bind:** respect .prop modifier on components ([#6159](https://github.com/vuejs/vue/issues/6159)) ([06b9b0b](https://github.com/vuejs/vue/commit/06b9b0bbadcc6c5afd300ed7748294e62ba00803))
-- **v-model:** use stricter check for option update ([c70addf](https://github.com/vuejs/vue/commit/c70addf7d1a8e820ed80b6ab14aace5aa7b604c5)), closes [#6112](https://github.com/vuejs/vue/issues/6112)
+- **v-model:** use stricter check for `` option update ([c70addf](https://github.com/vuejs/vue/commit/c70addf7d1a8e820ed80b6ab14aace5aa7b604c5)), closes [#6112](https://github.com/vuejs/vue/issues/6112)
- **v-on:** revert component root data.on/data.nativeOn behavior for ([1713061](https://github.com/vuejs/vue/commit/17130611261fdbab70d0e5ab45036e4b612b17fe)), closes [#6109](https://github.com/vuejs/vue/issues/6109)
- work around IE/Edge bug when accessing document.activeElement from iframe ([fc3d7cd](https://github.com/vuejs/vue/commit/fc3d7cd7a93534d76840418467f303d4b301fbcd)), closes [#6157](https://github.com/vuejs/vue/issues/6157)
diff --git a/examples/classic/elastic-header/index.html b/examples/classic/elastic-header/index.html
index 3ba66367de..095c1beeb2 100644
--- a/examples/classic/elastic-header/index.html
+++ b/examples/classic/elastic-header/index.html
@@ -32,7 +32,7 @@
Elastic Draggable SVG Header
- with Vue.js + dynamics.js
+ with Vue.js + dynamics.js
Note this is just an effect demo - there are of course many additional details if you want to use this in production, e.g. handling responsive sizes, reload threshold and content scrolling. Those are out of scope for this quick little hack. However, the idea is that you can hide them as internal details of a Vue.js component and expose a simple Web-Component-like interface.
diff --git a/examples/classic/todomvc/app.js b/examples/classic/todomvc/app.js
index f8bfeb1ea6..7a1a65486a 100644
--- a/examples/classic/todomvc/app.js
+++ b/examples/classic/todomvc/app.js
@@ -55,7 +55,7 @@ var app = new Vue({
},
// computed properties
- // https://vuejs.org/guide/computed.html
+ // https://v2.vuejs.org/v2/guide/computed.html
computed: {
filteredTodos: function () {
return filters[this.visibility](this.todos)
@@ -129,7 +129,7 @@ var app = new Vue({
// a custom directive to wait for the DOM to be updated
// before focusing on the input field.
- // https://vuejs.org/guide/custom-directive.html
+ // https://v2.vuejs.org/v2/guide/custom-directive.html
directives: {
'todo-focus': function (el, binding) {
if (binding.value) {
diff --git a/examples/classic/todomvc/readme.md b/examples/classic/todomvc/readme.md
index 3155b80944..64277f62e9 100644
--- a/examples/classic/todomvc/readme.md
+++ b/examples/classic/todomvc/readme.md
@@ -3,16 +3,16 @@
> Vue.js is a library for building interactive web interfaces.
It provides data-driven, nestable view components with a simple and flexible API.
-> _[Vue.js - vuejs.org](https://vuejs.org)_
+> _[Vue.js - v2.vuejs.org](https://v2.vuejs.org)_
## Learning Vue.js
-The [Vue.js website](https://vuejs.org/) is a great resource to get started.
+The [Vue.js website](https://v2.vuejs.org/) is a great resource to get started.
Here are some links you may find helpful:
-* [Official Guide](https://vuejs.org/guide/)
-* [API Reference](https://vuejs.org/api/)
-* [Examples](https://vuejs.org/examples/)
+* [Official Guide](https://v2.vuejs.org/guide/)
+* [API Reference](https://v2.vuejs.org/api/)
+* [Examples](https://v2.vuejs.org/examples/)
Get help from other Vue.js users:
diff --git a/package.json b/package.json
index 33eff56cac..9fc45db965 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "vue",
- "version": "2.7.13",
+ "version": "2.7.14",
"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 5159c5cce0..637c2568fc 100644
--- a/packages/compiler-sfc/package.json
+++ b/packages/compiler-sfc/package.json
@@ -1,6 +1,6 @@
{
"name": "@vue/compiler-sfc",
- "version": "2.7.13",
+ "version": "2.7.14",
"description": "compiler-sfc for Vue 2",
"main": "dist/compiler-sfc.js",
"types": "dist/compiler-sfc.d.ts",
diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts
index 548fc59242..db04dbef33 100644
--- a/packages/compiler-sfc/src/compileScript.ts
+++ b/packages/compiler-sfc/src/compileScript.ts
@@ -39,7 +39,7 @@ import { walk } from 'estree-walker'
import { RawSourceMap } from 'source-map'
import { warnOnce } from './warn'
import { isReservedTag } from 'web/util'
-import { bindRE, dirRE, onRE } from 'compiler/parser'
+import { bindRE, dirRE, onRE, slotRE } from 'compiler/parser'
import { parseText } from 'compiler/parser/text-parser'
import { DEFAULT_FILENAME } from './parseComponent'
import {
@@ -1804,6 +1804,8 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor, isTS: boolean) {
if (dirRE.test(name)) {
const baseName = onRE.test(name)
? 'on'
+ : slotRE.test(name)
+ ? 'slot'
: bindRE.test(name)
? 'bind'
: name.replace(dirRE, '')
diff --git a/packages/compiler-sfc/test/compileScript.spec.ts b/packages/compiler-sfc/test/compileScript.spec.ts
index 7924c83d4e..11077b2aac 100644
--- a/packages/compiler-sfc/test/compileScript.spec.ts
+++ b/packages/compiler-sfc/test/compileScript.spec.ts
@@ -1571,7 +1571,23 @@ describe('SFC analyze
-
+
+ `)
+ })
+
+ // #12841
+ test('should not error when performing ts expression check for v-slot destructured default value', () => {
+ compile(`
+
+
+
+
+ {{ bar.baz }}
+
+
+
`)
})
})
diff --git a/packages/server-renderer/package.json b/packages/server-renderer/package.json
index 194d6e9f76..79c78175f5 100644
--- a/packages/server-renderer/package.json
+++ b/packages/server-renderer/package.json
@@ -1,6 +1,6 @@
{
"name": "vue-server-renderer",
- "version": "2.7.13",
+ "version": "2.7.14",
"description": "server renderer for Vue 2.0",
"main": "index.js",
"types": "types/index.d.ts",
diff --git a/packages/template-compiler/package.json b/packages/template-compiler/package.json
index 79515498d0..7e7d506ed9 100644
--- a/packages/template-compiler/package.json
+++ b/packages/template-compiler/package.json
@@ -1,6 +1,6 @@
{
"name": "vue-template-compiler",
- "version": "2.7.13",
+ "version": "2.7.14",
"description": "template compiler for Vue 2.0",
"main": "index.js",
"unpkg": "browser.js",
diff --git a/src/compiler/codegen/index.ts b/src/compiler/codegen/index.ts
index e3d5935b8d..b0daf352f8 100644
--- a/src/compiler/codegen/index.ts
+++ b/src/compiler/codegen/index.ts
@@ -259,7 +259,7 @@ export function genFor(
state.warn(
`<${el.tag} v-for="${alias} in ${exp}">: component lists rendered with ` +
`v-for should have explicit keys. ` +
- `See https://vuejs.org/guide/list.html#key for more info.`,
+ `See https://v2.vuejs.org/v2/guide/list.html#key for more info.`,
el.rawAttrsMap['v-for'],
true /* tip */
)
diff --git a/src/compiler/parser/index.ts b/src/compiler/parser/index.ts
index c02379d0f1..148cc0110f 100644
--- a/src/compiler/parser/index.ts
+++ b/src/compiler/parser/index.ts
@@ -42,7 +42,7 @@ export const bindRE = /^:|^\.|^v-bind:/
const propBindRE = /^\./
const modifierRE = /\.[^.\]]+(?=[^\]]*$)/g
-const slotRE = /^v-slot(:|$)|^#/
+export const slotRE = /^v-slot(:|$)|^#/
const lineBreakRE = /[\r\n]/
const whitespaceRE = /[ \f\t\r\n]+/g
diff --git a/src/core/observer/index.ts b/src/core/observer/index.ts
index 51f928c5c2..ef7296567c 100644
--- a/src/core/observer/index.ts
+++ b/src/core/observer/index.ts
@@ -16,7 +16,6 @@ import {
noop
} from '../util/index'
import { isReadonly, isRef, TrackOpTypes, TriggerOpTypes } from '../../v3'
-import { rawMap } from '../../v3/reactivity/reactive'
const arrayKeys = Object.getOwnPropertyNames(arrayMethods)
@@ -116,7 +115,6 @@ export function observe(
(isArray(value) || isPlainObject(value)) &&
Object.isExtensible(value) &&
!value.__v_skip /* ReactiveFlags.SKIP */ &&
- !rawMap.has(value) &&
!isRef(value) &&
!(value instanceof VNode)
) {
diff --git a/src/core/util/options.ts b/src/core/util/options.ts
index baddeb09b6..ef6a10342a 100644
--- a/src/core/util/options.ts
+++ b/src/core/util/options.ts
@@ -51,7 +51,8 @@ if (__DEV__) {
*/
function mergeData(
to: Record,
- from: Record | null
+ from: Record | null,
+ recursive = true
): Record {
if (!from) return to
let key, toVal, fromVal
@@ -66,7 +67,7 @@ function mergeData(
if (key === '__ob__') continue
toVal = to[key]
fromVal = from[key]
- if (!hasOwn(to, key)) {
+ if (!recursive || !hasOwn(to, key)) {
set(to, key, fromVal)
} else if (
toVal !== fromVal &&
@@ -262,7 +263,22 @@ strats.props =
if (childVal) extend(ret, childVal)
return ret
}
-strats.provide = mergeDataOrFn
+
+strats.provide = function (parentVal: Object | null, childVal: Object | null) {
+ if (!parentVal) return childVal
+ return function () {
+ const ret = Object.create(null)
+ mergeData(ret, isFunction(parentVal) ? parentVal.call(this) : parentVal)
+ if (childVal) {
+ mergeData(
+ ret,
+ isFunction(childVal) ? childVal.call(this) : childVal,
+ false // non-recursive
+ )
+ }
+ return ret
+ }
+}
/**
* Default strategy.
diff --git a/src/v3/reactivity/reactive.ts b/src/v3/reactivity/reactive.ts
index c65f25e67d..da9a1bf0c1 100644
--- a/src/v3/reactivity/reactive.ts
+++ b/src/v3/reactivity/reactive.ts
@@ -5,13 +5,10 @@ import {
isPrimitive,
warn,
toRawType,
- isServerRendering,
- isObject
+ isServerRendering
} from 'core/util'
import type { Ref, UnwrapRefSimple, RawSymbol } from './ref'
-export const rawMap = new WeakMap()
-
export const enum ReactiveFlags {
SKIP = '__v_skip',
IS_READONLY = '__v_isReadonly',
@@ -122,8 +119,9 @@ export function toRaw(observed: T): T {
export function markRaw(
value: T
): T & { [RawSymbol]?: true } {
- if (isObject(value)) {
- rawMap.set(value, true)
+ // non-extensible objects won't be observed anyway
+ if (Object.isExtensible(value)) {
+ def(value, ReactiveFlags.SKIP, true)
}
return value
}
diff --git a/src/v3/reactivity/readonly.ts b/src/v3/reactivity/readonly.ts
index c3794bb53b..e3a8393030 100644
--- a/src/v3/reactivity/readonly.ts
+++ b/src/v3/reactivity/readonly.ts
@@ -32,8 +32,8 @@ export type DeepReadonly = T extends Builtin
? { readonly [K in keyof T]: DeepReadonly }
: Readonly
-const rawToReadonlyMap = new WeakMap()
-const rawToShallowReadonlyMap = new WeakMap()
+const rawToReadonlyFlag = `__v_rawToReadonly`
+const rawToShallowReadonlyFlag = `__v_rawToShallowReadonly`
export function readonly(
target: T
@@ -57,20 +57,26 @@ function createReadonly(target: any, shallow: boolean) {
return target as any
}
+ if (__DEV__ && !Object.isExtensible(target)) {
+ warn(
+ `Vue 2 does not support creating readonly proxy for non-extensible object.`
+ )
+ }
+
// already a readonly object
if (isReadonly(target)) {
return target as any
}
// already has a readonly proxy
- const map = shallow ? rawToShallowReadonlyMap : rawToReadonlyMap
- const existingProxy = map.get(target)
+ const existingFlag = shallow ? rawToShallowReadonlyFlag : rawToReadonlyFlag
+ const existingProxy = target[existingFlag]
if (existingProxy) {
return existingProxy
}
const proxy = Object.create(Object.getPrototypeOf(target))
- map.set(target, proxy)
+ def(target, existingFlag, proxy)
def(proxy, ReactiveFlags.IS_READONLY, true)
def(proxy, ReactiveFlags.RAW, target)
diff --git a/test/unit/features/options/inject.spec.ts b/test/unit/features/options/inject.spec.ts
index 983367b612..b4c295e3f5 100644
--- a/test/unit/features/options/inject.spec.ts
+++ b/test/unit/features/options/inject.spec.ts
@@ -712,4 +712,12 @@ describe('Options provide/inject', () => {
await nextTick()
expect(spy).toHaveBeenCalledWith(2)
})
+
+ // #12854
+ test('should not mutate original provide options', () => {
+ const hairMixin = { provide: { hair: 'red' } }
+ const eyesMixin = { provide: { eyes: 'brown' } }
+ new Vue({ mixins: [hairMixin, eyesMixin], render() {} }).$mount()
+ expect(eyesMixin.provide).toStrictEqual({ eyes: 'brown' })
+ })
})
diff --git a/test/unit/features/v3/reactivity/reactive.spec.ts b/test/unit/features/v3/reactivity/reactive.spec.ts
index a8a30e0353..aa49f103f6 100644
--- a/test/unit/features/v3/reactivity/reactive.spec.ts
+++ b/test/unit/features/v3/reactivity/reactive.spec.ts
@@ -259,7 +259,7 @@ describe('reactivity/reactive', () => {
})
test('markRaw on non-extensible objects', () => {
- const foo = Object.freeze({})
+ const foo = Object.seal({})
markRaw(foo)
expect(isReactive(reactive(foo))).toBe(false)
})
diff --git a/test/unit/features/v3/reactivity/readonly.spec.ts b/test/unit/features/v3/reactivity/readonly.spec.ts
index fab99bbfbc..252fb9884b 100644
--- a/test/unit/features/v3/reactivity/readonly.spec.ts
+++ b/test/unit/features/v3/reactivity/readonly.spec.ts
@@ -526,10 +526,13 @@ describe('reactivity/readonly', () => {
expect(`et operation on key "x" failed`).toHaveBeenWarned()
})
- test('compatibility with non-extensible objects', () => {
+ test('warn non-extensible objects', () => {
const foo = Object.freeze({ a: 1 })
- const bar = readonly(foo)
- expect(isReadonly(bar)).toBe(true)
- expect(readonly(foo)).toBe(bar)
+ try {
+ readonly(foo)
+ } catch (e) {}
+ expect(
+ `Vue 2 does not support creating readonly proxy for non-extensible object`
+ ).toHaveBeenWarned()
})
})
diff --git a/types/jsx.d.ts b/types/jsx.d.ts
index 4924f4c643..845cfdcb03 100644
--- a/types/jsx.d.ts
+++ b/types/jsx.d.ts
@@ -1297,7 +1297,9 @@ export interface Events {
}
type EventHandlers = {
- [K in keyof E]?: E[K] extends Function ? E[K] : (payload: E[K]) => void
+ [K in keyof E]?: E[K] extends (...args: any) => any
+ ? E[K]
+ : (payload: E[K]) => void
}
type ReservedProps = {
diff --git a/types/test/v3/tsx-test.tsx b/types/test/v3/tsx-test.tsx
index 286c16997a..6a9dcce4fc 100644
--- a/types/test/v3/tsx-test.tsx
+++ b/types/test/v3/tsx-test.tsx
@@ -1,4 +1,4 @@
-import { VNode, defineComponent, ref } from '../../index'
+import { VNode, defineComponent, ref, RenderContext } from '../../index'
import { expectType } from '../utils'
expectType(
)
@@ -25,7 +25,13 @@ expectType(
)
// allow Ref type type on arbitrary element
const fooRef = ref()
expectType(
)
-expectType( {fooRef.value = el as HTMLElement}} />)
+expectType
(
+ {
+ fooRef.value = el as HTMLElement
+ }}
+ />
+)
expectType
(
;
-
;
+
+export default ({ data }: RenderContext) => {
+ return
+}
diff --git a/types/test/vue-test.ts b/types/test/vue-test.ts
index b792cec583..fdf37b52ab 100644
--- a/types/test/vue-test.ts
+++ b/types/test/vue-test.ts
@@ -228,21 +228,21 @@ obj.a++
const ComponentWithStyleInVNodeData = Vue.extend({
render(h) {
const elementWithStyleAsString = h('div', {
- style: 'background-color: red;'
+ style: '--theme-color: black;'
})
- const elementWithStyleAsObject = h('div', {
- style: { backgroundColor: 'green' }
+ const elementWithStyleCSSProperties = h('div', {
+ style: { ['--theme-color' as any]: 'black' }
})
- const elementWithStyleAsArrayOfObjects = h('div', {
- style: [{ backgroundColor: 'blue' }]
+ const elementWithStyleAsArrayOfStyleValues = h('div', {
+ style: [{ ['--theme-color' as any]: 'black' }]
})
return h('div', undefined, [
elementWithStyleAsString,
- elementWithStyleAsObject,
- elementWithStyleAsArrayOfObjects
+ elementWithStyleCSSProperties,
+ elementWithStyleAsArrayOfStyleValues
])
}
})
diff --git a/types/vnode.d.ts b/types/vnode.d.ts
index 29bdb398c1..d6f23ec3b6 100644
--- a/types/vnode.d.ts
+++ b/types/vnode.d.ts
@@ -1,3 +1,4 @@
+import { StyleValue } from './jsx'
import { Vue } from './vue'
import { DirectiveFunction, DirectiveOptions } from './options'
import { Ref } from './v3-generated'
@@ -85,7 +86,7 @@ export interface VNodeData {
staticClass?: string
class?: any
staticStyle?: { [key: string]: any }
- style?: string | object[] | object
+ style?: StyleValue
props?: { [key: string]: any }
attrs?: { [key: string]: any }
domProps?: { [key: string]: any }