diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 7bda0561856..21f32de041a 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 4c75474b8d6..05577cb11d4 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 3ba66367de6..095c1beeb20 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 f8bfeb1ea61..7a1a65486a3 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 3155b80944d..64277f62e9a 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 33eff56cac0..9fc45db9652 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 5159c5cce04..637c2568fc5 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 548fc592423..db04dbef333 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 7924c83d4eb..11077b2aacc 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 194d6e9f765..79c78175f51 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 79515498d03..7e7d506ed93 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 e3d5935b8d6..b0daf352f82 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 c02379d0f14..148cc0110f5 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 51f928c5c24..ef7296567c7 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 baddeb09b6e..ef6a10342a9 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 c65f25e67d8..da9a1bf0c1c 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 c3794bb53b3..e3a83930301 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 983367b6126..b4c295e3f51 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 a8a30e0353c..aa49f103f6e 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 fab99bbfbcb..252fb9884b7 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 4924f4c643c..845cfdcb030 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 286c16997a0..6a9dcce4fc1 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 b792cec583d..fdf37b52abb 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 29bdb398c1c..d6f23ec3b67 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 }