Compare commits

..

85 Commits

Author SHA1 Message Date
Toddneal Stallworth 9e88707940
chore: fix spelling mistakes (#13216)
[skip ci]
2024-10-10 09:24:14 +02:00
Snoppy 73486cb5f5
chore: fix link broken (#13192)
* chore: fix link broken

Signed-off-by: snoppy <michaleli@foxmail.com>

* Update packages/template-compiler/README.md [skip ci]

---------

Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com>
2024-06-14 14:52:12 +02:00
Artfaith e428d89145
chore: browser compatibility table link (#13187)
Updated Browser Compatibility reference. The previous currently returns HTTP 404.
2024-05-21 09:51:55 +02:00
Evan You bed04a77e5 chore: update issue form [ci skip] 2023-12-31 21:23:55 +08:00
Evan You 0191d50c31
chore: eol readme (#13142) 2023-12-31 17:32:08 +08:00
Evan You cdcc4f0c66 chore: release name for 2.7.16 [ci skip] 2023-12-24 23:13:43 +08:00
Evan You 13f4e7dc03 release: v2.7.16 2023-12-24 23:02:07 +08:00
Evan You 56ce7f8c57 fix(lifecycle): esnure component effect scopes are disconnected
close #13134
2023-12-24 22:40:05 +08:00
Evan You 305e4ae9dc release: v2.7.16-beta.2 2023-12-14 09:28:08 +08:00
Evan You 3e1037e4a0 chore: bump vitest to 1.0.4 2023-12-14 09:21:26 +08:00
Evan You db9c566032 fix: account for nested render calls
close #13131
2023-12-14 09:21:11 +08:00
Evan You 895669ffa0 fix(types): export more types for v3 alignment (jsx / component options)
close #13078
close #13128
2023-12-14 08:40:20 +08:00
Evan You 73bdf14ef5 release: v2.7.16-beta.1 2023-12-08 09:42:01 +08:00
Evan You e0747f40a8 fix(keep-alive): fix memory leak without breaking transition tests 2023-12-07 17:07:15 +08:00
Evan You 2632249925 fix(keep-alive): fix keep-alive memory leak
close #12827
2023-12-07 16:12:36 +08:00
Evan You 3650c12f7d fix(types): provide types for built-in components
close #13002
2023-12-07 14:41:10 +08:00
lsdsjy 83d95351a9
fix(compiler-sfc): check template `ref` usage, (#12985)
close #12984
2023-12-07 14:14:27 +08:00
xonx 24fcf69624
fix(types): type VNodeChildren should allow type number (#13067)
close #12973
2023-12-07 13:59:43 +08:00
Evan You 6d857f5bee fix(watch): new property addition should trigger deep watcher with getter
close #12967
close #12972
2023-12-07 00:13:31 +08:00
Simon Lévesque a174c29dab
fix(types): fix shallowRef's return type (#12979)
close #12978
2023-12-06 23:51:56 +08:00
Evan You f5ef882a78 fix(style): always set new styles
close #12901
close #12946
2023-12-06 23:17:02 +08:00
Evan You d6468c4c38 chore(deps): bump esbuild 2023-12-06 17:29:47 +08:00
Evan You 25f97a5033 fix(compiler-sfc): fix rewriteDefault edge cases
close #13060
close #12892
close #12906
2023-12-06 17:25:12 +08:00
Evan You 10c2a87c70 chore(deps): bump @babel/parser 2023-12-06 17:09:56 +08:00
Evan You ae3e4b1c70 fix(utils): unwrap refs when stringifying values in template
close #12884
close #12888
2023-12-06 16:40:49 +08:00
Adam Hines de0b97b3ea
fix(types): fix type augmentation and compiler-sfc types w/moduleResolution: bundler (#13107)
close #13106
2023-12-06 15:52:18 +08:00
Grigorii K. Shartsev 45d6ad6645
chore(compiler-sfc): specify prettier version (#13053)
close: #13052
2023-12-06 15:49:41 +08:00
Evan You 0ad8e8d94f fix(shallowReactive): should track value if already reactive when set in shallowReactive 2023-12-06 15:45:15 +08:00
Evan You d30f6fd25f test: fix tests 2023-12-06 15:21:00 +08:00
Evan You 08382f0080 fix(props): should not unwrap props that are raw refs
close #12930
2023-12-06 15:10:49 +08:00
Evan You 947993f7e8 chore: bump vitest to 1.0 2023-12-06 15:08:23 +08:00
Evan You 223a9e9f2e chore: bust sponsor cache [ci skip] 2023-11-07 15:32:23 +08:00
Evan You 81598ea2f3 release: v2.7.15 2023-10-23 15:55:40 +08:00
Evan You af9a10f3c1 chore: update snapshots 2023-10-23 15:15:18 +08:00
xdm c22363425a
fix(patch): clone insert hooks to avoid being mutated during iteration (#12905) 2023-10-23 15:11:13 +08:00
Liu Bo 51fef2ca69
fix(compiler-sfc): add semicolon after `defineProps` statement (#12879) 2023-10-23 15:09:23 +08:00
webfansplz b8c8b3fc7a
fix(compiler-sfc): Resolve object expression parsing errors in `v-on` (#12862) 2023-10-23 15:08:58 +08:00
webfansplz d27c128b7c
fix(compiler-sfc): fix macro usage in multi-variable declaration (#12873) 2023-10-23 15:08:34 +08:00
webfansplz bb59751dd4
fix(compiler-sfc): Optimize the value of emitIdentifier (#12851) 2023-10-23 15:08:17 +08:00
webfansplz 099401e227
fix(types/sfc): improve the type inference using `withDefaults` (#12872) 2023-10-23 15:06:28 +08:00
xonx 67c1d26cb0
fix(types): correct serverPrefetch this type (#13068)
close #12488
2023-10-23 14:58:47 +08:00
Red Huang 74ca5a13ba
fix(lifecycle): scope might changed when call hook (#13070) 2023-10-22 10:52:10 +08:00
Evan You 1399ee6aa0 test: pin esbuild to 0.16 for karma-esbuild compat 2023-10-22 10:46:45 +08:00
Evan You 78ef6271d2 test: upgrade vitest + fix ssr tests for Node 18+ 2023-10-22 10:32:47 +08:00
Evan You 6149048ce9 chore: update node version task name 2023-10-22 09:47:16 +08:00
Evan You 18cc5479f6 chore: bump required node and pnpm versions for maintenance 2023-10-22 09:40:18 +08:00
mikoloism 49b6bd4264
refactor(shared): update `genStaticKeys` (#13010) 2023-04-27 11:43:19 +02:00
rj1 a9ca2d8519
chore: typos (#12949) 2023-02-04 19:16:38 +01:00
星宿君 d52fbff7a7
chore: fix typo in utils.ts (#12927) [skip ci] 2023-01-12 15:47:00 +01:00
Vadim 0e8511a8be
chore: fix typo in apiAsyncComponent.ts (#12912) 2022-12-27 22:38:05 +01:00
Ihor Sychevskyi 34c6192f4a
chore: update links (http=https) (#12911) 2022-12-27 10:19:37 +01:00
Caichong 2e57061766
chore: comment typos (#12878)
Co-authored-by: 方恒 <fangheng@shwpg.com>
2022-12-14 09:43:02 +01:00
董雨航 ca11dc6a86
chore: fix typo (#12894) 2022-12-06 15:35:28 +01:00
Evan You 9dd006b481 release: v2.7.14 2022-11-09 20:39:52 +08:00
Evan You 29b5f58803 fix(reactivity): avoid using WeakMap for IE compatibility
Using a WeakMap polyfill isn't ideal because the reason we tried to use
WeakMap was to work with non-extensible objects. However, WeakMap
polyfill for non-extensible objects are non-weak and could lead to
memory leaks.

The trade-off is that we remove support for `readonly()` on
non-extensible objects, which seems reasonable.

close #12837
2022-11-09 20:33:11 +08:00
Evan You d1899caf68 fix(provide/inject): do not mutate original provide options during merge
fix #12854
2022-11-09 20:04:55 +08:00
a161803398 5e3d4e90cd
fix(compiler-sfc): fix template usage check edge case for v-slot destructured default value (#12842)
fix #12841
2022-11-09 04:52:35 -05:00
Evan You 5aed733ab6 test: add test case for #12778 2022-11-09 17:35:45 +08:00
k-furusho f7db7f361b
fix(types): fix spreading VNodeData in tsx (#12789)
fix #12778
2022-11-09 04:34:55 -05:00
webfansplz 0b3cf7dda9
fix(types): stricter type condition for `EventHandlers` (#12840)
fix #12832
2022-11-09 04:25:28 -05:00
webfansplz a5afc4d0a4
chore: fix typo (#12863) 2022-11-09 09:07:36 +01:00
Jinjiang 6d9aac8bd3
chore: fix some broken links to v2 docs (#12839) 2022-10-19 12:45:59 +08:00
Jinjiang a7a71ad990
Update the dev to main in the PR template (#12834) 2022-10-16 20:13:22 +08:00
Evan You 259c7060da chore: fix changelog rendering [ci skip] 2022-10-15 17:39:04 +08:00
Evan You df281b0e4c release: v2.7.13 2022-10-14 11:41:56 +08:00
Evan You 800207c473 fix(effectScope): calling off() of a detached scope should not break currentScope
fix #12825
2022-10-14 10:51:07 +08:00
不见月 5960f05c69 fix(watch): avoid traversing objects that are marked non-reactive (#12806) 2022-10-12 21:43:46 +08:00
Blake Newman 8e262618cd fix(types): style attribute svg (#12800)
Set style attribute on svg to use `StyleValue`
2022-10-12 21:43:42 +08:00
Evan You 4cad410071 release: v2.7.12 2022-10-12 21:41:36 +08:00
Evan You e80cd09fff Revert "fix(setup): setup hook should be called before beforeCreate"
This reverts commit e1342df784.

reopen #12802
close #12821
close #12822
2022-10-12 21:22:26 +08:00
Evan You c61395d3f1 release: v2.7.11 2022-10-11 19:13:06 +08:00
Evan You 8880b55d52 perf: improve unsub perf for deps with massive amount of subs
close #12696
2022-10-11 19:02:47 +08:00
Evan You 738f4b3c57 fix(build): enforce LF line ending in built files
fix #12819
2022-10-11 17:51:46 +08:00
Evan You cc14d4452c chore: bump build deps 2022-10-11 17:39:59 +08:00
Evan You e1342df784 fix(setup): setup hook should be called before beforeCreate
fix #12802

Note this commit moves the initialization of injections and props to
before the invocation of beforeCreate. This should not cause breakage
because props and inject normalization has always been done before
beforeCreate, so code that attempts to modifiy props/inject options
inside beforeCreate should have never worked.
2022-10-11 16:29:30 +08:00
Evan You 0d6d972b32 fix(compiler-sfc): export parseComponent for compat with fork-ts-checker-webpack-plugin
fix #12719
2022-10-11 14:58:24 +08:00
fukang wang bc5b92adde
fix(types): fix error with options watch (#12779)
fix #12780
2022-10-11 02:43:33 -04:00
Evan You fb13930096 fix(sfc): prune returned bindings for non-TS as well
In Vue 3, pruning is only done for TS to produce valid code and
tree-shaking is done by inlining the template for production.
In Vue 2 we do not inline the template in production, so return binding
pruning is needed in all cases.

fix #12765
2022-10-11 14:10:48 +08:00
Shiluo34 87f69aa26f
fix(types): support Ref and function types in tsx ref attribute (#12759)
fix #12758
2022-10-11 01:36:50 -04:00
Xiersa 5d26f815c6
fix(reactivity): check skip first before checking ref when creating observer (#12813)
fix #12812
2022-10-11 01:26:20 -04:00
Evan You 4a0d88e46e fix(reactivity): use WeakMap for proxy/raw checks, compat with non-extensible objects
fix #12799
close #12798
2022-10-11 12:26:32 +08:00
ZHAO Jinxiang 27eed829cc
fix(types): vue 3 directive type compatibility (#12792) 2022-10-10 23:51:05 -04:00
Evan You 2f335b2f9d fix(sfc): remove sfc scoped deep syntax deprecation warnings 2022-10-11 11:41:31 +08:00
Evan You 60d268c426 chore: cache bust svg [ci skip] 2022-09-01 14:31:31 +08:00
Evan You d189b4beaa chore: special sponsor [ci skip] 2022-09-01 14:30:09 +08:00
87 changed files with 3691 additions and 2446 deletions

View File

@ -10,4 +10,4 @@ Project maintainers have the right and responsibility to remove, edit, or reject
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
This Code of Conduct is adapted from the [Contributor Covenant](https://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)

View File

@ -36,7 +36,7 @@ Hi! I'm really excited that you are interested in contributing to Vue.js. Before
## Development Setup
You will need [Node.js](http://nodejs.org) **version 12+** and [pnpm](https://pnpm.io/).
You will need [Node.js](https://nodejs.org) **version 18+** and [pnpm](https://pnpm.io/) **version 8+**.
After cloning the repo, run:

View File

@ -1,11 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Create new issue
url: https://new-issue.vuejs.org/
about: Please use the following link to create a new issue.
- name: Patreon
url: https://www.patreon.com/evanyou
about: Love Vue.js? Please consider supporting us via Patreon.
- name: Open Collective
url: https://opencollective.com/vuejs/donate
about: Love Vue.js? Please consider supporting us via Open Collective.
- name: Vue 2 has reached EOL!
url: https://v2.vuejs.org/eol/
about: Vue 2 has reached EOL and is no longer actively maintained. Click the link on the right for more details.
- name: Vue 2 NES by HeroDevs
url: https://www.herodevs.com/support/nes-vue?utm_source=vuejs-github&utm_medium=issue-form
about: Learn more about Vue 2 NES if you have security or compliance requirements for continued Vue 2 usage.

View File

@ -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

View File

@ -15,10 +15,10 @@ jobs:
- name: Install pnpm
uses: pnpm/action-setup@v2
- name: Set node version to 16
- name: Set node version to 18
uses: actions/setup-node@v2
with:
node-version: 16
node-version: 18
cache: 'pnpm'
- run: pnpm install
@ -34,10 +34,10 @@ jobs:
- name: Install pnpm
uses: pnpm/action-setup@v2
- name: Set node version to 16
- name: Set node version to 18
uses: actions/setup-node@v2
with:
node-version: 16
node-version: 18
cache: 'pnpm'
- run: pnpm install
@ -56,10 +56,10 @@ jobs:
- name: Install pnpm
uses: pnpm/action-setup@v2
- name: Set node version to 16
- name: Set node version to 18
uses: actions/setup-node@v2
with:
node-version: 16
node-version: 18
cache: 'pnpm'
- run: pnpm install
@ -78,10 +78,10 @@ jobs:
- name: Install pnpm
uses: pnpm/action-setup@v2
- name: Set node version to 16
- name: Set node version to 18
uses: actions/setup-node@v2
with:
node-version: 16
node-version: 18
cache: 'pnpm'
- run: pnpm install

View File

@ -1,3 +1,115 @@
## [2.7.16 Swan Song](https://github.com/vuejs/vue/compare/v2.7.16-beta.2...v2.7.16) (2023-12-24)
### Bug Fixes
* **lifecycle:** ensure component effect scopes are disconnected ([56ce7f8](https://github.com/vuejs/vue/commit/56ce7f8c573116ed6683149206cf35c987249d42)), closes [#13134](https://github.com/vuejs/vue/issues/13134)
## [2.7.16-beta.2](https://github.com/vuejs/vue/compare/v2.7.16-beta.1...v2.7.16-beta.2) (2023-12-14)
### Bug Fixes
* account for nested render calls ([db9c566](https://github.com/vuejs/vue/commit/db9c566032da0ec5cd758a3e8525e9733874c1e5)), closes [#13131](https://github.com/vuejs/vue/issues/13131)
* **types:** export more types for v3 alignment (jsx / component options) ([895669f](https://github.com/vuejs/vue/commit/895669ffa01f8075a326308caa8ad6a5f69a1919)), closes [#13078](https://github.com/vuejs/vue/issues/13078) [#13128](https://github.com/vuejs/vue/issues/13128)
## [2.7.16-beta.1](https://github.com/vuejs/vue/compare/v2.7.15...v2.7.16-beta.1) (2023-12-08)
### Bug Fixes
* **compiler-sfc:** check template `ref` usage, ([#12985](https://github.com/vuejs/vue/issues/12985)) ([83d9535](https://github.com/vuejs/vue/commit/83d95351a9f809311d624fc3398e7f6829b72447)), closes [#12984](https://github.com/vuejs/vue/issues/12984)
* **compiler-sfc:** fix rewriteDefault edge cases ([25f97a5](https://github.com/vuejs/vue/commit/25f97a5033187372e7b8c591c79336197ee5c833)), closes [#13060](https://github.com/vuejs/vue/issues/13060) [#12892](https://github.com/vuejs/vue/issues/12892) [#12906](https://github.com/vuejs/vue/issues/12906)
* **keep-alive:** fix keep-alive memory leak ([2632249](https://github.com/vuejs/vue/commit/2632249925e632e56f6dfc8fdbcf682c82e4081b)), closes [#12827](https://github.com/vuejs/vue/issues/12827)
* **keep-alive:** fix memory leak without breaking transition tests ([e0747f4](https://github.com/vuejs/vue/commit/e0747f40a879b4000a1959d21377b51d1f1ed988))
* **props:** should not unwrap props that are raw refs ([08382f0](https://github.com/vuejs/vue/commit/08382f008016c3b3b93f84594266f2e191fee91d)), closes [#12930](https://github.com/vuejs/vue/issues/12930)
* **shallowReactive:** should track value if already reactive when set in shallowReactive ([0ad8e8d](https://github.com/vuejs/vue/commit/0ad8e8d94f3a3bf4429f25850c85a6bbb2b81364))
* **style:** always set new styles ([f5ef882](https://github.com/vuejs/vue/commit/f5ef882a781b8a62c9ca00e95006d07636567c8e)), closes [#12901](https://github.com/vuejs/vue/issues/12901) [#12946](https://github.com/vuejs/vue/issues/12946)
* **types:** fix shallowRef's return type ([#12979](https://github.com/vuejs/vue/issues/12979)) ([a174c29](https://github.com/vuejs/vue/commit/a174c29dab2cf655b06f7870e0ac5a78ef35ec8a)), closes [#12978](https://github.com/vuejs/vue/issues/12978)
* **types:** fix type augmentation and compiler-sfc types w/moduleResolution: bundler ([#13107](https://github.com/vuejs/vue/issues/13107)) ([de0b97b](https://github.com/vuejs/vue/commit/de0b97b3eadae120eda505b45df2de2115dcb6f0)), closes [#13106](https://github.com/vuejs/vue/issues/13106)
* **types:** provide types for built-in components ([3650c12](https://github.com/vuejs/vue/commit/3650c12f7d3a20f3155bc1fd2b068e84289e0d33)), closes [#13002](https://github.com/vuejs/vue/issues/13002)
* **types:** type VNodeChildren should allow type number ([#13067](https://github.com/vuejs/vue/issues/13067)) ([24fcf69](https://github.com/vuejs/vue/commit/24fcf69624a633d43dfc0aa5fa6b93d11de7fad5)), closes [#12973](https://github.com/vuejs/vue/issues/12973)
* **utils:** unwrap refs when stringifying values in template ([ae3e4b1](https://github.com/vuejs/vue/commit/ae3e4b1c706b8d61a4a312ca5d23441df021b4b4)), closes [#12884](https://github.com/vuejs/vue/issues/12884) [#12888](https://github.com/vuejs/vue/issues/12888)
* **watch:** new property addition should trigger deep watcher with getter ([6d857f5](https://github.com/vuejs/vue/commit/6d857f5bee275dc98106e3b2cbc7722f5ec0cfc0)), closes [#12967](https://github.com/vuejs/vue/issues/12967) [#12972](https://github.com/vuejs/vue/issues/12972)
## [2.7.15](https://github.com/vuejs/vue/compare/v2.7.14...v2.7.15) (2023-10-23)
### Bug Fixes
* **compiler-sfc:** add semicolon after `defineProps` statement ([#12879](https://github.com/vuejs/vue/issues/12879)) ([51fef2c](https://github.com/vuejs/vue/commit/51fef2ca69459c1175e105991f60511f1996e0c8))
* **compiler-sfc:** fix macro usage in multi-variable declaration ([#12873](https://github.com/vuejs/vue/issues/12873)) ([d27c128](https://github.com/vuejs/vue/commit/d27c128b7cb1640f3aa185a5ecdea4ff35763794))
* **compiler-sfc:** Optimize the value of emitIdentifier ([#12851](https://github.com/vuejs/vue/issues/12851)) ([bb59751](https://github.com/vuejs/vue/commit/bb59751dd4e45afcaafd607f22505a724b1ef841))
* **compiler-sfc:** Resolve object expression parsing errors in `v-on` ([#12862](https://github.com/vuejs/vue/issues/12862)) ([b8c8b3f](https://github.com/vuejs/vue/commit/b8c8b3fc7a211744fdabd237a1a986a1f80b7c43))
* **lifecycle:** scope might changed when call hook ([#13070](https://github.com/vuejs/vue/issues/13070)) ([74ca5a1](https://github.com/vuejs/vue/commit/74ca5a13ba12a31580f1567e7c6d789e96730e46))
* **patch:** clone insert hooks to avoid being mutated during iteration ([#12905](https://github.com/vuejs/vue/issues/12905)) ([c223634](https://github.com/vuejs/vue/commit/c22363425ae246ccbb8418342e94edfa270d93e5))
* **types/sfc:** improve the type inference using `withDefaults` ([#12872](https://github.com/vuejs/vue/issues/12872)) ([099401e](https://github.com/vuejs/vue/commit/099401e227fd5ed496ff615528d1a9b3b64d4fbf))
* **types:** correct serverPrefetch this type ([#13068](https://github.com/vuejs/vue/issues/13068)) ([67c1d26](https://github.com/vuejs/vue/commit/67c1d26cb0af3eb2db0a11fc7768a8299e7f7d58)), closes [#12488](https://github.com/vuejs/vue/issues/12488)
## [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)
### Bug Fixes
* **effectScope:** calling off() of a detached scope should not break currentScope ([800207c](https://github.com/vuejs/vue/commit/800207c473c7d6dfcdc883100a3d443fc5ad2e39)), closes [#12825](https://github.com/vuejs/vue/issues/12825)
* **types:** style attribute svg ([#12800](https://github.com/vuejs/vue/issues/12800)) ([8e26261](https://github.com/vuejs/vue/commit/8e262618cdc3251ca9630b17de4a000567ffb007))
* **watch:** avoid traversing objects that are marked non-reactive ([#12806](https://github.com/vuejs/vue/issues/12806)) ([5960f05](https://github.com/vuejs/vue/commit/5960f05c69099c174062b6672c7a21d717a3bccf))
## [2.7.12](https://github.com/vuejs/vue/compare/v2.7.11...v2.7.12) (2022-10-12)
### Reverts
* Revert "fix(setup): setup hook should be called before beforeCreate" ([e80cd09](https://github.com/vuejs/vue/commit/e80cd09fff570df57d608f8f5aaccee6d7f31917)), closes [#12802](https://github.com/vuejs/vue/issues/12802) [#12821](https://github.com/vuejs/vue/issues/12821) [#12822](https://github.com/vuejs/vue/issues/12822)
## [2.7.11](https://github.com/vuejs/vue/compare/v2.7.10...v2.7.11) (2022-10-11)
### Bug Fixes
* **build:** enforce LF line ending in built files ([738f4b3](https://github.com/vuejs/vue/commit/738f4b3c570dc3a1818924a203a9f8e4b1ec90f0)), closes [#12819](https://github.com/vuejs/vue/issues/12819)
* **compiler-sfc:** export parseComponent for compat with fork-ts-checker-webpack-plugin ([0d6d972](https://github.com/vuejs/vue/commit/0d6d972b32521fd18eb853b1073c0a19859a499a)), closes [#12719](https://github.com/vuejs/vue/issues/12719)
* **reactivity:** check skip first before checking ref when creating observer ([#12813](https://github.com/vuejs/vue/issues/12813)) ([5d26f81](https://github.com/vuejs/vue/commit/5d26f815c643d41e6ca6f29329593223b981fc24)), closes [#12812](https://github.com/vuejs/vue/issues/12812)
* **reactivity:** use WeakMap for proxy/raw checks, compat with non-extensible objects ([4a0d88e](https://github.com/vuejs/vue/commit/4a0d88e46e4180edc7f22e36c25df3f8ac5d60d2)), closes [#12799](https://github.com/vuejs/vue/issues/12799) [#12798](https://github.com/vuejs/vue/issues/12798)
* **setup:** setup hook should be called before beforeCreate ([e1342df](https://github.com/vuejs/vue/commit/e1342df7847a51c75192fec74e94378178e046b0)), closes [#12802](https://github.com/vuejs/vue/issues/12802)
* **sfc:** prune returned bindings for non-TS as well ([fb13930](https://github.com/vuejs/vue/commit/fb1393009660b38046b1f6dfb532b481cc53b3b7)), closes [#12765](https://github.com/vuejs/vue/issues/12765)
* **sfc:** remove sfc scoped deep syntax deprecation warnings ([2f335b2](https://github.com/vuejs/vue/commit/2f335b2f9d09b962f40e38740826d444e4fff073))
* **types:** fix error with options watch ([#12779](https://github.com/vuejs/vue/issues/12779)) ([bc5b92a](https://github.com/vuejs/vue/commit/bc5b92adde147436f2adb25e457f0c967829467f)), closes [#12780](https://github.com/vuejs/vue/issues/12780)
* **types:** support Ref and function types in tsx ref attribute ([#12759](https://github.com/vuejs/vue/issues/12759)) ([87f69aa](https://github.com/vuejs/vue/commit/87f69aa26f195390b948fbb0ff62cf954b58c82c)), closes [#12758](https://github.com/vuejs/vue/issues/12758)
* **types:** vue 3 directive type compatibility ([#12792](https://github.com/vuejs/vue/issues/12792)) ([27eed82](https://github.com/vuejs/vue/commit/27eed829ccf9978a63b8cd989ff4c03897276bc2))
### Performance Improvements
* improve unsub perf for deps with massive amount of subs ([8880b55](https://github.com/vuejs/vue/commit/8880b55d52f8d873f79ef67436217c8752cddef5)), closes [#12696](https://github.com/vuejs/vue/issues/12696)
## [2.7.10](https://github.com/vuejs/vue/compare/v2.7.9...v2.7.10) (2022-08-23)
@ -594,7 +706,7 @@ In addition:
- should consider presence of normal slots when caching normalized scoped slots ([9313cf9](https://github.com/vuejs/vue/commit/9313cf91740e1d43c43cf9e73d905dbab913beb5)), closes [#9644](https://github.com/vuejs/vue/issues/9644)
- should not swallow user catch on rejected promise in methods ([7186940](https://github.com/vuejs/vue/commit/7186940143704acc4ec046132f6a56e9c983e510)), closes [#9694](https://github.com/vuejs/vue/issues/9694)
- should use fallback for scoped slots with single falsy v-if ([781c705](https://github.com/vuejs/vue/commit/781c70514e01bc402828946805bfad7437c7175e)), closes [#9658](https://github.com/vuejs/vue/issues/9658)
- **ssr:** fix nested async functional componet rendering ([#9673](https://github.com/vuejs/vue/issues/9673)) ([8082d2f](https://github.com/vuejs/vue/commit/8082d2f910d963f14c151fb445e0fcc5c975cca9)), closes [#9643](https://github.com/vuejs/vue/issues/9643)
- **ssr:** fix nested async functional component rendering ([#9673](https://github.com/vuejs/vue/issues/9673)) ([8082d2f](https://github.com/vuejs/vue/commit/8082d2f910d963f14c151fb445e0fcc5c975cca9)), closes [#9643](https://github.com/vuejs/vue/issues/9643)
- **ssr:** not push non-async css files into map ([#9677](https://github.com/vuejs/vue/issues/9677)) ([d282400](https://github.com/vuejs/vue/commit/d28240009c4c49fb2ef42a79206f0d9ad03f736c))
- **transition:** fix appear check for transition wrapper components ([#9668](https://github.com/vuejs/vue/issues/9668)) ([4de4649](https://github.com/vuejs/vue/commit/4de4649d9637262a9b007720b59f80ac72a5620c))
- v-bind object should be overridable by single bindings ([#9653](https://github.com/vuejs/vue/issues/9653)) ([0b57380](https://github.com/vuejs/vue/commit/0b57380f10986c6b07e3c240acc06bfd2eddfd1b)), closes [#9641](https://github.com/vuejs/vue/issues/9641)
@ -797,7 +909,7 @@ In addition:
- fix single v-for child optimization ([847e493](https://github.com/vuejs/vue/commit/847e493768371cec4718969e02bdb7f8463f4e03))
- fix v-for component with undefined value ([4748760](https://github.com/vuejs/vue/commit/47487607fbb99339038cf84990ba341c25b5e20d)), closes [#9181](https://github.com/vuejs/vue/issues/9181)
- **lifecycle:** beforeUpdated should not be called if component is destroyed ([#9171](https://github.com/vuejs/vue/issues/9171)) ([87bad80](https://github.com/vuejs/vue/commit/87bad80f0cb9a30b95d9410120ff6e3e2022a723)), closes [#8076](https://github.com/vuejs/vue/issues/8076)
- **types:** accept primatives and falsy values in createElement children ([#9154](https://github.com/vuejs/vue/issues/9154)) ([d780dd2](https://github.com/vuejs/vue/commit/d780dd2e2adcf71f40c086055a659a9a2b4a8282)), closes [#8498](https://github.com/vuejs/vue/issues/8498)
- **types:** accept primitive and falsy values in createElement children ([#9154](https://github.com/vuejs/vue/issues/9154)) ([d780dd2](https://github.com/vuejs/vue/commit/d780dd2e2adcf71f40c086055a659a9a2b4a8282)), closes [#8498](https://github.com/vuejs/vue/issues/8498)
- **v-model:** properly handle multiline v-model expressions ([#9184](https://github.com/vuejs/vue/issues/9184)) ([3d44937](https://github.com/vuejs/vue/commit/3d449376d557c4533a9664f95df3a168ecee9bfa)), closes [#9183](https://github.com/vuejs/vue/issues/9183)
- **weex:** support data class type that is string ([#9139](https://github.com/vuejs/vue/issues/9139)) ([d8285c5](https://github.com/vuejs/vue/commit/d8285c57a613c42eddf2d4f2b75c1cea6aa4703a)), closes [#9124](https://github.com/vuejs/vue/issues/9124)
@ -845,7 +957,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 <pre> ([#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 `<pre>` ([#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)
@ -906,7 +1018,7 @@ In addition:
- beforeUpdate should be called before render and allow state mutation ([#7822](https://github.com/vuejs/vue/issues/7822)) ([b7445a2](https://github.com/vuejs/vue/commit/b7445a2b945dcded287601ace8e711ab5cf35ab5)), closes [#7481](https://github.com/vuejs/vue/issues/7481)
- **codegen:** support IE11 and Edge use of "Esc" key ([#7887](https://github.com/vuejs/vue/issues/7887)) ([1bd6196](https://github.com/vuejs/vue/commit/1bd6196fb234c28754d9a27095afe0b5b84990ad)), closes [#7880](https://github.com/vuejs/vue/issues/7880)
- correct the `has` implementation in the `_renderProxy` ([#7878](https://github.com/vuejs/vue/issues/7878)) ([7b38739](https://github.com/vuejs/vue/commit/7b387390aa917edffc0eabce0b4186ea1ef40e2c))
- ensure init/prepatch hooks are still repsected ([de42278](https://github.com/vuejs/vue/commit/de42278d34f6a800cec5c7eb781c1b8b83a829dd)), closes [vue-router#1338](https://github.com/vue-router/issues/1338)
- ensure init/prepatch hooks are still respected ([de42278](https://github.com/vuejs/vue/commit/de42278d34f6a800cec5c7eb781c1b8b83a829dd)), closes [vue-router#1338](https://github.com/vue-router/issues/1338)
- invoke component node create hooks before insertion ([#7823](https://github.com/vuejs/vue/issues/7823)) ([f43ce3a](https://github.com/vuejs/vue/commit/f43ce3a5d8f73e273f2d03c9d86ea5662cda481a)), closes [#7531](https://github.com/vuejs/vue/issues/7531)
- **observer:** invoke getters on initial observation if setter defined ([#7828](https://github.com/vuejs/vue/issues/7828)) ([7a145d8](https://github.com/vuejs/vue/commit/7a145d86430bad65271f4d6ab1344b215fefe52a))
@ -937,7 +1049,7 @@ In addition:
### Bug Fixes
- do not traverse VNodes when regsitering dependencies ([84a9a9d](https://github.com/vuejs/vue/commit/84a9a9d61057f6f40a9ad2bee456b39ef0a8f001)), closes [#7786](https://github.com/vuejs/vue/issues/7786)
- do not traverse VNodes when registering dependencies ([84a9a9d](https://github.com/vuejs/vue/commit/84a9a9d61057f6f40a9ad2bee456b39ef0a8f001)), closes [#7786](https://github.com/vuejs/vue/issues/7786)
## [2.5.14](https://github.com/vuejs/vue/compare/v2.5.13...v2.5.14) (2018-03-09)
@ -1133,7 +1245,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 <select v-model> initial state ([e1657fd](https://github.com/vuejs/vue/commit/e1657fd7ce49bff3c3ecad3c56ae527347505c34)), closes [#6986](https://github.com/vuejs/vue/issues/6986)
- **ssr:** properly render `<select v-model>` 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))
@ -1170,14 +1282,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 <template> scoped slot ([68bdbf5](https://github.com/vuejs/vue/commit/68bdbf508b915872627676d6bf987bdac9e5fe97)), closes [#6725](https://github.com/vuejs/vue/issues/6725)
- properly handle v-if on `<template>` 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 <progress> in IE/Edge ([c64f9ae](https://github.com/vuejs/vue/commit/c64f9ae1649175ee8cac1c7ecf3283897c948202)), closes [#6666](https://github.com/vuejs/vue/issues/6666)
- properly render value on `<progress>` 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 <foreignObject> as root node ([cf1ff5b](https://github.com/vuejs/vue/commit/cf1ff5b0dc3d15c1e16821cb5e4fc984c74f07c1)), closes [#6642](https://github.com/vuejs/vue/issues/6642)
- use correct ns inside `<foreignObject>` 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)
@ -1202,7 +1314,7 @@ In addition:
- support denoting normal elements as scoped slot ([dae173d](https://github.com/vuejs/vue/commit/dae173d96d15f47de6ce6961354d5c05e4273005))
- support RegExp in ignoredElements ([#6769](https://github.com/vuejs/vue/issues/6769)) ([795b908](https://github.com/vuejs/vue/commit/795b908095b29e76435479879c1ade7ef759ce7b))
- **types:** further improve Vue type declarations for canonical usage ([#6391](https://github.com/vuejs/vue/issues/6391)) ([db138e2](https://github.com/vuejs/vue/commit/db138e2254d71f6b96e033acf66ba43ad269841a))
- **v-model:** craete non-existent properties as reactive ([e1da0d5](https://github.com/vuejs/vue/commit/e1da0d585c797860533d6cb10ea3d09c7fb711fc)), closes [#5932](https://github.com/vuejs/vue/issues/5932)
- **v-model:** create non-existent properties as reactive ([e1da0d5](https://github.com/vuejs/vue/commit/e1da0d585c797860533d6cb10ea3d09c7fb711fc)), closes [#5932](https://github.com/vuejs/vue/issues/5932)
- **v-model:** support dynamic input type binding ([f3fe012](https://github.com/vuejs/vue/commit/f3fe012d5499f607656b152ce5fcb506c641f9f4))
- v-on automatic key inference ([4987eeb](https://github.com/vuejs/vue/commit/4987eeb3a734a16a4978d1061f73039002d351e6))
@ -1228,12 +1340,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 <embed> ([d77b953](https://github.com/vuejs/vue/commit/d77b95317cedae299605fb692e2c7c67796b17cb)), closes [#6202](https://github.com/vuejs/vue/issues/6202)
- handle special case for allowfullscreen on `<embed>` ([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 <progress> ([7116af4](https://github.com/vuejs/vue/commit/7116af4e07520040ed7328c39d0a456808bfe1e1)), closes [#6561](https://github.com/vuejs/vue/issues/6561)
- set value as domProp for `<progress>` ([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)
@ -1274,14 +1386,14 @@ In addition:
- checkbox v-model="array" ignore false-value ([#6180](https://github.com/vuejs/vue/issues/6180)) ([3d14e85](https://github.com/vuejs/vue/commit/3d14e855e422b656859d1b419af43b94320fcfce)), closes [#6178](https://github.com/vuejs/vue/issues/6178)
- **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)
- ensure looseEqual is not dependent 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 <pre> ([082fc39](https://github.com/vuejs/vue/commit/082fc3967db4d3290e901a38504dcd9bb698e561)), closes [#6146](https://github.com/vuejs/vue/issues/6146)
- **parser:** only ignore the first newline in `<pre>` ([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 <select> 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 `<select>` 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)

View File

@ -1,3 +1,11 @@
## Vue 2 has reached End of Life
**You are looking at the now inactive repository for Vue 2. The actively maintained repository for the latest version of Vue is [vuejs/core](https://github.com/vuejs/core).**
Vue has reached End of Life on December 31st, 2023. It no longer receives new features, updates, or fixes. However, it is still available on all existing distribution channels (CDNs, package managers, Github, etc).
If you are starting a new project, please start with the latest version of Vue (3.x). We also strongly recommend current Vue 2 users to upgrade ([guide](https://v3-migration.vuejs.org/)), but we also acknowledge that not all users have the bandwidth or incentive to do so. If you have to stay on Vue 2 but also have compliance or security requirements about unmaintained software, check out [Vue 2 NES](https://www.herodevs.com/support/nes-vue?utm_source=vuejs-github&utm_medium=vue2-readme).
<p align="center"><a href="https://vuejs.org" target="_blank" rel="noopener noreferrer"><img width="100" src="https://vuejs.org/images/logo.png" alt="Vue logo"></a></p>
<p align="center">
@ -9,17 +17,23 @@
<a href="https://chat.vuejs.org/"><img src="https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true" alt="Chat"></a>
</p>
## This repo is for Vue 2
You are looking at the repository for Vue 2. The repo for Vue 3 is [vuejs/core](https://github.com/vuejs/core).
## Sponsors
Vue.js is an MIT-licensed open source project with its ongoing development made possible entirely by the support of these awesome [backers](https://github.com/vuejs/core/blob/main/BACKERS.md). If you'd like to join them, please consider [ sponsor Vue's development](https://vuejs.org/sponsor/).
<p align="center">
<h3 align="center">Special Sponsor</h3>
</p>
<p align="center">
<a target="_blank" href="https://github.com/appwrite/appwrite">
<img alt="special sponsor appwrite" src="https://sponsors.vuejs.org/images/appwrite.svg" width="300">
</a>
</p>
<p align="center">
<a target="_blank" href="https://vuejs.org/sponsor/">
<img alt="sponsors" src="https://sponsors.vuejs.org/sponsors.svg">
<img alt="sponsors" src="https://sponsors.vuejs.org/sponsors.svg?v3">
</a>
</p>
@ -31,7 +45,7 @@ Vue (pronounced `/vjuː/`, like view) is a **progressive framework** for buildin
#### Browser Compatibility
Vue.js supports all browsers that are [ES5-compliant](https://kangax.github.io/compat-table/es5/) (IE8 and below are not supported).
Vue.js supports all browsers that are [ES5-compliant](https://compat-table.github.io/compat-table/es5/) (IE8 and below are not supported).
## Ecosystem

152
dist/vue.runtime.mjs vendored
View File

@ -1,76 +1,76 @@
import Vue from './vue.runtime.common.js'
export default Vue
// this should be kept in sync with src/v3/index.ts
export const {
version,
// refs
ref,
shallowRef,
isRef,
toRef,
toRefs,
unref,
proxyRefs,
customRef,
triggerRef,
computed,
// reactive
reactive,
isReactive,
isReadonly,
isShallow,
isProxy,
shallowReactive,
markRaw,
toRaw,
readonly,
shallowReadonly,
// watch
watch,
watchEffect,
watchPostEffect,
watchSyncEffect,
// effectScope
effectScope,
onScopeDispose,
getCurrentScope,
// provide / inject
provide,
inject,
// lifecycle
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted,
onErrorCaptured,
onActivated,
onDeactivated,
onServerPrefetch,
onRenderTracked,
onRenderTriggered,
// v2 only
set,
del,
// v3 compat
h,
getCurrentInstance,
useSlots,
useAttrs,
mergeDefaults,
nextTick,
useCssModule,
useCssVars,
defineComponent,
defineAsyncComponent
} = Vue
import Vue from './vue.runtime.common.js'
export default Vue
// this should be kept in sync with src/v3/index.ts
export const {
version,
// refs
ref,
shallowRef,
isRef,
toRef,
toRefs,
unref,
proxyRefs,
customRef,
triggerRef,
computed,
// reactive
reactive,
isReactive,
isReadonly,
isShallow,
isProxy,
shallowReactive,
markRaw,
toRaw,
readonly,
shallowReadonly,
// watch
watch,
watchEffect,
watchPostEffect,
watchSyncEffect,
// effectScope
effectScope,
onScopeDispose,
getCurrentScope,
// provide / inject
provide,
inject,
// lifecycle
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted,
onErrorCaptured,
onActivated,
onDeactivated,
onServerPrefetch,
onRenderTracked,
onRenderTriggered,
// v2 only
set,
del,
// v3 compat
h,
getCurrentInstance,
useSlots,
useAttrs,
mergeDefaults,
nextTick,
useCssModule,
useCssVars,
defineComponent,
defineAsyncComponent
} = Vue

View File

@ -32,7 +32,7 @@
<draggable-header-view>
<template slot="header">
<h1>Elastic Draggable SVG Header</h1>
<p>with <a href="https://vuejs.org">Vue.js</a> + <a href="http://dynamicsjs.com">dynamics.js</a></p>
<p>with <a href="https://v2.vuejs.org">Vue.js</a> + <a href="http://dynamicsjs.com">dynamics.js</a></p>
</template>
<template slot="content">
<p>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.</p>

View File

@ -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) {

View File

@ -54,8 +54,8 @@
</section>
<footer class="info">
<p>Double-click to edit a todo</p>
<p>Written by <a href="http://evanyou.me">Evan You</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
<p>Written by <a href="https://evanyou.me">Evan You</a></p>
<p>Part of <a href="https://todomvc.com">TodoMVC</a></p>
</footer>
<script>

View File

@ -3,20 +3,20 @@
> 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:
* [Vue.js official forum](http://forum.vuejs.org)
* [Vue.js official forum](https://forum.vuejs.org)
* [Vue.js on Twitter](https://twitter.com/vuejs)
* [Vue.js on Gitter](https://gitter.im/vuejs/vue)
@ -24,4 +24,4 @@ _If you have other helpful links to share, or find any of the links above no lon
## Credit
This TodoMVC application was created by [Evan You](http://evanyou.me).
This TodoMVC application was created by [Evan You](https://evanyou.me).

View File

@ -1,7 +1,7 @@
{
"name": "vue",
"version": "2.7.10",
"packageManager": "pnpm@7.1.0",
"version": "2.7.16",
"packageManager": "pnpm@8.9.2",
"description": "Reactive, component-oriented view layer for modern web interfaces.",
"main": "dist/vue.runtime.common.js",
"module": "dist/vue.runtime.esm.js",
@ -18,19 +18,23 @@
],
"exports": {
".": {
"types": "./types/index.d.ts",
"import": {
"node": "./dist/vue.runtime.mjs",
"default": "./dist/vue.runtime.esm.js"
},
"require": "./dist/vue.runtime.common.js",
"types": "./types/index.d.ts"
"require": "./dist/vue.runtime.common.js"
},
"./compiler-sfc": {
"types": "./compiler-sfc/index.d.ts",
"import": "./compiler-sfc/index.mjs",
"require": "./compiler-sfc/index.js"
},
"./dist/*": "./dist/*",
"./types/*": "./types/*",
"./types/*": [
"./types/*.d.ts",
"./types/*"
],
"./package.json": "./package.json"
},
"sideEffects": false,
@ -87,19 +91,19 @@
"csstype": "^3.1.0"
},
"devDependencies": {
"@babel/parser": "^7.18.4",
"@babel/parser": "^7.23.5",
"@microsoft/api-extractor": "^7.25.0",
"@rollup/plugin-alias": "^3.1.9",
"@rollup/plugin-commonjs": "^22.0.0",
"@rollup/plugin-node-resolve": "^13.3.0",
"@rollup/plugin-replace": "^4.0.0",
"@types/he": "^1.1.2",
"@types/node": "^17.0.41",
"@types/node": "^20.10.3",
"chalk": "^4.1.2",
"conventional-changelog-cli": "^2.2.2",
"cross-spawn": "^7.0.3",
"enquirer": "^2.3.6",
"esbuild": "^0.14.43",
"esbuild": "^0.19.8",
"execa": "^4.1.0",
"he": "^1.2.0",
"jasmine-core": "^4.2.0",
@ -107,7 +111,7 @@
"karma": "^6.3.20",
"karma-chrome-launcher": "^3.1.1",
"karma-cli": "^2.0.0",
"karma-esbuild": "^2.2.4",
"karma-esbuild": "^2.2.5",
"karma-jasmine": "^5.0.1",
"lint-staged": "^12.5.0",
"lodash": "^4.17.21",
@ -117,16 +121,16 @@
"prettier": "^2.6.2",
"puppeteer": "^14.3.0",
"rimraf": "^3.0.2",
"rollup": "^2.75.6",
"rollup-plugin-typescript2": "^0.31.2",
"rollup": "^2.79.1",
"rollup-plugin-typescript2": "^0.32.0",
"semver": "^7.3.7",
"shelljs": "^0.8.5",
"terser": "^5.14.0",
"todomvc-app-css": "^2.4.2",
"ts-node": "^10.8.1",
"tslib": "^2.4.0",
"typescript": "^4.7.3",
"vitest": "^0.12.10",
"typescript": "^4.8.4",
"vitest": "^1.0.4",
"yorkie": "^2.0.0"
}
}

View File

@ -1,6 +1,6 @@
{
"name": "@vue/compiler-sfc",
"version": "2.7.10",
"version": "2.7.16",
"description": "compiler-sfc for Vue 2",
"main": "dist/compiler-sfc.js",
"types": "dist/compiler-sfc.d.ts",
@ -8,12 +8,12 @@
"dist"
],
"dependencies": {
"@babel/parser": "^7.18.4",
"@babel/parser": "^7.23.5",
"postcss": "^8.4.14",
"source-map": "^0.6.1"
},
"devDependencies": {
"@babel/types": "^7.18.4",
"@babel/types": "^7.23.5",
"@types/estree": "^0.0.48",
"@types/hash-sum": "^1.0.0",
"@types/lru-cache": "^5.1.1",
@ -30,5 +30,8 @@
"pug": "^3.0.2",
"sass": "^1.52.3",
"stylus": "^0.58.1"
},
"optionalDependencies": {
"prettier": "^1.18.2 || ^2.0.0"
}
}

View File

@ -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 {
@ -284,11 +284,9 @@ export function compileScript(
userImportAlias[imported] = local
}
// template usage check is only needed in non-inline mode, so we can skip
// the work if inlineTemplate is true.
let isUsedInTemplate = true
if (isTS && sfc.template && !sfc.template.src && !sfc.template.lang) {
isUsedInTemplate = isImportUsed(local, sfc)
if (sfc.template && !sfc.template.src && !sfc.template.lang) {
isUsedInTemplate = isImportUsed(local, sfc, isTS)
}
userImports[local] = {
@ -416,7 +414,10 @@ export function compileScript(
}
if (declId) {
emitIdentifier = scriptSetup!.content.slice(declId.start!, declId.end!)
emitIdentifier =
declId.type === 'Identifier'
? declId.name
: scriptSetup!.content.slice(declId.start!, declId.end!)
}
return true
@ -782,7 +783,7 @@ export function compileScript(
if (node.trailingComments && node.trailingComments.length > 0) {
const lastCommentNode =
node.trailingComments[node.trailingComments.length - 1]
end = lastCommentNode.end + startOffset
end = lastCommentNode.end! + startOffset
}
// locate the end of whitespace between this statement and the next
while (end <= source.length) {
@ -909,11 +910,11 @@ export function compileScript(
} else {
let start = decl.start! + startOffset
let end = decl.end! + startOffset
if (i < total - 1) {
// not the last one, locate the start of the next
if (i === 0) {
// first one, locate the start of the next
end = node.declarations[i + 1].start! + startOffset
} else {
// last one, locate the end of the prev
// not first one, locate the end of the prev
start = node.declarations[i - 1].end! + startOffset
}
s.remove(start, end)
@ -1124,7 +1125,7 @@ export function compileScript(
startOffset,
`\nconst ${propsIdentifier} = __props${
propsTypeDecl ? ` as ${genSetupPropsType(propsTypeDecl)}` : ``
}\n`
};\n`
)
}
if (propsDestructureRestId) {
@ -1132,7 +1133,7 @@ export function compileScript(
startOffset,
`\nconst ${propsDestructureRestId} = ${helper(
`createPropsRestProxy`
)}(__props, ${JSON.stringify(Object.keys(propsDestructuredBindings))})\n`
)}(__props, ${JSON.stringify(Object.keys(propsDestructuredBindings))});\n`
)
}
@ -1574,7 +1575,7 @@ function extractRuntimeEmits(
}
function extractEventNames(
eventName: Identifier | RestElement,
eventName: ArrayPattern | Identifier | ObjectPattern | RestElement,
emits: Set<string>
) {
if (
@ -1584,14 +1585,18 @@ function extractEventNames(
) {
const typeNode = eventName.typeAnnotation.typeAnnotation
if (typeNode.type === 'TSLiteralType') {
if (typeNode.literal.type !== 'UnaryExpression') {
if (
typeNode.literal.type !== 'UnaryExpression' &&
typeNode.literal.type !== 'TemplateLiteral'
) {
emits.add(String(typeNode.literal.value))
}
} else if (typeNode.type === 'TSUnionType') {
for (const t of typeNode.types) {
if (
t.type === 'TSLiteralType' &&
t.literal.type !== 'UnaryExpression'
t.literal.type !== 'UnaryExpression' &&
t.literal.type !== 'TemplateLiteral'
) {
emits.add(String(t.literal.value))
}
@ -1782,7 +1787,7 @@ function getObjectOrArrayExpressionKeys(value: Node): string[] {
const templateUsageCheckCache = new LRU<string, string>(512)
function resolveTemplateUsageCheckString(sfc: SFCDescriptor) {
function resolveTemplateUsageCheckString(sfc: SFCDescriptor, isTS: boolean) {
const { content } = sfc.template!
const cached = templateUsageCheckCache.get(content)
if (cached) {
@ -1802,6 +1807,8 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) {
if (dirRE.test(name)) {
const baseName = onRE.test(name)
? 'on'
: slotRE.test(name)
? 'slot'
: bindRE.test(name)
? 'bind'
: name.replace(dirRE, '')
@ -1809,15 +1816,17 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) {
code += `,v${capitalize(camelize(baseName))}`
}
if (value) {
code += `,${processExp(value, baseName)}`
code += `,${processExp(value, isTS, baseName)}`
}
} else if (name === 'ref') {
code += `,${value}`
}
}
},
chars(text) {
const res = parseText(text)
if (res) {
code += `,${processExp(res.expression)}`
code += `,${processExp(res.expression, isTS)}`
}
}
})
@ -1829,17 +1838,17 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) {
const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/
function processExp(exp: string, dir?: string): string {
if (/ as\s+\w|<.*>|:/.test(exp)) {
function processExp(exp: string, isTS: boolean, dir?: string): string {
if (isTS && / as\s+\w|<.*>|:/.test(exp)) {
if (dir === 'slot') {
exp = `(${exp})=>{}`
} else if (dir === 'on') {
exp = `()=>{${exp}}`
exp = `()=>{return ${exp}}`
} else if (dir === 'for') {
const inMatch = exp.match(forAliasRE)
if (inMatch) {
const [, LHS, RHS] = inMatch
return processExp(`(${LHS})=>{}`) + processExp(RHS)
return processExp(`(${LHS})=>{}`, true) + processExp(RHS, true)
}
}
let ret = ''
@ -1867,36 +1876,38 @@ function stripTemplateString(str: string): string {
return ''
}
function isImportUsed(local: string, sfc: SFCDescriptor): boolean {
function isImportUsed(
local: string,
sfc: SFCDescriptor,
isTS: boolean
): boolean {
return new RegExp(
// #4274 escape $ since it's a special char in regex
// (and is the only regex special char that is valid in identifiers)
`[^\\w$_]${local.replace(/\$/g, '\\$')}[^\\w$_]`
).test(resolveTemplateUsageCheckString(sfc))
).test(resolveTemplateUsageCheckString(sfc, isTS))
}
/**
* Note: this comparison assumes the prev/next script are already identical,
* and only checks the special case where <script setup lang="ts"> unused import
* and only checks the special case where <script setup> unused import
* pruning result changes due to template changes.
*/
export function hmrShouldReload(
prevImports: Record<string, ImportBinding>,
next: SFCDescriptor
): boolean {
if (
!next.scriptSetup ||
(next.scriptSetup.lang !== 'ts' && next.scriptSetup.lang !== 'tsx')
) {
if (!next.scriptSetup) {
return false
}
const isTS = next.scriptSetup.lang === 'ts' || next.scriptSetup.lang === 'tsx'
// for each previous import, check if its used status remain the same based on
// the next descriptor's template
for (const key in prevImports) {
// if an import was previous unused, but now is used, we need to force
// reload so that the script now includes that import.
if (!prevImports[key].isUsedInTemplate && isImportUsed(key, next)) {
if (!prevImports[key].isUsedInTemplate && isImportUsed(key, next, isTS)) {
return true
}
}

View File

@ -6,6 +6,13 @@ export { compileScript } from './compileScript'
export { generateCodeFrame } from 'compiler/codeframe'
export { rewriteDefault } from './rewriteDefault'
// For backwards compat only. Some existing tools like
// fork-ts-checker-webpack-plugin relies on its presence for differentiating
// between Vue 2 and Vue 3.
// ref #12719
// ref https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/issues/765
export { parseComponent } from './parseComponent'
// types
export { SFCParseOptions } from './parse'
export { CompilerOptions, WarningMessage } from 'types/compiler'

View File

@ -42,8 +42,14 @@ export function rewriteDefault(
}).program.body
ast.forEach(node => {
if (node.type === 'ExportDefaultDeclaration') {
if (node.declaration.type === 'ClassDeclaration') {
s.overwrite(node.start!, node.declaration.id.start!, `class `)
if (node.declaration.type === 'ClassDeclaration' && node.declaration.id) {
let start: number =
node.declaration.decorators && node.declaration.decorators.length > 0
? node.declaration.decorators[
node.declaration.decorators.length - 1
].end!
: node.start!
s.overwrite(start, node.declaration.id.start!, ` class `)
s.append(`\nconst ${as} = ${node.declaration.id.name}`)
} else {
s.overwrite(node.start!, node.declaration.start!, `const ${as} = `)

View File

@ -1,6 +1,5 @@
import { PluginCreator, Rule, AtRule } from 'postcss'
import selectorParser from 'postcss-selector-parser'
import { warn } from '../warn'
const animationNameRE = /^(-\w+-)?animation-name$/
const animationRE = /^(-\w+-)?animation$/
@ -94,10 +93,10 @@ function rewriteSelector(
) {
n.value = ' '
n.spaces.before = n.spaces.after = ''
warn(
`the >>> and /deep/ combinators have been deprecated. ` +
`Use :deep() instead.`
)
// warn(
// `the >>> and /deep/ combinators have been deprecated. ` +
// `Use :deep() instead.`
// )
return false
}
@ -126,12 +125,12 @@ function rewriteSelector(
}
selector.removeChild(n)
} else {
// DEPRECATED usage
// DEPRECATED usage in v3
// .foo ::v-deep .bar -> .foo[xxxxxxx] .bar
warn(
`::v-deep usage as a combinator has ` +
`been deprecated. Use :deep(<inner-selector>) instead.`
)
// warn(
// `::v-deep usage as a combinator has ` +
// `been deprecated. Use :deep(<inner-selector>) instead.`
// )
const prev = selector.at(selector.index(n) - 1)
if (prev && isSpaceCombinator(prev)) {
selector.removeChild(prev)

View File

@ -1,4 +1,4 @@
// Vitest Snapshot v1
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`SFC analyze <script> bindings > auto name inference > basic 1`] = `
"export default {
@ -20,7 +20,7 @@ exports[`SFC analyze <script> bindings > auto name inference > do not overwrite
export default /*#__PURE__*/Object.assign(__default__, {
setup(__props) {
const a = 1
return { a, defineComponent }
return { a }
}
})"
@ -93,7 +93,7 @@ exports[`SFC compile <script setup> > <script> and <script setup> co-usage > scr
"import { defineComponent as _defineComponent } from 'vue'
const __default__ = {
name: \\"test\\"
name: "test"
}
import { x } from './x'
@ -212,7 +212,7 @@ export default {
props: propsModel,
setup(__props) {
const props = __props
const props = __props;
@ -229,7 +229,7 @@ export default {
props: {},
setup(__props) {
const props = __props
const props = __props;
return { props, x }
@ -245,7 +245,7 @@ exports[`SFC compile <script setup> > defineProps() 1`] = `
},
setup(__props) {
const props = __props
const props = __props;
const bar = 1
@ -262,7 +262,7 @@ exports[`SFC compile <script setup> > defineProps/defineEmits in multi-variable
emits: ['a'],
setup(__props, { emit }) {
const props = __props
const props = __props;
@ -278,7 +278,7 @@ exports[`SFC compile <script setup> > defineProps/defineEmits in multi-variable
emits: ['a'],
setup(__props, { emit }) {
const props = __props
const props = __props;
const a = 1;
@ -288,6 +288,22 @@ return { props, a, emit }
}"
`;
exports[`SFC compile <script setup> > defineProps/defineEmits in multi-variable declaration fix #6757 1`] = `
"export default {
props: ['item'],
emits: ['a'],
setup(__props, { emit }) {
const props = __props;
const a = 1;
return { a, props, emit }
}
}"
`;
exports[`SFC compile <script setup> > dev mode import usage check > TS annotations 1`] = `
"import { defineComponent as _defineComponent } from 'vue'
import { Foo, Baz, Qux, Fred } from './x'
@ -348,6 +364,20 @@ return { vMyDir }
})"
`;
exports[`SFC compile <script setup> > dev mode import usage check > imported ref as template ref 1`] = `
"import { defineComponent as _defineComponent } from 'vue'
import { aref } from './x'
export default /*#__PURE__*/_defineComponent({
setup(__props) {
return { aref }
}
})"
`;
exports[`SFC compile <script setup> > dev mode import usage check > js template string interpolations 1`] = `
"import { defineComponent as _defineComponent } from 'vue'
import { VAR, VAR2, VAR3 } from './x'
@ -537,7 +567,7 @@ exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (exp
export interface Emits { (e: 'foo' | 'bar'): void }
export default /*#__PURE__*/_defineComponent({
emits: [\\"foo\\", \\"bar\\"],
emits: ["foo", "bar"],
setup(__props, { emit }: { emit: ({ (e: 'foo' | 'bar'): void }), expose: any, slots: any, attrs: any }) {
@ -553,11 +583,27 @@ exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (exp
export type Emits = { (e: 'foo' | 'bar'): void }
export default /*#__PURE__*/_defineComponent({
emits: [\\"foo\\", \\"bar\\"],
emits: ["foo", "bar"],
setup(__props, { emit }: { emit: ({ (e: 'foo' | 'bar'): void }), expose: any, slots: any, attrs: any }) {
return { emit }
}
})"
`;
exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (interface ts type) 1`] = `
"import { defineComponent as _defineComponent } from 'vue'
interface Emits { (e: 'foo'): void }
export default /*#__PURE__*/_defineComponent({
emits: ['foo'],
setup(__props, { emit }) {
return { emit }
}
@ -569,7 +615,7 @@ exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (int
interface Emits { (e: 'foo' | 'bar'): void }
export default /*#__PURE__*/_defineComponent({
emits: [\\"foo\\", \\"bar\\"],
emits: ["foo", "bar"],
setup(__props, { emit }: { emit: ({ (e: 'foo' | 'bar'): void }), expose: any, slots: any, attrs: any }) {
@ -585,7 +631,7 @@ exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (ref
export type Emits = (e: 'foo' | 'bar') => void
export default /*#__PURE__*/_defineComponent({
emits: [\\"foo\\", \\"bar\\"],
emits: ["foo", "bar"],
setup(__props, { emit }: { emit: ((e: 'foo' | 'bar') => void), expose: any, slots: any, attrs: any }) {
@ -601,7 +647,7 @@ exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (ref
type Emits = (e: 'foo' | 'bar') => void
export default /*#__PURE__*/_defineComponent({
emits: [\\"foo\\", \\"bar\\"],
emits: ["foo", "bar"],
setup(__props, { emit }: { emit: ((e: 'foo' | 'bar') => void), expose: any, slots: any, attrs: any }) {
@ -617,7 +663,7 @@ exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (typ
type Emits = { (e: 'foo' | 'bar'): void }
export default /*#__PURE__*/_defineComponent({
emits: [\\"foo\\", \\"bar\\"],
emits: ["foo", "bar"],
setup(__props, { emit }: { emit: ({ (e: 'foo' | 'bar'): void }), expose: any, slots: any, attrs: any }) {
@ -632,7 +678,7 @@ exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (typ
"import { defineComponent as _defineComponent } from 'vue'
export default /*#__PURE__*/_defineComponent({
emits: [\\"foo\\", \\"bar\\", \\"baz\\"],
emits: ["foo", "bar", "baz"],
setup(__props, { emit }: { emit: ({(e: 'foo' | 'bar'): void; (e: 'baz', id: number): void;}), expose: any, slots: any, attrs: any }) {
@ -647,7 +693,7 @@ exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type 1`]
"import { defineComponent as _defineComponent } from 'vue'
export default /*#__PURE__*/_defineComponent({
emits: [\\"foo\\", \\"bar\\"],
emits: ["foo", "bar"],
setup(__props, { emit }: { emit: ((e: 'foo' | 'bar') => void), expose: any, slots: any, attrs: any }) {
@ -803,7 +849,7 @@ export default /*#__PURE__*/_defineComponent({
emits: ['a', 'b'],
setup(__props, { emit }) {
const props = __props
const props = __props;
@ -862,9 +908,9 @@ exports[`SFC compile <script setup> > with TypeScript > runtime Enum in normal s
"import { defineComponent as _defineComponent } from 'vue'
enum Foo { A = 123 }
export enum D { D = \\"D\\" }
const enum C { C = \\"C\\" }
enum B { B = \\"B\\" }
export enum D { D = "D" }
const enum C { C = "C" }
enum B { B = "B" }
export default /*#__PURE__*/_defineComponent({
setup(__props) {
@ -892,7 +938,7 @@ const props = __props as {
foo?: string
bar?: number
baz: boolean
}
};
@ -914,7 +960,7 @@ export default /*#__PURE__*/_defineComponent({
},
setup(__props: any) {
const props = __props as { foo: string, bar?: number, baz: boolean, qux(): number }
const props = __props as { foo: string, bar?: number, baz: boolean, qux(): number };

View File

@ -1,11 +1,11 @@
// Vitest Snapshot v1
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`CSS vars injection > codegen > <script> w/ default export 1`] = `
"const __default__ = { setup() {} }
import { useCssVars as _useCssVars } from 'vue'
const __injectCSSVars__ = () => {
_useCssVars((_vm, _setup) => ({
\\"xxxxxxxx-color\\": (_vm.color)
"xxxxxxxx-color": (_vm.color)
}))}
const __setup__ = __default__.setup
__default__.setup = __setup__
@ -23,7 +23,7 @@ exports[`CSS vars injection > codegen > <script> w/ default export in strings/co
import { useCssVars as _useCssVars } from 'vue'
const __injectCSSVars__ = () => {
_useCssVars((_vm, _setup) => ({
\\"xxxxxxxx-color\\": (_vm.color)
"xxxxxxxx-color": (_vm.color)
}))}
const __setup__ = __default__.setup
__default__.setup = __setup__
@ -39,7 +39,7 @@ const __default__ = {}
import { useCssVars as _useCssVars } from 'vue'
const __injectCSSVars__ = () => {
_useCssVars((_vm, _setup) => ({
\\"xxxxxxxx-color\\": (_vm.color)
"xxxxxxxx-color": (_vm.color)
}))}
const __setup__ = __default__.setup
__default__.setup = __setup__
@ -56,7 +56,7 @@ export default {
setup(__props) {
_useCssVars((_vm, _setup) => ({
\\"xxxxxxxx-width\\": (_setup.width)
"xxxxxxxx-width": (_setup.width)
}))
const color = 'red';const width = 100
return { color, width }
@ -72,10 +72,10 @@ export default {
setup(__props) {
_useCssVars((_vm, _setup) => ({
\\"xxxxxxxx-foo\\": (_setup.foo),
\\"xxxxxxxx-foo____px_\\": (_setup.foo + 'px'),
\\"xxxxxxxx-_a___b____2____px_\\": ((_setup.a + _setup.b) / 2 + 'px'),
\\"xxxxxxxx-__a___b______2___a_\\": (((_setup.a + _setup.b)) / (2 * _setup.a))
"xxxxxxxx-foo": (_setup.foo),
"xxxxxxxx-foo____px_": (_setup.foo + 'px'),
"xxxxxxxx-_a___b____2____px_": ((_setup.a + _setup.b) / 2 + 'px'),
"xxxxxxxx-__a___b______2___a_": (((_setup.a + _setup.b)) / (2 * _setup.a))
}))
let a = 100
@ -95,7 +95,7 @@ export default {
setup(__props) {
_useCssVars((_vm, _setup) => ({
\\"xxxxxxxx-color\\": (_setup.color)
"xxxxxxxx-color": (_setup.color)
}))
const color = 'red'
return { color }
@ -111,7 +111,7 @@ export default {
setup(__props) {
_useCssVars((_vm, _setup) => ({
\\"xxxxxxxx-color\\": (_setup.color)
"xxxxxxxx-color": (_setup.color)
}))
const color = 'red'
@ -128,8 +128,8 @@ const __default__ = {}
import { useCssVars as _useCssVars } from 'vue'
const __injectCSSVars__ = () => {
_useCssVars((_vm, _setup) => ({
\\"xxxxxxxx-color\\": (_vm.color),
\\"xxxxxxxx-font_size\\": (_vm.font.size)
"xxxxxxxx-color": (_vm.color),
"xxxxxxxx-font_size": (_vm.font.size)
}))}
const __setup__ = __default__.setup
__default__.setup = __setup__
@ -150,9 +150,9 @@ export default {
setup(__props) {
_useCssVars((_vm, _setup) => ({
\\"xxxxxxxx-color\\": (_setup.color),
\\"xxxxxxxx-size\\": (_setup.size),
\\"xxxxxxxx-foo\\": (_vm.foo)
"xxxxxxxx-color": (_setup.color),
"xxxxxxxx-size": (_setup.size),
"xxxxxxxx-foo": (_vm.foo)
}))
const color = 'red'
@ -178,7 +178,7 @@ exports[`CSS vars injection > w/ normal <script> binding analysis 1`] = `
import { useCssVars as _useCssVars } from 'vue'
const __injectCSSVars__ = () => {
_useCssVars((_vm, _setup) => ({
\\"xxxxxxxx-size\\": (_vm.size)
"xxxxxxxx-size": (_vm.size)
}))}
const __setup__ = __default__.setup
__default__.setup = __setup__

View File

@ -141,6 +141,21 @@ const myEmit = defineEmits(['foo', 'bar'])
expect(content).toMatch(`emits: ['a'],`)
})
// vuejs/core #6757
test('defineProps/defineEmits in multi-variable declaration fix #6757 ', () => {
const { content } = compile(`
<script setup>
const a = 1,
props = defineProps(['item']),
emit = defineEmits(['a']);
</script>
`)
assertCode(content)
expect(content).toMatch(`const a = 1;`) // test correct removal
expect(content).toMatch(`props: ['item'],`)
expect(content).toMatch(`emits: ['a'],`)
})
test('defineProps/defineEmits in multi-variable declaration (full removal)', () => {
const { content } = compile(`
<script setup>
@ -383,6 +398,19 @@ defineExpose({ foo: 123 })
assertCode(content)
})
test('imported ref as template ref', () => {
const { content } = compile(`
<script setup lang="ts">
import { aref } from './x'
</script>
<template>
<div ref="aref"></div>
</template>
`)
expect(content).toMatch(`return { aref }`)
assertCode(content)
})
test('vue interpolations', () => {
const { content } = compile(`
<script setup lang="ts">
@ -1081,6 +1109,19 @@ const emit = defineEmits(['a', 'b'])
expect(content).toMatch(`emits: ["foo", "bar"]`)
})
// https://github.com/vuejs/core/issues/5393
test('defineEmits w/ type (interface ts type)', () => {
const { content } = compile(`
<script setup lang="ts">
interface Emits { (e: 'foo'): void }
const emit: Emits = defineEmits(['foo'])
</script>
`)
assertCode(content)
expect(content).toMatch(`setup(__props, { emit }) {`)
expect(content).toMatch(`emits: ['foo']`)
})
test('runtime Enum', () => {
const { content, bindings } = compile(
`<script setup lang="ts">
@ -1571,7 +1612,23 @@ describe('SFC analyze <script> bindings', () => {
</script>
<template>
<div @click="$emit('update:a');"></div>
</tempalte>
</template>
`)
})
// #12841
test('should not error when performing ts expression check for v-slot destructured default value', () => {
compile(`
<script setup lang="ts">
import FooComp from './Foo.vue'
</script>
<template>
<FooComp>
<template #bar="{ bar = { baz: '' } }">
{{ bar.baz }}
</template>
</FooComp>
</template>
`)
})
})

View File

@ -31,21 +31,21 @@ it('should work', () => {
var _vm = this,
_c = _vm._self._c
return _c(
\\"div\\",
{ attrs: { id: \\"app\\" } },
"div",
{ attrs: { id: "app" } },
[
_c(\\"div\\", { style: { color: _vm.color } }, [_vm._v(_vm._s(_vm.foo))]),
_vm._v(\\" \\"),
_c("div", { style: { color: _vm.color } }, [_vm._v(_vm._s(_vm.foo))]),
_vm._v(" "),
_vm._l(_vm.list, function (i) {
return _c(\\"p\\", [_vm._v(_vm._s(i))])
return _c("p", [_vm._v(_vm._s(i))])
}),
_vm._v(\\" \\"),
_c(\\"foo\\", {
_vm._v(" "),
_c("foo", {
inlineTemplate: {
render: function () {
var _vm = this,
_c = _vm._self._c
return _c(\\"div\\", [_vm._v(_vm._s(_vm.bar))])
return _c("div", [_vm._v(_vm._s(_vm.bar))])
},
staticRenderFns: [],
},
@ -81,10 +81,10 @@ it('setup bindings', () => {
_c = _vm._self._c,
_setup = _vm._self._setupProxy
return _c(
\\"div\\",
"div",
{
on: {
click: function (\$event) {
click: function ($event) {
_setup.count++
},
},

View File

@ -190,7 +190,7 @@ describe('compiler sfc: rewriteDefault', () => {
).toMatchInlineSnapshot(`
"/*
export default class Foo {}*/
class Bar {}
class Bar {}
const script = Bar"
`)
})
@ -206,7 +206,10 @@ describe('compiler sfc: rewriteDefault', () => {
test('@Component\nexport default class w/ comments', async () => {
expect(
rewriteDefault(`// export default\n@Component\nexport default class Foo {}`, 'script')
rewriteDefault(
`// export default\n@Component\nexport default class Foo {}`,
'script'
)
).toMatchInlineSnapshot(`
"// export default
@Component
@ -231,15 +234,78 @@ describe('compiler sfc: rewriteDefault', () => {
test('@Component\nexport default class w/ comments 3', async () => {
expect(
rewriteDefault(
`/*\n@Component\nexport default class Foo {}*/\n` + `export default class Bar {}`,
`/*\n@Component\nexport default class Foo {}*/\n` +
`export default class Bar {}`,
'script'
)
).toMatchInlineSnapshot(`
"/*
@Component
export default class Foo {}*/
class Bar {}
class Bar {}
const script = Bar"
`)
})
// #13060
test('@Component\nexport default class w/ comments 4', async () => {
expect(
rewriteDefault(
`@Component
export default class App extends Vue {
/* default <- This word means my component is not built correctly */
@Prop({ type: String, required: true })
protected someString: string;
}`,
'script'
)
).toMatchInlineSnapshot(`
"@Component
class App extends Vue {
/* default <- This word means my component is not built correctly */
@Prop({ type: String, required: true })
protected someString: string;
}
const script = App"
`)
})
// #12892
test('@Component\nexport default class w/ comments 5', async () => {
expect(
rewriteDefault(
`@Component({})
export default class HelloWorld extends Vue {
test = "";
mounted() {
console.log("mounted!");
this.test = "Hallo Welt!";
}
exportieren(): void {
// do nothing
}
defaultWert(): void {
// do nothing
}
}`,
'script',
['typescript', 'decorators-legacy']
)
).toMatchInlineSnapshot(`
"@Component({}) class HelloWorld extends Vue {
test = "";
mounted() {
console.log("mounted!");
this.test = "Hallo Welt!";
}
exportieren(): void {
// do nothing
}
defaultWert(): void {
// do nothing
}
}
const script = HelloWorld"
`)
})
})

View File

@ -1,6 +1,6 @@
{
"name": "vue-server-renderer",
"version": "2.7.10",
"version": "2.7.16",
"description": "server renderer for Vue 2.0",
"main": "index.js",
"types": "types/index.d.ts",
@ -38,7 +38,7 @@
"file-loader": "^3.0.1",
"memory-fs": "^0.5.0",
"vue": "file:../..",
"webpack": "^4.46.0"
"webpack": "^4.47.0"
},
"homepage": "https://github.com/vuejs/vue/tree/dev/packages/vue-server-renderer#readme"
}

View File

@ -34,8 +34,6 @@ export class RenderContext {
renderStates: Array<RenderState>
write: (text: string, next: Function) => void
renderNode: (node: VNode, isRoot: boolean, context: RenderContext) => void
//@ts-expect-error
next: () => void
done: (err?: Error) => void
modules: Array<(node: VNode) => string | null>
@ -67,11 +65,9 @@ export class RenderContext {
this.get = cache && normalizeAsync(cache, 'get')
this.has = cache && normalizeAsync(cache, 'has')
//@ts-expect-error
this.next = this.next.bind(this)
}
//@ts-expect-error
next() {
// eslint-disable-next-line
while (true) {

View File

@ -2,9 +2,10 @@
import Vue from 'vue'
import renderToString from 'server/index-basic'
import { _it } from './utils'
describe('SSR: basicRenderer', () => {
it('should work', done => {
_it('should work', done => {
renderToString(
new Vue({
template: `
@ -61,7 +62,7 @@ describe('SSR: basicRenderer', () => {
})
// #5941
it('should work properly when accessing $ssrContext in root component', done => {
_it('should work properly when accessing $ssrContext in root component', done => {
let ssrContext
renderToString(
new Vue({

View File

@ -4,7 +4,7 @@ import { createWebpackBundleRenderer } from './compile-with-webpack'
describe('SSR: bundle renderer', () => {
createAssertions(true)
createAssertions(false)
// createAssertions(false)
})
function createAssertions(runInNewContext) {

View File

@ -2,10 +2,12 @@
import Vue from 'vue'
import { createRenderer } from 'server/index'
import { _it } from './utils'
const { renderToStream } = createRenderer()
describe('SSR: renderToStream', () => {
it('should render to a stream', done => {
_it('should render to a stream', done => {
const stream = renderToStream(
new Vue({
template: `
@ -74,7 +76,7 @@ describe('SSR: renderToStream', () => {
})
})
it('should catch error', done => {
_it('should catch error', done => {
const stream = renderToStream(
new Vue({
render() {
@ -90,7 +92,7 @@ describe('SSR: renderToStream', () => {
stream.on('data', _ => _)
})
it('should not mingle two components', done => {
_it('should not mingle two components', done => {
const padding = new Array(20000).join('x')
const component1 = new Vue({
template: `<div>${padding}<div></div></div>`,
@ -114,7 +116,7 @@ describe('SSR: renderToStream', () => {
stream2.read(1)
})
it('should call context.rendered', done => {
_it('should call context.rendered', done => {
let a = 0
const stream = renderToStream(
new Vue({

View File

@ -3,10 +3,12 @@
import Vue from 'vue'
import VM from 'vm'
import { createRenderer } from 'server/index'
import { _it } from './utils'
const { renderToString } = createRenderer()
describe('SSR: renderToString', () => {
it('static attributes', done => {
_it('static attributes', done => {
renderVmWithOptions(
{
template: '<div id="foo" bar="123"></div>'
@ -20,7 +22,7 @@ describe('SSR: renderToString', () => {
)
})
it('unary tags', done => {
_it('unary tags', done => {
renderVmWithOptions(
{
template: '<input value="123">'
@ -34,7 +36,7 @@ describe('SSR: renderToString', () => {
)
})
it('dynamic attributes', done => {
_it('dynamic attributes', done => {
renderVmWithOptions(
{
template: '<div qux="quux" :id="foo" :bar="baz"></div>',
@ -52,7 +54,7 @@ describe('SSR: renderToString', () => {
)
})
it('static class', done => {
_it('static class', done => {
renderVmWithOptions(
{
template: '<div class="foo bar"></div>'
@ -66,7 +68,7 @@ describe('SSR: renderToString', () => {
)
})
it('dynamic class', done => {
_it('dynamic class', done => {
renderVmWithOptions(
{
template:
@ -86,7 +88,7 @@ describe('SSR: renderToString', () => {
)
})
it('custom component class', done => {
_it('custom component class', done => {
renderVmWithOptions(
{
template: '<div><cmp class="cmp"></cmp></div>',
@ -105,7 +107,7 @@ describe('SSR: renderToString', () => {
)
})
it('nested component class', done => {
_it('nested component class', done => {
renderVmWithOptions(
{
template: '<cmp class="outer" :class="cls"></cmp>',
@ -135,7 +137,7 @@ describe('SSR: renderToString', () => {
)
})
it('dynamic style', done => {
_it('dynamic style', done => {
renderVmWithOptions(
{
template:
@ -154,7 +156,7 @@ describe('SSR: renderToString', () => {
)
})
it('dynamic string style', done => {
_it('dynamic string style', done => {
renderVmWithOptions(
{
template: '<div :style="style"></div>',
@ -171,7 +173,7 @@ describe('SSR: renderToString', () => {
)
})
it('auto-prefixed style value as array', done => {
_it('auto-prefixed style value as array', done => {
renderVmWithOptions(
{
template: '<div :style="style"></div>',
@ -190,7 +192,7 @@ describe('SSR: renderToString', () => {
)
})
it('custom component style', done => {
_it('custom component style', done => {
renderVmWithOptions(
{
template: '<section><comp :style="style"></comp></section>',
@ -212,7 +214,7 @@ describe('SSR: renderToString', () => {
)
})
it('nested custom component style', done => {
_it('nested custom component style', done => {
renderVmWithOptions(
{
template: '<comp style="color: blue" :style="style"></comp>',
@ -240,7 +242,7 @@ describe('SSR: renderToString', () => {
)
})
it('component style not passed to child', done => {
_it('component style not passed to child', done => {
renderVmWithOptions(
{
template: '<comp :style="style"></comp>',
@ -262,7 +264,7 @@ describe('SSR: renderToString', () => {
)
})
it('component style not passed to slot', done => {
_it('component style not passed to slot', done => {
renderVmWithOptions(
{
template:
@ -285,7 +287,7 @@ describe('SSR: renderToString', () => {
)
})
it('attrs merging on components', done => {
_it('attrs merging on components', done => {
const Test = {
render: h =>
h('div', {
@ -308,7 +310,7 @@ describe('SSR: renderToString', () => {
)
})
it('domProps merging on components', done => {
_it('domProps merging on components', done => {
const Test = {
render: h =>
h('div', {
@ -331,7 +333,7 @@ describe('SSR: renderToString', () => {
)
})
it('v-show directive render', done => {
_it('v-show directive render', done => {
renderVmWithOptions(
{
template: '<div v-show="false"><span>inner</span></div>'
@ -345,7 +347,7 @@ describe('SSR: renderToString', () => {
)
})
it('v-show directive merge with style', done => {
_it('v-show directive merge with style', done => {
renderVmWithOptions(
{
template:
@ -360,7 +362,7 @@ describe('SSR: renderToString', () => {
)
})
it('v-show directive not passed to child', done => {
_it('v-show directive not passed to child', done => {
renderVmWithOptions(
{
template: '<foo v-show="false"></foo>',
@ -379,7 +381,7 @@ describe('SSR: renderToString', () => {
)
})
it('v-show directive not passed to slot', done => {
_it('v-show directive not passed to slot', done => {
renderVmWithOptions(
{
template: '<foo v-show="false"><span>inner</span></foo>',
@ -398,7 +400,7 @@ describe('SSR: renderToString', () => {
)
})
it('v-show directive merging on components', done => {
_it('v-show directive merging on components', done => {
renderVmWithOptions(
{
template: '<foo v-show="false"></foo>',
@ -430,7 +432,7 @@ describe('SSR: renderToString', () => {
)
})
it('text interpolation', done => {
_it('text interpolation', done => {
renderVmWithOptions(
{
template: '<div>{{ foo }} side {{ bar }}</div>',
@ -448,7 +450,7 @@ describe('SSR: renderToString', () => {
)
})
it('v-html on root', done => {
_it('v-html on root', done => {
renderVmWithOptions(
{
template: '<div v-html="text"></div>',
@ -465,7 +467,7 @@ describe('SSR: renderToString', () => {
)
})
it('v-text on root', done => {
_it('v-text on root', done => {
renderVmWithOptions(
{
template: '<div v-text="text"></div>',
@ -482,7 +484,7 @@ describe('SSR: renderToString', () => {
)
})
it('v-html', done => {
_it('v-html', done => {
renderVmWithOptions(
{
template: '<div><div v-html="text"></div></div>',
@ -499,7 +501,7 @@ describe('SSR: renderToString', () => {
)
})
it('v-html with null value', done => {
_it('v-html with null value', done => {
renderVmWithOptions(
{
template: '<div><div v-html="text"></div></div>',
@ -516,7 +518,7 @@ describe('SSR: renderToString', () => {
)
})
it('v-text', done => {
_it('v-text', done => {
renderVmWithOptions(
{
template: '<div><div v-text="text"></div></div>',
@ -533,7 +535,7 @@ describe('SSR: renderToString', () => {
)
})
it('v-text with null value', done => {
_it('v-text with null value', done => {
renderVmWithOptions(
{
template: '<div><div v-text="text"></div></div>',
@ -550,7 +552,7 @@ describe('SSR: renderToString', () => {
)
})
it('child component (hoc)', done => {
_it('child component (hoc)', done => {
renderVmWithOptions(
{
template: '<child class="foo" :msg="msg"></child>',
@ -579,7 +581,7 @@ describe('SSR: renderToString', () => {
)
})
it('has correct lifecycle during render', done => {
_it('has correct lifecycle during render', done => {
let lifecycleCount = 1
renderVmWithOptions(
{
@ -622,7 +624,7 @@ describe('SSR: renderToString', () => {
)
})
it('computed properties', done => {
_it('computed properties', done => {
renderVmWithOptions(
{
template: '<div>{{ b }}</div>',
@ -648,7 +650,7 @@ describe('SSR: renderToString', () => {
)
})
it('renders async component', done => {
_it('renders async component', done => {
renderVmWithOptions(
{
template: `
@ -683,7 +685,7 @@ describe('SSR: renderToString', () => {
)
})
it('renders async component (Promise, nested)', done => {
_it('renders async component (Promise, nested)', done => {
const Foo = () =>
Promise.resolve({
render: h => h('div', [h('span', 'foo'), h(Bar)])
@ -706,7 +708,7 @@ describe('SSR: renderToString', () => {
)
})
it('renders async component (ES module)', done => {
_it('renders async component (ES module)', done => {
const Foo = () =>
Promise.resolve({
__esModule: true,
@ -735,7 +737,7 @@ describe('SSR: renderToString', () => {
)
})
it('renders async component (hoc)', done => {
_it('renders async component (hoc)', done => {
renderVmWithOptions(
{
template: '<test-async></test-async>',
@ -761,7 +763,7 @@ describe('SSR: renderToString', () => {
)
})
it('renders async component (functional, single node)', done => {
_it('renders async component (functional, single node)', done => {
renderVmWithOptions(
{
template: `
@ -793,7 +795,7 @@ describe('SSR: renderToString', () => {
)
})
it('renders async component (functional, multiple nodes)', done => {
_it('renders async component (functional, multiple nodes)', done => {
renderVmWithOptions(
{
template: `
@ -831,7 +833,7 @@ describe('SSR: renderToString', () => {
)
})
it('renders nested async functional component', done => {
_it('renders nested async functional component', done => {
renderVmWithOptions(
{
template: `
@ -877,7 +879,7 @@ describe('SSR: renderToString', () => {
)
})
it('should catch async component error', done => {
_it('should catch async component error', done => {
renderToString(
new Vue({
template: '<test-async></test-async>',
@ -900,7 +902,7 @@ describe('SSR: renderToString', () => {
})
// #11963, #10391
it('renders async children passed in slots', done => {
_it('renders async children passed in slots', done => {
const Parent = {
template: `<div><slot name="child"/></div>`
}
@ -930,7 +932,7 @@ describe('SSR: renderToString', () => {
)
})
it('everything together', done => {
_it('everything together', done => {
renderVmWithOptions(
{
template: `
@ -985,7 +987,7 @@ describe('SSR: renderToString', () => {
)
})
it('normal attr', done => {
_it('normal attr', done => {
renderVmWithOptions(
{
template: `
@ -1013,7 +1015,7 @@ describe('SSR: renderToString', () => {
)
})
it('enumerated attr', done => {
_it('enumerated attr', done => {
renderVmWithOptions(
{
template: `
@ -1043,7 +1045,7 @@ describe('SSR: renderToString', () => {
)
})
it('boolean attr', done => {
_it('boolean attr', done => {
renderVmWithOptions(
{
template: `
@ -1069,7 +1071,7 @@ describe('SSR: renderToString', () => {
)
})
it('v-bind object', done => {
_it('v-bind object', done => {
renderVmWithOptions(
{
data: {
@ -1086,7 +1088,7 @@ describe('SSR: renderToString', () => {
)
})
it('custom directives on raw element', done => {
_it('custom directives on raw element', done => {
const renderer = createRenderer({
directives: {
'class-prefixer': (node, dir) => {
@ -1129,7 +1131,7 @@ describe('SSR: renderToString', () => {
)
})
it('custom directives on component', done => {
_it('custom directives on component', done => {
const Test = {
template: '<span>hello world</span>'
}
@ -1161,7 +1163,7 @@ describe('SSR: renderToString', () => {
)
})
it('custom directives on element root of a component', done => {
_it('custom directives on element root of a component', done => {
const Test = {
template:
'<span v-class-prefixer="\'my\'" class="class1" :class="\'class2\'">hello world</span>'
@ -1193,7 +1195,7 @@ describe('SSR: renderToString', () => {
)
})
it('custom directives on element with parent element', done => {
_it('custom directives on element with parent element', done => {
const renderer = createRenderer({
directives: {
'class-prefixer': (node, dir) => {
@ -1221,26 +1223,29 @@ describe('SSR: renderToString', () => {
)
})
it('should not warn for custom directives that do not have server-side implementation', done => {
renderToString(
new Vue({
directives: {
test: {
bind() {
// noop
_it(
'should not warn for custom directives that do not have server-side implementation',
done => {
renderToString(
new Vue({
directives: {
test: {
bind() {
// noop
}
}
}
},
template: '<div v-test></div>'
}),
() => {
expect('Failed to resolve directive: test').not.toHaveBeenWarned()
done()
}
)
})
},
template: '<div v-test></div>'
}),
() => {
expect('Failed to resolve directive: test').not.toHaveBeenWarned()
done()
}
)
}
)
it('_scopeId', done => {
_it('_scopeId', done => {
renderVmWithOptions(
{
_scopeId: '_v-parent',
@ -1268,7 +1273,7 @@ describe('SSR: renderToString', () => {
)
})
it('_scopeId on slot content', done => {
_it('_scopeId on slot content', done => {
renderVmWithOptions(
{
_scopeId: '_v-parent',
@ -1294,7 +1299,7 @@ describe('SSR: renderToString', () => {
)
})
it('comment nodes', done => {
_it('comment nodes', done => {
renderVmWithOptions(
{
template: '<div><transition><div v-if="false"></div></transition></div>'
@ -1308,7 +1313,7 @@ describe('SSR: renderToString', () => {
)
})
it('should catch error', done => {
_it('should catch error', done => {
renderToString(
new Vue({
render() {
@ -1323,7 +1328,7 @@ describe('SSR: renderToString', () => {
)
})
it('default value Foreign Function', () => {
_it('default value Foreign Function', () => {
const FunctionConstructor = VM.runInNewContext('Function')
const func = () => 123
const vm = new Vue({
@ -1340,7 +1345,7 @@ describe('SSR: renderToString', () => {
expect(vm.a).toBe(func)
})
it('should prevent xss in attributes', done => {
_it('should prevent xss in attributes', done => {
renderVmWithOptions(
{
data: {
@ -1359,7 +1364,7 @@ describe('SSR: renderToString', () => {
)
})
it('should prevent xss in attribute names', done => {
_it('should prevent xss in attribute names', done => {
renderVmWithOptions(
{
data: {
@ -1378,7 +1383,7 @@ describe('SSR: renderToString', () => {
)
})
it('should prevent xss in attribute names (optimized)', done => {
_it('should prevent xss in attribute names (optimized)', done => {
renderVmWithOptions(
{
data: {
@ -1399,22 +1404,25 @@ describe('SSR: renderToString', () => {
)
})
it('should prevent script xss with v-bind object syntax + array value', done => {
renderVmWithOptions(
{
data: {
test: ['"><script>alert(1)</script><!--"']
_it(
'should prevent script xss with v-bind object syntax + array value',
done => {
renderVmWithOptions(
{
data: {
test: ['"><script>alert(1)</script><!--"']
},
template: `<div v-bind="{ test }"></div>`
},
template: `<div v-bind="{ test }"></div>`
},
res => {
expect(res).not.toContain(`<script>alert(1)</script>`)
done()
}
)
})
res => {
expect(res).not.toContain(`<script>alert(1)</script>`)
done()
}
)
}
)
it('v-if', done => {
_it('v-if', done => {
renderVmWithOptions(
{
template: `
@ -1433,7 +1441,7 @@ describe('SSR: renderToString', () => {
)
})
it('v-for', done => {
_it('v-for', done => {
renderVmWithOptions(
{
template: `
@ -1452,7 +1460,7 @@ describe('SSR: renderToString', () => {
)
})
it('template v-if', done => {
_it('template v-if', done => {
renderVmWithOptions(
{
template: `
@ -1473,7 +1481,7 @@ describe('SSR: renderToString', () => {
)
})
it('template v-for', done => {
_it('template v-for', done => {
renderVmWithOptions(
{
template: `
@ -1494,7 +1502,7 @@ describe('SSR: renderToString', () => {
)
})
it('with inheritAttrs: false + $attrs', done => {
_it('with inheritAttrs: false + $attrs', done => {
renderVmWithOptions(
{
template: `<foo id="a"/>`,
@ -1514,7 +1522,7 @@ describe('SSR: renderToString', () => {
)
})
it('should escape static strings', done => {
_it('should escape static strings', done => {
renderVmWithOptions(
{
template: `<div>&lt;foo&gt;</div>`
@ -1526,7 +1534,7 @@ describe('SSR: renderToString', () => {
)
})
it('should not cache computed properties', done => {
_it('should not cache computed properties', done => {
renderVmWithOptions(
{
template: `<div>{{ foo }}</div>`,
@ -1549,7 +1557,7 @@ describe('SSR: renderToString', () => {
})
// #8977
it('should call computed properties with vm as first argument', done => {
_it('should call computed properties with vm as first argument', done => {
renderToString(
new Vue({
data: {
@ -1571,7 +1579,7 @@ describe('SSR: renderToString', () => {
)
})
it('return Promise', async () => {
_it('return Promise', async () => {
await renderToString(
new Vue({
template: `<div>{{ foo }}</div>`,
@ -1582,7 +1590,7 @@ describe('SSR: renderToString', () => {
})
})
it('return Promise (error)', async () => {
_it('return Promise (error)', async () => {
await renderToString(
new Vue({
render() {
@ -1595,7 +1603,7 @@ describe('SSR: renderToString', () => {
})
})
it('should catch template compilation error', done => {
_it('should catch template compilation error', done => {
renderToString(
new Vue({
template: `<div></div><div></div>`
@ -1610,7 +1618,7 @@ describe('SSR: renderToString', () => {
})
// #6907
it('should not optimize root if conditions', done => {
_it('should not optimize root if conditions', done => {
renderVmWithOptions(
{
data: { foo: 123 },
@ -1625,7 +1633,7 @@ describe('SSR: renderToString', () => {
)
})
it('render muted properly', done => {
_it('render muted properly', done => {
renderVmWithOptions(
{
template: '<video muted></video>'
@ -1639,7 +1647,7 @@ describe('SSR: renderToString', () => {
)
})
it('render v-model with textarea', done => {
_it('render v-model with textarea', done => {
renderVmWithOptions(
{
data: { foo: 'bar' },
@ -1652,7 +1660,7 @@ describe('SSR: renderToString', () => {
)
})
it('render v-model with textarea (non-optimized)', done => {
_it('render v-model with textarea (non-optimized)', done => {
renderVmWithOptions(
{
render(h) {
@ -1672,7 +1680,7 @@ describe('SSR: renderToString', () => {
)
})
it('render v-model with <select> (value binding)', done => {
_it('render v-model with <select> (value binding)', done => {
renderVmWithOptions(
{
data: {
@ -1702,7 +1710,7 @@ describe('SSR: renderToString', () => {
)
})
it('render v-model with <select> (static value)', done => {
_it('render v-model with <select> (static value)', done => {
renderVmWithOptions(
{
data: {
@ -1729,7 +1737,7 @@ describe('SSR: renderToString', () => {
)
})
it('render v-model with <select> (text as value)', done => {
_it('render v-model with <select> (text as value)', done => {
renderVmWithOptions(
{
data: {
@ -1760,7 +1768,7 @@ describe('SSR: renderToString', () => {
})
// #7223
it('should not double escape attribute values', done => {
_it('should not double escape attribute values', done => {
renderVmWithOptions(
{
template: `
@ -1777,7 +1785,7 @@ describe('SSR: renderToString', () => {
})
// #7859
it('should not double escape class values', done => {
_it('should not double escape class values', done => {
renderVmWithOptions(
{
template: `
@ -1793,7 +1801,7 @@ describe('SSR: renderToString', () => {
)
})
it('should expose ssr helpers on functional context', done => {
_it('should expose ssr helpers on functional context', done => {
let called = false
renderVmWithOptions(
{
@ -1815,7 +1823,7 @@ describe('SSR: renderToString', () => {
)
})
it('should support serverPrefetch option', done => {
_it('should support serverPrefetch option', done => {
renderVmWithOptions(
{
template: `
@ -1840,7 +1848,7 @@ describe('SSR: renderToString', () => {
)
})
it('should support serverPrefetch option (nested)', done => {
_it('should support serverPrefetch option (nested)', done => {
renderVmWithOptions(
{
template: `
@ -1890,7 +1898,7 @@ describe('SSR: renderToString', () => {
)
})
it('should support serverPrefetch option (nested async)', done => {
_it('should support serverPrefetch option (nested async)', done => {
renderVmWithOptions(
{
template: `
@ -1942,7 +1950,7 @@ describe('SSR: renderToString', () => {
)
})
it('should merge serverPrefetch option', done => {
_it('should merge serverPrefetch option', done => {
const mixin = {
data: {
message: ''
@ -1986,29 +1994,32 @@ describe('SSR: renderToString', () => {
)
})
it(`should skip serverPrefetch option that doesn't return a promise`, done => {
renderVmWithOptions(
{
template: `
_it(
`should skip serverPrefetch option that doesn't return a promise`,
done => {
renderVmWithOptions(
{
template: `
<div>{{ count }}</div>
`,
data: {
count: 0
data: {
count: 0
},
serverPrefetch() {
setTimeout(() => {
this.count = 42
}, 1)
}
},
serverPrefetch() {
setTimeout(() => {
this.count = 42
}, 1)
result => {
expect(result).toContain('<div data-server-rendered="true">0</div>')
done()
}
},
result => {
expect(result).toContain('<div data-server-rendered="true">0</div>')
done()
}
)
})
)
}
)
it('should call context.rendered', done => {
_it('should call context.rendered', done => {
let a = 0
renderToString(
new Vue({
@ -2028,7 +2039,7 @@ describe('SSR: renderToString', () => {
)
})
it('invalid style value', done => {
_it('invalid style value', done => {
renderVmWithOptions(
{
template: '<div :style="style"><p :style="style2"/></div>',
@ -2054,7 +2065,7 @@ describe('SSR: renderToString', () => {
)
})
it('numeric style value', done => {
_it('numeric style value', done => {
renderVmWithOptions(
{
template: '<div :style="style"></div>',
@ -2076,7 +2087,7 @@ describe('SSR: renderToString', () => {
)
})
it('handling max stack size limit', done => {
_it('handling max stack size limit', done => {
const vueInstance = new Vue({
template: `<div class="root">
<child v-for="(x, i) in items" :key="i"></child>
@ -2094,7 +2105,7 @@ describe('SSR: renderToString', () => {
renderToString(vueInstance, err => done(err))
})
it('undefined v-model with textarea', done => {
_it('undefined v-model with textarea', done => {
renderVmWithOptions(
{
render(h) {
@ -2116,7 +2127,7 @@ describe('SSR: renderToString', () => {
)
})
it('Options inheritAttrs in parent component', done => {
_it('Options inheritAttrs in parent component', done => {
const childComponent = {
template: `<div>{{ someProp }}</div>`,
props: {

View File

@ -0,0 +1,22 @@
/**
* Async callback style it for compatibility with old tests.
*/
export function _it(
desc: string,
runner: (done: (err?: Error) => void) => void | Promise<any>
) {
it(desc, async () => {
if (runner.length === 0) {
return runner(() => {})
}
await new Promise<void>((resolve, reject) => {
const res = runner(err => {
if (err) reject(err)
else resolve()
})
if (res instanceof Promise) {
resolve(res)
}
})
})
}

View File

@ -130,7 +130,7 @@ This is only useful at runtime with pre-configured builds, so it doesn't accept
Same as `compiler.compile` but generates SSR-specific render function code by optimizing parts of the template into string concatenation in order to improve SSR performance.
This is used by default in `vue-loader@>=12` and can be disabled using the [`optimizeSSR`](https://vue-loader.vuejs.org/en/options.html#optimizessr) option.
This is used by default in `vue-loader@>=12` and can be disabled using the [`optimizeSSR`](https://vue-loader.vuejs.org/options.html#optimizessr) option.
---

View File

@ -1,6 +1,6 @@
{
"name": "vue-template-compiler",
"version": "2.7.10",
"version": "2.7.16",
"description": "template compiler for Vue 2.0",
"main": "index.js",
"unpkg": "browser.js",

File diff suppressed because it is too large Load Diff

View File

@ -227,6 +227,9 @@ const builds = {
function genConfig(name) {
const opts = builds[name]
const isTargetingBrowser = !(
opts.transpile === false || opts.format === 'cjs'
)
// console.log('__dir', __dirname)
const config = {
@ -243,11 +246,9 @@ function genConfig(name) {
compilerOptions: {
// if targeting browser, target es5
// if targeting node, es2017 means Node 8
target:
opts.transpile === false || opts.format === 'cjs'
? 'es2017'
: 'es5'
target: isTargetingBrowser ? 'es5' : 'es2017'
},
include: isTargetingBrowser ? ['src'] : ['src', 'packages/*/src'],
exclude: ['test', 'test-dts']
}
})

View File

@ -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 */
)

View File

@ -98,7 +98,7 @@ export function parseHTML(html, options: HTMLParserOptions) {
}
}
// http://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment
// https://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment
if (conditionalComment.test(html)) {
const conditionalEnd = html.indexOf(']>')

View File

@ -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

View File

@ -33,10 +33,15 @@ function matches(
}
function pruneCache(
keepAliveInstance: { cache: CacheEntryMap; keys: string[]; _vnode: VNode },
keepAliveInstance: {
cache: CacheEntryMap
keys: string[]
_vnode: VNode
$vnode: VNode
},
filter: Function
) {
const { cache, keys, _vnode } = keepAliveInstance
const { cache, keys, _vnode, $vnode } = keepAliveInstance
for (const key in cache) {
const entry = cache[key]
if (entry) {
@ -46,6 +51,7 @@ function pruneCache(
}
}
}
$vnode.componentOptions!.children = undefined
}
function pruneCacheEntry(

View File

@ -34,6 +34,9 @@ export function initMixin(Vue: typeof Component) {
vm.__v_skip = true
// effect scope
vm._scope = new EffectScope(true /* detached */)
// #13134 edge case where a child component is manually created during the
// render of a parent component
vm._scope.parent = undefined
vm._scope._vm = true
// merge options
if (options && options._isComponent) {

View File

@ -18,6 +18,7 @@ import {
invokeWithErrorHandling
} from '../util/index'
import { currentInstance, setCurrentInstance } from 'v3/currentInstance'
import { getCurrentScope } from 'v3/reactivity/effectScope'
import { syncSetupProxy } from 'v3/apiSetup'
export let activeInstance: any = null
@ -398,7 +399,8 @@ export function callHook(
) {
// #7573 disable dep collection when invoking lifecycle hooks
pushTarget()
const prev = currentInstance
const prevInst = currentInstance
const prevScope = getCurrentScope()
setContext && setCurrentInstance(vm)
const handlers = vm.$options[hook]
const info = `${hook} hook`
@ -410,6 +412,10 @@ export function callHook(
if (vm._hasHookEvent) {
vm.$emit('hook:' + hook)
}
setContext && setCurrentInstance(prev)
if (setContext) {
setCurrentInstance(prevInst)
prevScope && prevScope.on()
}
popTarget()
}

View File

@ -15,7 +15,7 @@ import VNode, { createEmptyVNode } from '../vdom/vnode'
import { isUpdatingChildComponent } from './lifecycle'
import type { Component } from 'types/component'
import { setCurrentInstance } from 'v3/currentInstance'
import { currentInstance, setCurrentInstance } from 'v3/currentInstance'
import { syncSetupSlots } from 'v3/apiSetup'
export function initRender(vm: Component) {
@ -120,11 +120,10 @@ export function renderMixin(Vue: typeof Component) {
// to the data on the placeholder node.
vm.$vnode = _parentVnode!
// render self
const prevInst = currentInstance
const prevRenderInst = currentRenderingInstance
let vnode
try {
// There's no need to maintain a stack because all render fns are called
// separately from one another. Nested component's render fns are called
// when parent component is patched.
setCurrentInstance(vm)
currentRenderingInstance = vm
vnode = render.call(vm._renderProxy, vm.$createElement)
@ -148,8 +147,8 @@ export function renderMixin(Vue: typeof Component) {
vnode = vm._vnode
}
} finally {
currentRenderingInstance = null
setCurrentInstance()
currentRenderingInstance = prevRenderInst
setCurrentInstance(prevInst)
}
// if the returned array contains only a single node, allow it
if (isArray(vnode) && vnode.length === 1) {

View File

@ -95,19 +95,25 @@ function initProps(vm: Component, propsOptions: Object) {
vm
)
}
defineReactive(props, key, value, () => {
if (!isRoot && !isUpdatingChildComponent) {
warn(
`Avoid mutating a prop directly since the value will be ` +
`overwritten whenever the parent component re-renders. ` +
`Instead, use a data or computed property based on the prop's ` +
`value. Prop being mutated: "${key}"`,
vm
)
}
})
defineReactive(
props,
key,
value,
() => {
if (!isRoot && !isUpdatingChildComponent) {
warn(
`Avoid mutating a prop directly since the value will be ` +
`overwritten whenever the parent component re-renders. ` +
`Instead, use a data or computed property based on the prop's ` +
`value. Prop being mutated: "${key}"`,
vm
)
}
},
true /* shallow */
)
} else {
defineReactive(props, key, value)
defineReactive(props, key, value, undefined, true /* shallow */)
}
// static props are already proxied on the component's prototype
// during Vue.extend(). We only need to proxy props defined at

View File

@ -1,9 +1,19 @@
import { remove } from '../util/index'
import config from '../config'
import { DebuggerOptions, DebuggerEventExtraInfo } from 'v3'
let uid = 0
const pendingCleanupDeps: Dep[] = []
export const cleanupDeps = () => {
for (let i = 0; i < pendingCleanupDeps.length; i++) {
const dep = pendingCleanupDeps[i]
dep.subs = dep.subs.filter(s => s)
dep._pending = false
}
pendingCleanupDeps.length = 0
}
/**
* @internal
*/
@ -21,7 +31,9 @@ export interface DepTarget extends DebuggerOptions {
export default class Dep {
static target?: DepTarget | null
id: number
subs: Array<DepTarget>
subs: Array<DepTarget | null>
// pending subs cleanup
_pending = false
constructor() {
this.id = uid++
@ -33,7 +45,15 @@ export default class Dep {
}
removeSub(sub: DepTarget) {
remove(this.subs, sub)
// #12696 deps with massive amount of subscribers are extremely slow to
// clean up in Chromium
// to workaround this, we unset the sub for now, and clear them on
// next scheduler flush.
this.subs[this.subs.indexOf(sub)] = null
if (!this._pending) {
this._pending = true
pendingCleanupDeps.push(this)
}
}
depend(info?: DebuggerEventExtraInfo) {
@ -50,7 +70,7 @@ export default class Dep {
notify(info?: DebuggerEventExtraInfo) {
// stabilize the subscriber list first
const subs = this.subs.slice()
const subs = this.subs.filter(s => s) as DepTarget[]
if (__DEV__ && !config.async) {
// subs aren't sorted in scheduler if not running async
// we need to sort them now to make sure they fire in correct
@ -58,15 +78,15 @@ export default class Dep {
subs.sort((a, b) => a.id - b.id)
}
for (let i = 0, l = subs.length; i < l; i++) {
const sub = subs[i]
if (__DEV__ && info) {
const sub = subs[i]
sub.onTrigger &&
sub.onTrigger({
effect: subs[i],
...info
})
}
subs[i].update()
sub.update()
}
}
}

View File

@ -7,7 +7,6 @@ import {
hasOwn,
isArray,
hasProto,
isObject,
isPlainObject,
isPrimitive,
isUndef,
@ -20,7 +19,7 @@ import { isReadonly, isRef, TrackOpTypes, TriggerOpTypes } from '../../v3'
const arrayKeys = Object.getOwnPropertyNames(arrayMethods)
const NO_INIITIAL_VALUE = {}
const NO_INITIAL_VALUE = {}
/**
* In some cases we may want to disable observation inside a component's
@ -80,7 +79,7 @@ export class Observer {
const keys = Object.keys(value)
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
defineReactive(value, key, NO_INIITIAL_VALUE, undefined, shallow, mock)
defineReactive(value, key, NO_INITIAL_VALUE, undefined, shallow, mock)
}
}
}
@ -107,22 +106,20 @@ export function observe(
shallow?: boolean,
ssrMockReactivity?: boolean
): Observer | void {
if (!isObject(value) || isRef(value) || value instanceof VNode) {
return
if (value && hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
return value.__ob__
}
let ob: Observer | void
if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
ob = value.__ob__
} else if (
if (
shouldObserve &&
(ssrMockReactivity || !isServerRendering()) &&
(isArray(value) || isPlainObject(value)) &&
Object.isExtensible(value) &&
!value.__v_skip /* ReactiveFlags.SKIP */
!value.__v_skip /* ReactiveFlags.SKIP */ &&
!isRef(value) &&
!(value instanceof VNode)
) {
ob = new Observer(value, shallow, ssrMockReactivity)
return new Observer(value, shallow, ssrMockReactivity)
}
return ob
}
/**
@ -134,7 +131,8 @@ export function defineReactive(
val?: any,
customSetter?: Function | null,
shallow?: boolean,
mock?: boolean
mock?: boolean,
observeEvenIfShallow = false
) {
const dep = new Dep()
@ -148,12 +146,12 @@ export function defineReactive(
const setter = property && property.set
if (
(!getter || setter) &&
(val === NO_INIITIAL_VALUE || arguments.length === 2)
(val === NO_INITIAL_VALUE || arguments.length === 2)
) {
val = obj[key]
}
let childOb = !shallow && observe(val, false, mock)
let childOb = shallow ? val && val.__ob__ : observe(val, false, mock)
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
@ -197,7 +195,7 @@ export function defineReactive(
} else {
val = newVal
}
childOb = !shallow && observe(newVal, false, mock)
childOb = shallow ? newVal && newVal.__ob__ : observe(newVal, false, mock)
if (__DEV__) {
dep.notify({
type: TriggerOpTypes.SET,

View File

@ -1,6 +1,6 @@
import type Watcher from './watcher'
import config from '../config'
import Dep from './dep'
import Dep, { cleanupDeps } from './dep'
import { callHook, activateChildComponent } from '../instance/lifecycle'
import { warn, nextTick, devtools, inBrowser, isIE } from '../util/index'
@ -121,6 +121,7 @@ function flushSchedulerQueue() {
// call component updated and activated hooks
callActivatedHooks(activatedQueue)
callUpdatedHooks(updatedQueue)
cleanupDeps()
// devtool hook
/* istanbul ignore if */

View File

@ -21,6 +21,7 @@ function _traverse(val: any, seen: SimpleSet) {
const isA = isArray(val)
if (
(!isA && !isObject(val)) ||
val.__v_skip /* ReactiveFlags.SKIP */ ||
Object.isFrozen(val) ||
val instanceof VNode
) {

View File

@ -51,7 +51,8 @@ if (__DEV__) {
*/
function mergeData(
to: Record<string | symbol, any>,
from: Record<string | symbol, any> | null
from: Record<string | symbol, any> | null,
recursive = true
): Record<PropertyKey, any> {
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.

View File

@ -878,8 +878,11 @@ export function createPatchFunction(backend) {
const insert = ancestor.data.hook.insert
if (insert.merged) {
// start at index 1 to avoid re-invoking component mounted hook
for (let i = 1; i < insert.fns.length; i++) {
insert.fns[i]()
// clone insert hooks to avoid being mutated during iteration.
// e.g. for customed directives under transition group.
const cloned = insert.fns.slice(1)
for (let i = 0; i < cloned.length; i++) {
cloned[i]()
}
}
} else {

View File

@ -91,10 +91,8 @@ function updateStyle(oldVnode: VNodeWithData, vnode: VNodeWithData) {
}
for (name in newStyle) {
cur = newStyle[name]
if (cur !== oldStyle[name]) {
// ie9 setting to null has no effect, must use empty string
setProp(el, name, cur == null ? '' : cur)
}
// ie9 setting to null has no effect, must use empty string
setProp(el, name, cur == null ? '' : cur)
}
}

View File

@ -62,7 +62,7 @@ export function isUnknownElement(tag: string): boolean {
}
const el = document.createElement(tag)
if (tag.indexOf('-') > -1) {
// http://stackoverflow.com/a/28210364/1070244
// https://stackoverflow.com/a/28210364/1070244
return (unknownElementCache[tag] =
el.constructor === window.HTMLUnknownElement ||
el.constructor === window.HTMLElement)

View File

@ -90,10 +90,18 @@ export function toString(val: any): string {
return val == null
? ''
: Array.isArray(val) || (isPlainObject(val) && val.toString === _toString)
? JSON.stringify(val, null, 2)
? JSON.stringify(val, replacer, 2)
: String(val)
}
function replacer(_key: string, val: any): any {
// avoid circular deps from v3
if (val && val.__v_isRef) {
return val.value
}
return val
}
/**
* Convert an input value to a number for persistence.
* If the conversion fails, return original string.
@ -133,7 +141,13 @@ export const isReservedAttribute = makeMap('key,ref,slot,slot-scope,is')
* Remove an item from an array.
*/
export function remove(arr: Array<any>, item: any): Array<any> | void {
if (arr.length) {
const len = arr.length
if (len) {
// fast path for the only / last item
if (item === arr[len - 1]) {
arr.length = len - 1
return
}
const index = arr.indexOf(item)
if (index > -1) {
return arr.splice(index, 1)
@ -280,9 +294,7 @@ export function genStaticKeys(
modules: Array<{ staticKeys?: string[] } /* ModuleOptions */>
): string {
return modules
.reduce((keys, m) => {
return keys.concat(m.staticKeys || [])
}, [] as string[])
.reduce<string[]>((keys, m) => keys.concat(m.staticKeys || []), [])
.join(',')
}

View File

@ -1,3 +1,3 @@
// If the the type T accepts type "any", output type Y, otherwise output type N.
// If the type T accepts type "any", output type Y, otherwise output type N.
// https://stackoverflow.com/questions/49927523/disallow-call-with-any/49928360#49928360
export type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N

View File

@ -47,7 +47,7 @@ export function defineAsyncComponent(
if (__DEV__ && suspensible) {
warn(
`The suspensiblbe option for async components is not supported in Vue2. It is ignored.`
`The suspensible option for async components is not supported in Vue2. It is ignored.`
)
}

View File

@ -185,8 +185,11 @@ function doWatch(
}
const instance = currentInstance
const call = (fn: Function, type: string, args: any[] | null = null) =>
invokeWithErrorHandling(fn, null, args, instance, type)
const call = (fn: Function, type: string, args: any[] | null = null) => {
const res = invokeWithErrorHandling(fn, null, args, instance, type)
if (deep && res && res.__ob__) res.__ob__.dep.depend()
return res
}
let getter: () => any
let forceTrigger = false
@ -209,6 +212,7 @@ function doWatch(
if (isRef(s)) {
return s.value
} else if (isReactive(s)) {
s.__ob__.dep.depend()
return traverse(s)
} else if (isFunction(s)) {
return call(s, WATCHER_GETTER)

View File

@ -16,9 +16,7 @@ export class EffectScope {
* @internal
*/
cleanups: (() => void)[] = []
/**
* only assigned by undetached scope
* @internal
*/
parent: EffectScope | undefined
@ -38,9 +36,9 @@ export class EffectScope {
*/
private index: number | undefined
constructor(detached = false) {
constructor(public detached = false) {
this.parent = activeEffectScope
if (!detached && activeEffectScope) {
this.parent = activeEffectScope
this.index =
(activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(
this
@ -93,7 +91,7 @@ export class EffectScope {
}
}
// nested scope, dereference from parent to avoid memory leaks
if (this.parent && !fromParent) {
if (!this.detached && this.parent && !fromParent) {
// optimized O(1) removal
const last = this.parent.scopes!.pop()
if (last && last !== this) {
@ -101,6 +99,7 @@ export class EffectScope {
last.index = this.index!
}
}
this.parent = undefined
this.active = false
}
}

View File

@ -119,7 +119,10 @@ export function toRaw<T>(observed: T): T {
export function markRaw<T extends object>(
value: T
): T & { [RawSymbol]?: true } {
def(value, ReactiveFlags.SKIP, true)
// non-extensible objects won't be observed anyway
if (Object.isExtensible(value)) {
def(value, ReactiveFlags.SKIP, true)
}
return value
}

View File

@ -57,6 +57,12 @@ 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

View File

@ -40,9 +40,7 @@ export function isRef(r: any): r is Ref {
return !!(r && (r as Ref).__v_isRef === true)
}
export function ref<T extends object>(
value: T
): [T] extends [Ref] ? T : Ref<UnwrapRef<T>>
export function ref<T extends Ref>(value: T): T
export function ref<T>(value: T): Ref<UnwrapRef<T>>
export function ref<T = any>(): Ref<T | undefined>
export function ref(value?: unknown) {
@ -53,9 +51,8 @@ declare const ShallowRefMarker: unique symbol
export type ShallowRef<T = any> = Ref<T> & { [ShallowRefMarker]?: true }
export function shallowRef<T extends object>(
value: T
): T extends Ref ? T : ShallowRef<T>
export function shallowRef<T>(value: T | Ref<T>): Ref<T> | ShallowRef<T>
export function shallowRef<T extends Ref>(value: T): T
export function shallowRef<T>(value: T): ShallowRef<T>
export function shallowRef<T = any>(): ShallowRef<T | undefined>
export function shallowRef(value?: unknown) {

View File

@ -2,12 +2,12 @@ const featureFlags = require('../../scripts/feature-flags')
process.env.CHROME_BIN = require('puppeteer').executablePath()
const define = {
__DEV__: true,
'process.env.CI': !!process.env.CI
__DEV__: `true`,
'process.env.CI': String(!!process.env.CI)
}
for (const key in featureFlags) {
define[`process.env.${key}`] = featureFlags[key]
define[`process.env.${key}`] = String(featureFlags[key])
}
module.exports = function (config) {

View File

@ -116,7 +116,7 @@ describe('Global config', () => {
expect(vm.computed).toBe('1,2,3')
expect(vm.data).toBe('1,2,3')
vm.prop.push(4, 5)
vm.prop = [...vm.prop, 4, 5]
expect(vm.computed).toBe('1,2,3,4,5')
expect(vm.data).toBe('1,2,3,4,5')
Vue.config.async = true

View File

@ -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' })
})
})

View File

@ -1,6 +1,7 @@
import Vue from 'vue'
import { hasSymbol } from 'core/util/env'
import testObjectOption from '../../../helpers/test-object-option'
import { ref } from 'v3'
describe('Options props', () => {
testObjectOption('props')
@ -593,4 +594,21 @@ describe('Options props', () => {
'Invalid prop type: "String" is not a constructor'
).toHaveBeenWarned()
})
// #12930
it('should not unwrap prop values that are raw refs', () => {
let val
const Comp = {
props: ['msg'],
created() {
val = this.msg
},
render() {}
}
const r = ref()
new Vue({
render: h => h(Comp, { props: { msg: r }})
}).$mount()
expect(val).toBe(r)
})
})

View File

@ -1200,4 +1200,35 @@ describe('api: watch', () => {
expect(parentSpy).toHaveBeenCalledTimes(1)
expect(childSpy).toHaveBeenCalledTimes(1)
})
// #12967
test('trigger when adding new property with Vue.set (getter)', async () => {
const spy = vi.fn()
const r = reactive({ exist: 5 })
watch(() => r, spy, { deep: true })
set(r, 'add', 1)
await nextTick()
expect(spy).toHaveBeenCalledTimes(1)
})
test('trigger when adding new property with Vue.set (getter in array source)', async () => {
const spy = vi.fn()
const r = reactive({ exist: 5 })
watch([() => r], spy, { deep: true })
set(r, 'add', 1)
await nextTick()
expect(spy).toHaveBeenCalledTimes(1)
})
test('trigger when adding new property with Vue.set (reactive in array source)', async () => {
const spy = vi.fn()
const r = reactive({ exist: 5 })
watch([r], spy, { deep: true })
set(r, 'add', 1)
await nextTick()
expect(spy).toHaveBeenCalledTimes(1)
})
})

View File

@ -1,3 +1,4 @@
import Vue from 'vue'
import { nextTick } from 'core/util'
import {
watch,
@ -279,4 +280,39 @@ describe('reactivity/effectScope', () => {
expect(getCurrentScope()).toBe(currentScope)
})
})
it('calling .off() of a detached scope inside an active scope should not break currentScope', () => {
const parentScope = new EffectScope()
parentScope.run(() => {
const childScope = new EffectScope(true)
childScope.on()
childScope.off()
expect(getCurrentScope()).toBe(parentScope)
})
})
it('scope should not break currentScope when component call hooks', () => {
const scope = new EffectScope()
const vm = new Vue({
template: `
<div>
<div v-if="show" />
</div>
`,
data() {
return {
show: false
}
}
}).$mount()
scope.run(() => {
// call renderTriggered hook here
vm.show = true
// this effect should be collected by scope not the component scope
effect(() => {})
})
expect(scope.effects.length).toBe(1)
})
})

View File

@ -258,6 +258,12 @@ describe('reactivity/reactive', () => {
expect(isReactive(obj.bar)).toBe(false)
})
test('markRaw on non-extensible objects', () => {
const foo = Object.seal({})
markRaw(foo)
expect(isReactive(reactive(foo))).toBe(false)
})
test('should not observe non-extensible objects', () => {
const obj = reactive({
foo: Object.preventExtensions({ a: 1 }),

View File

@ -525,4 +525,14 @@ describe('reactivity/readonly', () => {
expect(readonlyFoo.x).toBe(1)
expect(`et operation on key "x" failed`).toHaveBeenWarned()
})
test('warn non-extensible objects', () => {
const foo = Object.freeze({ a: 1 })
try {
readonly(foo)
} catch (e) {}
expect(
`Vue 2 does not support creating readonly proxy for non-extensible object`
).toHaveBeenWarned()
})
})

View File

@ -767,7 +767,7 @@ describe('parser', () => {
expect(ast.directives[0].arg).toBe('field1')
})
it('attribute with modifiered directive', () => {
it('attribute with modified directive', () => {
const ast = parse(
'<input type="text" name="field1" :value="msg" v-validate.on.off>',
baseOptions

View File

@ -1,4 +1,4 @@
import Dep from 'core/observer/dep'
import Dep, { cleanupDeps } from 'core/observer/dep'
describe('Dep', () => {
let dep
@ -24,8 +24,13 @@ describe('Dep', () => {
describe('removeSub()', () => {
it('should remove sub', () => {
dep.subs.push(null)
dep.removeSub(null)
const sub = {}
dep.subs.push(sub)
dep.removeSub(sub)
expect(dep.subs.includes(sub)).toBe(false)
// nulled subs are cleared on next flush
cleanupDeps()
expect(dep.subs.length).toBe(0)
})
})

View File

@ -0,0 +1,11 @@
import { toString } from 'core/util/index'
import { ref } from 'v3'
test('should unwrap refs', () => {
expect(
toString({
a: ref(0),
b: { c: ref(1) }
})
).toBe(JSON.stringify({ a: 0, b: { c: 1 } }, null, 2))
})

View File

@ -36,4 +36,19 @@ describe('vdom style module', () => {
expect(elm.style.fontSize).toBe('')
expect(elm.style.display).toBe('block')
})
it('border related style should update correctly', () => {
const vnode1 = new VNode('p', {
style: { border: '10px solid red', 'border-bottom': '10px solid blue' }
})
const vnode2 = new VNode('p', {
style: {
'border-right': '10px solid red',
'border-bottom': '10px solid blue'
}
})
patch(null, vnode1)
const elm = patch(vnode1, vnode2)
expect(elm.style.borderBottom).toBe('10px solid blue')
})
})

View File

@ -467,4 +467,42 @@ describe('vdom patch: edge cases', () => {
vm.visible = false
vm.$nextTick(done)
})
it('should call directive\'s inserted hook correctly when template root is changed', done => {
let insertCalled = false
const vm = new Vue({
data: {
isOn: false
},
components: {
'v-switch': {
props: {
on: Boolean
},
template: `
<div v-if="on" key="on">On</div>
<div v-else key="off">Off</div>`
}
},
directives: {
foo: {
inserted() {
insertCalled = true
}
}
},
template: `
<transition-group>
<v-switch key="swicth" v-foo :on="isOn"/>
</transition-group>
`
}).$mount()
vm.isOn = true
insertCalled = false
waitForUpdate(() => {
expect(vm.$el.textContent).toMatch('On')
expect(insertCalled).toBe(true)
}).then(done)
})
})

View File

@ -6,6 +6,7 @@
"target": "esnext",
"module": "ESNext",
"moduleResolution": "node",
"newLine": "LF",
"strict": true,
"allowJs": true,

63
types/built-in-components.d.ts vendored Normal file
View File

@ -0,0 +1,63 @@
import { DefineComponent } from './v3-define-component'
type Hook<T = () => void> = T | T[]
export interface TransitionProps {
name?: string
appear?: boolean
css?: boolean
mode?: 'in-out' | 'out-in' | 'default'
type?: 'transition' | 'animation'
duration?:
| number
| string
| {
enter: number
leave: number
}
// classes
enterClass?: string
enterActiveClass?: string
enterToClass?: string
appearClass?: string
appearActiveClass?: string
appearToClass?: string
leaveClass?: string
leaveActiveClass?: string
leaveToClass?: string
// event hooks
onBeforeEnter?: Hook<(el: Element) => void>
onEnter?: Hook<(el: Element, done: () => void) => void>
onAfterEnter?: Hook<(el: Element) => void>
onEnterCancelled?: Hook<(el: Element) => void>
onBeforeLeave?: Hook<(el: Element) => void>
onLeave?: Hook<(el: Element, done: () => void) => void>
onAfterLeave?: Hook<(el: Element) => void>
onLeaveCancelled?: Hook<(el: Element) => void>
onBeforeAppear?: Hook<(el: Element) => void>
onAppear?: Hook<(el: Element, done: () => void) => void>
onAfterAppear?: Hook<(el: Element) => void>
onAppearCancelled?: Hook<(el: Element) => void>
}
export declare const Transition: DefineComponent<TransitionProps>
export type TransitionGroupProps = Omit<TransitionProps, 'mode'> & {
tag?: string
moveClass?: string
}
export declare const TransitionGroup: DefineComponent<TransitionGroupProps>
type MatchPattern = string | RegExp | (string | RegExp)[]
export interface KeepAliveProps {
include?: MatchPattern
exclude?: MatchPattern
max?: number | string
}
export declare const KeepAlive: DefineComponent<KeepAliveProps>

2
types/common.d.ts vendored
View File

@ -14,7 +14,7 @@ type Equal<Left, Right> =
export type HasDefined<T> = Equal<T, unknown> extends true ? false : true
// If the the type T accepts type "any", output type Y, otherwise output type N.
// If the type T accepts type "any", output type Y, otherwise output type N.
// https://stackoverflow.com/questions/49927523/disallow-call-with-any/49928360#49928360
export type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N

10
types/index.d.ts vendored
View File

@ -1,6 +1,7 @@
import { Vue } from './vue'
import './umd'
import './jsx'
export * from './jsx'
export default Vue
@ -49,7 +50,12 @@ export {
ComputedOptions as ComponentComputedOptions,
MethodOptions as ComponentMethodOptions,
ComponentPropsOptions,
ComponentCustomOptions
ComponentCustomOptions,
ComponentOptionsMixin,
ComponentOptionsWithoutProps,
ComponentOptionsWithArrayProps,
ComponentOptionsWithProps,
ComponentOptionsBase
} from './v3-component-options'
export {
ComponentInstance,
@ -71,3 +77,5 @@ export {
FunctionDirective,
Directive
} from './v3-directive'
export * from './built-in-components'

6
types/jsx.d.ts vendored
View File

@ -731,7 +731,7 @@ export interface SVGAttributes extends AriaAttributes, EventHandlers<Events> {
* @see https://www.w3.org/TR/SVG/styling.html#ElementSpecificStyling
*/
class?: any
style?: string | CSSProperties
style?: StyleValue
color?: string
height?: Numberish
@ -1297,7 +1297,9 @@ export interface Events {
}
type EventHandlers<E> = {
[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 = {

11
types/options.d.ts vendored
View File

@ -4,6 +4,7 @@ import { SetupContext } from './v3-setup-context'
import { DebuggerEvent } from './v3-generated'
import { DefineComponent } from './v3-define-component'
import { ComponentOptionsMixin } from './v3-component-options'
import { ObjectDirective, FunctionDirective } from './v3-directive'
type Constructor = {
new (...args: any[]): any
@ -180,7 +181,7 @@ export interface ComponentOptions<
propsData?: object
computed?: Accessors<Computed>
methods?: Methods
watch?: Record<string, WatchOptionsWithHandler<any> | WatchHandler<any>>
watch?: Record<string, WatchOptionsWithHandler<any> | WatchHandler<any> | Array<WatchOptionsWithHandler<any> | WatchHandler<any>>>
setup?: (
this: void,
@ -209,7 +210,7 @@ export interface ComponentOptions<
activated?(): void
deactivated?(): void
errorCaptured?(err: Error, vm: Vue, info: string): boolean | void
serverPrefetch?(this: V): Promise<void>
serverPrefetch?(): Promise<void>
renderTracked?(e: DebuggerEvent): void
renderTriggerd?(e: DebuggerEvent): void
@ -318,6 +319,9 @@ export interface DirectiveBinding extends Readonly<VNodeDirective> {
readonly modifiers: { [key: string]: boolean }
}
/**
* @deprecated use {@link FunctionDirective} instead
*/
export type DirectiveFunction = (
el: HTMLElement,
binding: DirectiveBinding,
@ -325,6 +329,9 @@ export type DirectiveFunction = (
oldVnode: VNode
) => void
/**
* @deprecated use {@link ObjectDirective} instead
*/
export interface DirectiveOptions {
bind?: DirectiveFunction
inserted?: DirectiveFunction

View File

@ -41,4 +41,4 @@ const e: AsyncComponent = () => ({
})
// Test that Vue.component accepts any AsyncComponent
Vue.component('async-compponent1', a)
Vue.component('async-component1', a)

View File

@ -172,7 +172,14 @@ Vue.component('component', {
d: {
handler: 'someMethod',
immediate: true
}
},
e: [
'handle1',
function handle2 (val, oldVal) {},
{
handler: function handle3 (val, oldVal) {},
}
],
},
el: '#app',
template: '<div>{{ message }}</div>',

View File

@ -19,15 +19,19 @@ describe('defineProps w/ type declaration + withDefaults', () => {
arr?: string[]
obj?: { x: number }
fn?: (e: string) => void
x?: string
genStr?: string
x?: string
y?: string
z?: string
}>(),
{
number: 123,
arr: () => [],
obj: () => ({ x: 123 }),
fn: () => {},
genStr: () => ''
genStr: () => '',
y: undefined,
z: 'string'
}
)
@ -35,9 +39,15 @@ describe('defineProps w/ type declaration + withDefaults', () => {
res.arr.push('hi')
res.obj.x
res.fn('hi')
res.genStr.slice()
// @ts-expect-error
res.x.slice()
res.genStr.slice()
// @ts-expect-error
res.y.slice()
expectType<string | undefined>(res.x)
expectType<string | undefined>(res.y)
expectType<string>(res.z)
})
describe('defineProps w/ union type declaration + withDefaults', () => {

View File

@ -15,7 +15,7 @@ import {
set,
del
} from '../../index'
import { describe, expectType } from '../utils'
import { IsUnion, describe, expectType } from '../utils'
function plainType(arg: number | Ref<number>) {
// ref coercing
@ -385,3 +385,14 @@ describe('set/del', () => {
// @ts-expect-error
del([], 'fse', 123)
})
{
//#12978
type Steps = { step: '1' } | { step: '2' }
const shallowUnionGenParam = shallowRef<Steps>({ step: '1' })
const shallowUnionAsCast = shallowRef({ step: '1' } as Steps)
expectType<IsUnion<typeof shallowUnionGenParam>>(false)
expectType<IsUnion<typeof shallowUnionAsCast>>(false)
}

View File

@ -1,4 +1,4 @@
import { VNode, defineComponent } from '../../index'
import { VNode, defineComponent, ref, RenderContext } from '../../index'
import { expectType } from '../utils'
expectType<VNode>(<div />)
@ -22,6 +22,17 @@ expectError(<div foo="bar" />)
expectType<JSX.Element>(<div key="foo" />)
expectType<JSX.Element>(<div ref="bar" />)
// allow Ref type type on arbitrary element
const fooRef = ref<HTMLElement>()
expectType<JSX.Element>(<div ref={fooRef} />)
expectType<JSX.Element>(
<div
ref={el => {
fooRef.value = el as HTMLElement
}}
/>
)
expectType<JSX.Element>(
<input
onInput={e => {
@ -51,5 +62,8 @@ const Foo = defineComponent({
// working
;<Foo bar={1} />
;<Foo bar={1} foo="baz" />
;<div slot="x" />
export default ({ data }: RenderContext) => {
return <button {...data} />
}

View File

@ -1,4 +1,4 @@
import { ref, computed, watch } from '../../index'
import { ref, computed, watch, shallowRef } from '../../index'
import { expectType } from '../utils'
const source = ref('foo')
@ -76,3 +76,17 @@ watch([someRef, otherRef], values => {
// no type error
console.log(value2.a)
})
{
//#12978
type Steps = { step: '1' } | { step: '2' }
const shallowUnionGenParam = shallowRef<Steps>({ step: '1' })
const shallowUnionAsCast = shallowRef({ step: '1' } as Steps)
watch(shallowUnionGenParam, value => {
expectType<Steps>(value)
})
watch(shallowUnionAsCast, value => {
expectType<Steps>(value)
})
}

View File

@ -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
])
}
})

View File

@ -110,7 +110,11 @@ type InferDefault<P, T> = T extends
: (props: P) => T
type PropsWithDefaults<Base, Defaults> = Base & {
[K in keyof Defaults]: K extends keyof Base ? NotUndefined<Base[K]> : never
[K in keyof Defaults]: K extends keyof Base
? Defaults[K] extends undefined
? Base[K]
: NotUndefined<Base[K]>
: never
}
/**

17
types/vnode.d.ts vendored
View File

@ -1,5 +1,8 @@
import { StyleValue } from './jsx'
import { Vue } from './vue'
import { DirectiveFunction, DirectiveOptions } from './options'
import { Ref } from './v3-generated'
import { ComponentPublicInstance } from './v3-component-public-instance'
/**
* For extending allowed non-declared props on components in TSX
@ -19,6 +22,7 @@ type ScopedSlotReturnValue =
| VNode
| string
| boolean
| number
| null
| undefined
| ScopedSlotReturnArray
@ -34,6 +38,7 @@ export type VNodeChildren =
| [ScopedSlot]
| string
| boolean
| number
| null
| undefined
export interface VNodeChildrenArrayContents
@ -65,17 +70,25 @@ export interface VNodeComponentOptions {
tag?: string
}
export type VNodeRef =
| string
| Ref
| ((
ref: Element | ComponentPublicInstance | null,
refs: Record<string, any>
) => void)
export interface VNodeData {
key?: string | number
slot?: string
scopedSlots?: { [key: string]: ScopedSlot | undefined }
ref?: string
ref?: VNodeRef
refInFor?: boolean
tag?: string
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 }

5
types/vue.d.ts vendored
View File

@ -22,6 +22,7 @@ import {
ExtractComputedReturns,
ComponentOptionsMixin
} from './v3-component-options'
import { Directive, ObjectDirective } from './v3-directive'
export interface CreateElement {
(
@ -338,6 +339,10 @@ export interface VueConstructor<V extends Vue = Vue> {
id: string,
definition?: DirectiveOptions | DirectiveFunction
): DirectiveOptions
directive(
id: string,
definition?: Directive
): ObjectDirective
filter(id: string, definition?: Function): Function
component(id: string): VueConstructor