[{"data":1,"prerenderedAt":12565},["ShallowReactive",2],{"blog-navigation":3},[4,1132,1437,4437,5029,5424,6119,7469,8490,9883,10754,11729,12004],{"_path":5,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":9,"description":10,"date":11,"author":12,"gravatar":13,"twitter":14,"excerpt":15,"body":25,"_type":1125,"_id":1126,"_source":1127,"_file":1128,"_stem":1129,"_extension":1130,"sitemap":1131},"/blog/vue-3-4","blog",false,"","Announcing Vue 3.4","Today we're excited to announce the release of Vue 3.4 \"🏀 Slam Dunk\"!","2023-12-28","Evan You","eca93da2c67aadafe35d477aa8f454b8","@youyuxi",{"type":16,"children":17},"root",[18],{"type":19,"tag":20,"props":21,"children":22},"element","p",{},[23],{"type":24,"value":10},"text",{"type":16,"children":26,"toc":1108},[27,31,45,62,66,71,78,144,150,157,172,195,200,205,211,225,230,235,429,449,454,490,504,515,529,562,567,590,602,616,621,727,732,778,790,796,810,815,833,851,857,862,876,890,896,902,915,920,996,1009,1015,1102],{"type":19,"tag":20,"props":28,"children":29},{},[30],{"type":24,"value":10},{"type":19,"tag":20,"props":32,"children":33},{},[34,36,43],{"type":24,"value":35},"This release includes some substantial internal improvements - most notably a rewritten template parser that is 2x faster, and a refactored reactivity system that makes effect triggering more accurate and efficient. It also packs a number of quality-of-life API improvements, including the stabilization of ",{"type":19,"tag":37,"props":38,"children":40},"code",{"className":39},[],[41],{"type":24,"value":42},"defineModel",{"type":24,"value":44}," and a new same-name shorthand when binding props.",{"type":19,"tag":20,"props":46,"children":47},{},[48,50,60],{"type":24,"value":49},"This post provides an overview of the highlighted features in 3.4. For the full list of changes, please consult\n",{"type":19,"tag":51,"props":52,"children":57},"a",{"href":53,"rel":54,"target":56},"https://github.com/vuejs/core/blob/main/CHANGELOG.md#340-2023-12-28",[55,55],"noopener","_blank",[58],{"type":24,"value":59},"the full changelog on GitHub",{"type":24,"value":61},".",{"type":19,"tag":63,"props":64,"children":65},"hr",{},[],{"type":19,"tag":20,"props":67,"children":68},{},[69],{"type":24,"value":70},"[[TOC]]",{"type":19,"tag":72,"props":73,"children":75},"h2",{"id":74},"potential-actions-needed",[76],{"type":24,"value":77},"Potential Actions Needed",{"type":19,"tag":79,"props":80,"children":81},"ol",{},[82,120,132],{"type":19,"tag":83,"props":84,"children":85},"li",{},[86,88],{"type":24,"value":87},"To fully leverage new features in 3.4, it is recommended to also update the following dependencies when upgrading to 3.4:",{"type":19,"tag":89,"props":90,"children":91},"ul",{},[92,105,110,115],{"type":19,"tag":83,"props":93,"children":94},{},[95,97,103],{"type":24,"value":96},"Volar / vue-tsc@^1.8.27 (",{"type":19,"tag":98,"props":99,"children":100},"strong",{},[101],{"type":24,"value":102},"required",{"type":24,"value":104},")",{"type":19,"tag":83,"props":106,"children":107},{},[108],{"type":24,"value":109},"@vitejs/plugin-vue@^5.0.0 (if using Vite)",{"type":19,"tag":83,"props":111,"children":112},{},[113],{"type":24,"value":114},"nuxt@^3.9.0 (if using Nuxt)",{"type":19,"tag":83,"props":116,"children":117},{},[118],{"type":24,"value":119},"vue-loader@^17.4.0 (if using webpack or vue-cli)",{"type":19,"tag":83,"props":121,"children":122},{},[123,125,131],{"type":24,"value":124},"If using TSX with Vue, check actions needed in ",{"type":19,"tag":51,"props":126,"children":128},{"href":127},"#removed-global-jsx-namespace",[129],{"type":24,"value":130},"Removed: Global JSX Namespace",{"type":24,"value":61},{"type":19,"tag":83,"props":133,"children":134},{},[135,137,143],{"type":24,"value":136},"Make sure you are no longer using any deprecated features (if you are, you should have warnings in the console telling you so). They may have been ",{"type":19,"tag":51,"props":138,"children":140},{"href":139},"#other-removed-features",[141],{"type":24,"value":142},"removed in 3.4",{"type":24,"value":61},{"type":19,"tag":72,"props":145,"children":147},{"id":146},"feature-highlights",[148],{"type":24,"value":149},"Feature Highlights",{"type":19,"tag":151,"props":152,"children":154},"h3",{"id":153},"_2x-faster-parser-and-improved-sfc-build-performance",[155],{"type":24,"value":156},"2X Faster Parser and Improved SFC Build Performance",{"type":19,"tag":89,"props":158,"children":159},{},[160],{"type":19,"tag":83,"props":161,"children":162},{},[163,165],{"type":24,"value":164},"Context: ",{"type":19,"tag":51,"props":166,"children":169},{"href":167,"rel":168,"target":56},"https://github.com/vuejs/core/pull/9674",[55,55],[170],{"type":24,"value":171},"PR#9674",{"type":19,"tag":20,"props":173,"children":174},{},[175,177,184,186,193],{"type":24,"value":176},"In 3.4, we completely rewrote the template parser. Previously, Vue used a recursive descent parser that relied on many regular expressions and look-ahead searches. The new parser uses a state-machine tokenizer based on the tokenizer in ",{"type":19,"tag":51,"props":178,"children":181},{"href":179,"rel":180,"target":56},"https://github.com/fb55/htmlparser2",[55,55],[182],{"type":24,"value":183},"htmlparser2",{"type":24,"value":185},", which iterates through the entire template string only once. The result is a parser that is consistently twice as fast for templates of all sizes. Thanks to our extensive test cases and ",{"type":19,"tag":51,"props":187,"children":190},{"href":188,"rel":189,"target":56},"https://github.com/vuejs/ecosystem-ci",[55,55],[191],{"type":24,"value":192},"ecosystem-ci",{"type":24,"value":194},", it is also 100% backwards compatible for Vue end users.",{"type":19,"tag":20,"props":196,"children":197},{},[198],{"type":24,"value":199},"While integrating the new parser with other parts of the system, we also discovered a few opportunities to further improve the overall SFC compilation performance. The benchmarks show a ~44% improvement when compiling the script and template parts of a Vue SFC while generating source maps, so 3.4 should result in faster builds for most projects using Vue SFCs. However, do note that Vue SFC compilation is only one part of the entire build process in real world projects. The final gain in end-to-end build time will likely be much smaller compared to the isolated benchmarks.",{"type":19,"tag":20,"props":201,"children":202},{},[203],{"type":24,"value":204},"Outside of Vue core, the new parser will also benefit the performance of Volar / vue-tsc, and community plugins that need to parse Vue SFCs or templates, e.g. Vue Macros.",{"type":19,"tag":151,"props":206,"children":208},{"id":207},"more-efficient-reactivity-system",[209],{"type":24,"value":210},"More Efficient Reactivity System",{"type":19,"tag":20,"props":212,"children":213},{},[214],{"type":19,"tag":98,"props":215,"children":216},{},[217,218],{"type":24,"value":164},{"type":19,"tag":51,"props":219,"children":222},{"href":220,"rel":221,"target":56},"https://github.com/vuejs/core/pull/5912",[55,55],[223],{"type":24,"value":224},"PR#5912",{"type":19,"tag":20,"props":226,"children":227},{},[228],{"type":24,"value":229},"3.4 also ships a substantial refactor of the reactivity system, with the goal of improving re-compute efficiency of computed properties.",{"type":19,"tag":20,"props":231,"children":232},{},[233],{"type":24,"value":234},"To illustrate what is being improved, let's consider the following scenario:",{"type":19,"tag":236,"props":237,"children":241},"pre",{"className":238,"code":239,"language":240,"meta":8,"style":8},"language-js shiki shiki-themes dracula-soft","const count = ref(0)\nconst isEven = computed(() => count.value % 2 === 0)\n\nwatchEffect(() => console.log(isEven.value)) // logs true\n\ncount.value = 2 // logs true again\n","js",[242],{"type":19,"tag":37,"props":243,"children":244},{"__ignoreMap":8},[245,290,351,361,399,407],{"type":19,"tag":246,"props":247,"children":250},"span",{"class":248,"line":249},"line",1,[251,257,263,268,274,279,285],{"type":19,"tag":246,"props":252,"children":254},{"style":253},"--shiki-default:#F286C4",[255],{"type":24,"value":256},"const",{"type":19,"tag":246,"props":258,"children":260},{"style":259},"--shiki-default:#F6F6F4",[261],{"type":24,"value":262}," count ",{"type":19,"tag":246,"props":264,"children":265},{"style":253},[266],{"type":24,"value":267},"=",{"type":19,"tag":246,"props":269,"children":271},{"style":270},"--shiki-default:#62E884",[272],{"type":24,"value":273}," ref",{"type":19,"tag":246,"props":275,"children":276},{"style":259},[277],{"type":24,"value":278},"(",{"type":19,"tag":246,"props":280,"children":282},{"style":281},"--shiki-default:#BF9EEE",[283],{"type":24,"value":284},"0",{"type":19,"tag":246,"props":286,"children":287},{"style":259},[288],{"type":24,"value":289},")\n",{"type":19,"tag":246,"props":291,"children":293},{"class":248,"line":292},2,[294,298,303,307,312,317,322,327,332,337,342,347],{"type":19,"tag":246,"props":295,"children":296},{"style":253},[297],{"type":24,"value":256},{"type":19,"tag":246,"props":299,"children":300},{"style":259},[301],{"type":24,"value":302}," isEven ",{"type":19,"tag":246,"props":304,"children":305},{"style":253},[306],{"type":24,"value":267},{"type":19,"tag":246,"props":308,"children":309},{"style":270},[310],{"type":24,"value":311}," computed",{"type":19,"tag":246,"props":313,"children":314},{"style":259},[315],{"type":24,"value":316},"(() ",{"type":19,"tag":246,"props":318,"children":319},{"style":253},[320],{"type":24,"value":321},"=>",{"type":19,"tag":246,"props":323,"children":324},{"style":259},[325],{"type":24,"value":326}," count.value ",{"type":19,"tag":246,"props":328,"children":329},{"style":253},[330],{"type":24,"value":331},"%",{"type":19,"tag":246,"props":333,"children":334},{"style":281},[335],{"type":24,"value":336}," 2",{"type":19,"tag":246,"props":338,"children":339},{"style":253},[340],{"type":24,"value":341}," ===",{"type":19,"tag":246,"props":343,"children":344},{"style":281},[345],{"type":24,"value":346}," 0",{"type":19,"tag":246,"props":348,"children":349},{"style":259},[350],{"type":24,"value":289},{"type":19,"tag":246,"props":352,"children":354},{"class":248,"line":353},3,[355],{"type":19,"tag":246,"props":356,"children":358},{"emptyLinePlaceholder":357},true,[359],{"type":24,"value":360},"\n",{"type":19,"tag":246,"props":362,"children":364},{"class":248,"line":363},4,[365,370,374,378,383,388,393],{"type":19,"tag":246,"props":366,"children":367},{"style":270},[368],{"type":24,"value":369},"watchEffect",{"type":19,"tag":246,"props":371,"children":372},{"style":259},[373],{"type":24,"value":316},{"type":19,"tag":246,"props":375,"children":376},{"style":253},[377],{"type":24,"value":321},{"type":19,"tag":246,"props":379,"children":380},{"style":259},[381],{"type":24,"value":382}," console.",{"type":19,"tag":246,"props":384,"children":385},{"style":270},[386],{"type":24,"value":387},"log",{"type":19,"tag":246,"props":389,"children":390},{"style":259},[391],{"type":24,"value":392},"(isEven.value)) ",{"type":19,"tag":246,"props":394,"children":396},{"style":395},"--shiki-default:#7B7F8B",[397],{"type":24,"value":398},"// logs true\n",{"type":19,"tag":246,"props":400,"children":402},{"class":248,"line":401},5,[403],{"type":19,"tag":246,"props":404,"children":405},{"emptyLinePlaceholder":357},[406],{"type":24,"value":360},{"type":19,"tag":246,"props":408,"children":410},{"class":248,"line":409},6,[411,416,420,424],{"type":19,"tag":246,"props":412,"children":413},{"style":259},[414],{"type":24,"value":415},"count.value ",{"type":19,"tag":246,"props":417,"children":418},{"style":253},[419],{"type":24,"value":267},{"type":19,"tag":246,"props":421,"children":422},{"style":281},[423],{"type":24,"value":336},{"type":19,"tag":246,"props":425,"children":426},{"style":395},[427],{"type":24,"value":428}," // logs true again\n",{"type":19,"tag":20,"props":430,"children":431},{},[432,434,439,441,447],{"type":24,"value":433},"Before 3.4, the callback of ",{"type":19,"tag":37,"props":435,"children":437},{"className":436},[],[438],{"type":24,"value":369},{"type":24,"value":440}," will fire every time ",{"type":19,"tag":37,"props":442,"children":444},{"className":443},[],[445],{"type":24,"value":446},"count.value",{"type":24,"value":448}," is changed, even if the computed result remains the same. With the post-3.4 optimizations, the callback now only fires if the computed result has actually changed.",{"type":19,"tag":20,"props":450,"children":451},{},[452],{"type":24,"value":453},"In addition, in 3.4:",{"type":19,"tag":89,"props":455,"children":456},{},[457,462],{"type":19,"tag":83,"props":458,"children":459},{},[460],{"type":24,"value":461},"Multiple computed dep changes only trigger sync effects once.",{"type":19,"tag":83,"props":463,"children":464},{},[465,467,473,475,481,482,488],{"type":24,"value":466},"Array ",{"type":19,"tag":37,"props":468,"children":470},{"className":469},[],[471],{"type":24,"value":472},"shift",{"type":24,"value":474},", ",{"type":19,"tag":37,"props":476,"children":478},{"className":477},[],[479],{"type":24,"value":480},"unshift",{"type":24,"value":474},{"type":19,"tag":37,"props":483,"children":485},{"className":484},[],[486],{"type":24,"value":487},"splice",{"type":24,"value":489}," methods only trigger sync effects once.",{"type":19,"tag":20,"props":491,"children":492},{},[493,495,502],{"type":24,"value":494},"In addition to the gains shown in the ",{"type":19,"tag":51,"props":496,"children":499},{"href":497,"rel":498,"target":56},"https://github.com/vuejs/core/pull/5912#issuecomment-1748985641",[55,55],[500],{"type":24,"value":501},"benchmarks",{"type":24,"value":503},", this should reduce unnecessary component re-renders in many scenarios while retaining full backwards compatibility.",{"type":19,"tag":151,"props":505,"children":507},{"id":506},"definemodel-is-now-stable",[508,513],{"type":19,"tag":37,"props":509,"children":511},{"className":510},[],[512],{"type":24,"value":42},{"type":24,"value":514}," is Now Stable",{"type":19,"tag":20,"props":516,"children":517},{},[518],{"type":19,"tag":98,"props":519,"children":520},{},[521,522],{"type":24,"value":164},{"type":19,"tag":51,"props":523,"children":526},{"href":524,"rel":525,"target":56},"https://github.com/vuejs/rfcs/discussions/503",[55,55],[527],{"type":24,"value":528},"RFC#503",{"type":19,"tag":20,"props":530,"children":531},{},[532,537,539,545,547,553,555,560],{"type":19,"tag":37,"props":533,"children":535},{"className":534},[],[536],{"type":24,"value":42},{"type":24,"value":538}," is a new ",{"type":19,"tag":37,"props":540,"children":542},{"className":541},[],[543],{"type":24,"value":544},"\u003Cscript setup>",{"type":24,"value":546}," macro that aims to simplify the implementation of components that support ",{"type":19,"tag":37,"props":548,"children":550},{"className":549},[],[551],{"type":24,"value":552},"v-model",{"type":24,"value":554},". It was previously shipped in 3.3 as an experimental feature, and has graduated to stable status in 3.4. It now also provides better support for usage with ",{"type":19,"tag":37,"props":556,"children":558},{"className":557},[],[559],{"type":24,"value":552},{"type":24,"value":561}," modifiers.",{"type":19,"tag":20,"props":563,"children":564},{},[565],{"type":24,"value":566},"Relevant Documentation:",{"type":19,"tag":89,"props":568,"children":569},{},[570,580],{"type":19,"tag":83,"props":571,"children":572},{},[573],{"type":19,"tag":51,"props":574,"children":577},{"href":575,"rel":576,"target":56},"https://vuejs.org/guide/components/v-model.html",[55,55],[578],{"type":24,"value":579},"Revised Component v-model section",{"type":19,"tag":83,"props":581,"children":582},{},[583],{"type":19,"tag":51,"props":584,"children":587},{"href":585,"rel":586,"target":56},"https://vuejs.org/api/sfc-script-setup.html#definemodel",[55,55],[588],{"type":24,"value":589},"defineModel API reference",{"type":19,"tag":151,"props":591,"children":593},{"id":592},"v-bind-same-name-shorthand",[594,600],{"type":19,"tag":37,"props":595,"children":597},{"className":596},[],[598],{"type":24,"value":599},"v-bind",{"type":24,"value":601}," Same-name Shorthand",{"type":19,"tag":20,"props":603,"children":604},{},[605],{"type":19,"tag":98,"props":606,"children":607},{},[608,609],{"type":24,"value":164},{"type":19,"tag":51,"props":610,"children":613},{"href":611,"rel":612,"target":56},"https://github.com/vuejs/core/pull/9451",[55,55],[614],{"type":24,"value":615},"PR#9451",{"type":19,"tag":20,"props":617,"children":618},{},[619],{"type":24,"value":620},"You can now shorten this:",{"type":19,"tag":236,"props":622,"children":626},{"className":623,"code":624,"language":625,"meta":8,"style":8},"language-vue shiki shiki-themes dracula-soft","\u003Cimg :id=\"id\" :src=\"src\" :alt=\"alt\" />\n","vue",[627],{"type":19,"tag":37,"props":628,"children":629},{"__ignoreMap":8},[630],{"type":19,"tag":246,"props":631,"children":632},{"class":248,"line":249},[633,638,643,648,654,658,664,668,672,676,681,685,689,693,697,701,706,710,714,718,722],{"type":19,"tag":246,"props":634,"children":635},{"style":259},[636],{"type":24,"value":637},"\u003C",{"type":19,"tag":246,"props":639,"children":640},{"style":253},[641],{"type":24,"value":642},"img",{"type":19,"tag":246,"props":644,"children":645},{"style":259},[646],{"type":24,"value":647}," :",{"type":19,"tag":246,"props":649,"children":651},{"style":650},"--shiki-default:#62E884;--shiki-default-font-style:italic",[652],{"type":24,"value":653},"id",{"type":19,"tag":246,"props":655,"children":656},{"style":253},[657],{"type":24,"value":267},{"type":19,"tag":246,"props":659,"children":661},{"style":660},"--shiki-default:#DEE492",[662],{"type":24,"value":663},"\"",{"type":19,"tag":246,"props":665,"children":666},{"style":259},[667],{"type":24,"value":653},{"type":19,"tag":246,"props":669,"children":670},{"style":660},[671],{"type":24,"value":663},{"type":19,"tag":246,"props":673,"children":674},{"style":259},[675],{"type":24,"value":647},{"type":19,"tag":246,"props":677,"children":678},{"style":650},[679],{"type":24,"value":680},"src",{"type":19,"tag":246,"props":682,"children":683},{"style":253},[684],{"type":24,"value":267},{"type":19,"tag":246,"props":686,"children":687},{"style":660},[688],{"type":24,"value":663},{"type":19,"tag":246,"props":690,"children":691},{"style":259},[692],{"type":24,"value":680},{"type":19,"tag":246,"props":694,"children":695},{"style":660},[696],{"type":24,"value":663},{"type":19,"tag":246,"props":698,"children":699},{"style":259},[700],{"type":24,"value":647},{"type":19,"tag":246,"props":702,"children":703},{"style":650},[704],{"type":24,"value":705},"alt",{"type":19,"tag":246,"props":707,"children":708},{"style":253},[709],{"type":24,"value":267},{"type":19,"tag":246,"props":711,"children":712},{"style":660},[713],{"type":24,"value":663},{"type":19,"tag":246,"props":715,"children":716},{"style":259},[717],{"type":24,"value":705},{"type":19,"tag":246,"props":719,"children":720},{"style":660},[721],{"type":24,"value":663},{"type":19,"tag":246,"props":723,"children":724},{"style":259},[725],{"type":24,"value":726}," />\n",{"type":19,"tag":20,"props":728,"children":729},{},[730],{"type":24,"value":731},"To this:",{"type":19,"tag":236,"props":733,"children":735},{"className":623,"code":734,"language":625,"meta":8,"style":8},"\u003Cimg :id :src :alt />\n",[736],{"type":19,"tag":37,"props":737,"children":738},{"__ignoreMap":8},[739],{"type":19,"tag":246,"props":740,"children":741},{"class":248,"line":249},[742,746,750,754,758,762,766,770,774],{"type":19,"tag":246,"props":743,"children":744},{"style":259},[745],{"type":24,"value":637},{"type":19,"tag":246,"props":747,"children":748},{"style":253},[749],{"type":24,"value":642},{"type":19,"tag":246,"props":751,"children":752},{"style":259},[753],{"type":24,"value":647},{"type":19,"tag":246,"props":755,"children":756},{"style":650},[757],{"type":24,"value":653},{"type":19,"tag":246,"props":759,"children":760},{"style":259},[761],{"type":24,"value":647},{"type":19,"tag":246,"props":763,"children":764},{"style":650},[765],{"type":24,"value":680},{"type":19,"tag":246,"props":767,"children":768},{"style":259},[769],{"type":24,"value":647},{"type":19,"tag":246,"props":771,"children":772},{"style":650},[773],{"type":24,"value":705},{"type":19,"tag":246,"props":775,"children":776},{"style":259},[777],{"type":24,"value":726},{"type":19,"tag":20,"props":779,"children":780},{},[781,783,788],{"type":24,"value":782},"This feature has been frequently requested in the past. Originally, we had concerns about its usage being confused with boolean attributes. However, after revisiting the feature, we now think it makes sense for ",{"type":19,"tag":37,"props":784,"children":786},{"className":785},[],[787],{"type":24,"value":599},{"type":24,"value":789}," to behave a bit more like JavaScript than native attributes, considering its dynamic nature.",{"type":19,"tag":151,"props":791,"children":793},{"id":792},"improved-hydration-mismatch-errors",[794],{"type":24,"value":795},"Improved Hydration Mismatch Errors",{"type":19,"tag":20,"props":797,"children":798},{},[799],{"type":19,"tag":98,"props":800,"children":801},{},[802,803],{"type":24,"value":164},{"type":19,"tag":51,"props":804,"children":807},{"href":805,"rel":806,"target":56},"https://github.com/vuejs/core/pull/5953",[55,55],[808],{"type":24,"value":809},"PR#5953",{"type":19,"tag":20,"props":811,"children":812},{},[813],{"type":24,"value":814},"3.4 ships a number of improvements to hydration mismatch error messages:",{"type":19,"tag":79,"props":816,"children":817},{},[818,823,828],{"type":19,"tag":83,"props":819,"children":820},{},[821],{"type":24,"value":822},"Improved clarity of the wording (rendered by server vs. expected on client).",{"type":19,"tag":83,"props":824,"children":825},{},[826],{"type":24,"value":827},"The message now includes the DOM node in question so you can quickly locate it on the page or in the elements panel.",{"type":19,"tag":83,"props":829,"children":830},{},[831],{"type":24,"value":832},"Hydration mismatch checks now also apply to class, style, and other dynamically bound attributes.",{"type":19,"tag":20,"props":834,"children":835},{},[836,838,849],{"type":24,"value":837},"In addition, 3.4 also adds a new compile-time flag, ",{"type":19,"tag":51,"props":839,"children":842},{"href":840,"rel":841,"target":56},"https://vuejs.org/api/compile-time-flags.html#vue-prod-hydration-mismatch-details",[55,55],[843],{"type":19,"tag":37,"props":844,"children":846},{"className":845},[],[847],{"type":24,"value":848},"__VUE_PROD_HYDRATION_MISMATCH_DETAILS__",{"type":24,"value":850},", which can be used to force hydration mismatch errors to include full details even in production.",{"type":19,"tag":151,"props":852,"children":854},{"id":853},"error-code-and-compile-time-flag-reference",[855],{"type":24,"value":856},"Error Code and Compile-time Flag Reference",{"type":19,"tag":20,"props":858,"children":859},{},[860],{"type":24,"value":861},"To reduce bundle size, Vue drops long error message strings in production builds. However, this means errors caught by error handlers in production will receive short error codes that are difficult to decipher without diving into Vue's source code.",{"type":19,"tag":20,"props":863,"children":864},{},[865,867,874],{"type":24,"value":866},"To improve this, we have added a ",{"type":19,"tag":51,"props":868,"children":871},{"href":869,"rel":870,"target":56},"https://vuejs.org/error-reference/",[55,55],[872],{"type":24,"value":873},"Production Error Reference Page",{"type":24,"value":875}," to the documentation. The error codes are automatically generated from the latest version of Vue stable release.",{"type":19,"tag":20,"props":877,"children":878},{},[879,881,888],{"type":24,"value":880},"We have also added a ",{"type":19,"tag":51,"props":882,"children":885},{"href":883,"rel":884,"target":56},"https://vuejs.org/api/compile-time-flags.html",[55,55],[886],{"type":24,"value":887},"Compile-Time Flags Reference",{"type":24,"value":889}," with instructions on how to configure these flags for different build tools.",{"type":19,"tag":72,"props":891,"children":893},{"id":892},"removed-deprecated-features",[894],{"type":24,"value":895},"Removed Deprecated Features",{"type":19,"tag":151,"props":897,"children":899},{"id":898},"global-jsx-namespace",[900],{"type":24,"value":901},"Global JSX Namespace",{"type":19,"tag":20,"props":903,"children":904},{},[905,907,913],{"type":24,"value":906},"Starting in 3.4, Vue no longer registers the global ",{"type":19,"tag":37,"props":908,"children":910},{"className":909},[],[911],{"type":24,"value":912},"JSX",{"type":24,"value":914}," namespace by default. This is necessary to avoid global namespace collision with React so that TSX of both libs can co-exist in the same project. This should not affect SFC-only users with latest version of Volar.",{"type":19,"tag":20,"props":916,"children":917},{},[918],{"type":24,"value":919},"If you are using TSX, there are two options:",{"type":19,"tag":79,"props":921,"children":922},{},[923,961],{"type":19,"tag":83,"props":924,"children":925},{},[926,928,935,937,943,945,951,953,959],{"type":24,"value":927},"Explicitly set ",{"type":19,"tag":51,"props":929,"children":932},{"href":930,"rel":931,"target":56},"https://www.typescriptlang.org/tsconfig#jsxImportSource",[55,55],[933],{"type":24,"value":934},"jsxImportSource",{"type":24,"value":936}," to ",{"type":19,"tag":37,"props":938,"children":940},{"className":939},[],[941],{"type":24,"value":942},"'vue'",{"type":24,"value":944}," in ",{"type":19,"tag":37,"props":946,"children":948},{"className":947},[],[949],{"type":24,"value":950},"tsconfig.json",{"type":24,"value":952}," before upgrading to 3.4. You can also opt-in per file by adding a ",{"type":19,"tag":37,"props":954,"children":956},{"className":955},[],[957],{"type":24,"value":958},"/* @jsxImportSource vue */",{"type":24,"value":960}," comment at the top of the file.",{"type":19,"tag":83,"props":962,"children":963},{},[964,966,971,973,979,981,987,989,994],{"type":24,"value":965},"If you have code that depends on the presence of the global ",{"type":19,"tag":37,"props":967,"children":969},{"className":968},[],[970],{"type":24,"value":912},{"type":24,"value":972}," namespace, e.g. usage of types like ",{"type":19,"tag":37,"props":974,"children":976},{"className":975},[],[977],{"type":24,"value":978},"JSX.Element",{"type":24,"value":980}," etc., you can retain the exact pre-3.4 global behavior by explicitly referencing ",{"type":19,"tag":37,"props":982,"children":984},{"className":983},[],[985],{"type":24,"value":986},"vue/jsx",{"type":24,"value":988},", which registers the global ",{"type":19,"tag":37,"props":990,"children":992},{"className":991},[],[993],{"type":24,"value":912},{"type":24,"value":995}," namespace.",{"type":19,"tag":20,"props":997,"children":998},{},[999,1001,1008],{"type":24,"value":1000},"Note that this is a type-only breaking change in a minor release, which adheres to our ",{"type":19,"tag":51,"props":1002,"children":1005},{"href":1003,"rel":1004,"target":56},"https://vuejs.org/about/releases.html#semantic-versioning-edge-cases",[55,55],[1006],{"type":24,"value":1007},"release policy",{"type":24,"value":61},{"type":19,"tag":151,"props":1010,"children":1012},{"id":1011},"other-removed-features",[1013],{"type":24,"value":1014},"Other Removed Features",{"type":19,"tag":89,"props":1016,"children":1017},{},[1018,1038,1049,1068],{"type":19,"tag":83,"props":1019,"children":1020},{},[1021,1028,1030,1037],{"type":19,"tag":51,"props":1022,"children":1025},{"href":1023,"rel":1024,"target":56},"https://vuejs.org/guide/extras/reactivity-transform.html",[55,55],[1026],{"type":24,"value":1027},"Reactivity Transform",{"type":24,"value":1029}," was marked deprecated in 3.3 and is now removed in 3.4. This change does not require a major due to the feature being experimental. Users who wish to continue using the feature can do so via the ",{"type":19,"tag":51,"props":1031,"children":1034},{"href":1032,"rel":1033,"target":56},"https://vue-macros.dev/features/reactivity-transform.html",[55,55],[1035],{"type":24,"value":1036},"Vue Macros plugin",{"type":24,"value":61},{"type":19,"tag":83,"props":1039,"children":1040},{},[1041,1047],{"type":19,"tag":37,"props":1042,"children":1044},{"className":1043},[],[1045],{"type":24,"value":1046},"app.config.unwrapInjectedRef",{"type":24,"value":1048}," has been removed. It was deprecated and enabled by default in 3.3. In 3.4 it is no longer possible to disable this behavior.",{"type":19,"tag":83,"props":1050,"children":1051},{},[1052,1058,1060,1066],{"type":19,"tag":37,"props":1053,"children":1055},{"className":1054},[],[1056],{"type":24,"value":1057},"@vnodeXXX",{"type":24,"value":1059}," event listeners in templates are now a compiler error instead of a deprecation warning. Use ",{"type":19,"tag":37,"props":1061,"children":1063},{"className":1062},[],[1064],{"type":24,"value":1065},"@vue:XXX",{"type":24,"value":1067}," listeners instead.",{"type":19,"tag":83,"props":1069,"children":1070},{},[1071,1077,1079,1100],{"type":19,"tag":37,"props":1072,"children":1074},{"className":1073},[],[1075],{"type":24,"value":1076},"v-is",{"type":24,"value":1078}," directive has been removed. It was deprecated in 3.3. Use the ",{"type":19,"tag":51,"props":1080,"children":1083},{"href":1081,"rel":1082,"target":56},"https://vuejs.org/api/built-in-special-attributes.html#is",[55,55],[1084,1090,1092,1098],{"type":19,"tag":37,"props":1085,"children":1087},{"className":1086},[],[1088],{"type":24,"value":1089},"is",{"type":24,"value":1091}," attribute with ",{"type":19,"tag":37,"props":1093,"children":1095},{"className":1094},[],[1096],{"type":24,"value":1097},"vue:",{"type":24,"value":1099}," prefix",{"type":24,"value":1101}," instead.",{"type":19,"tag":1103,"props":1104,"children":1105},"style",{},[1106],{"type":24,"value":1107},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":8,"searchDepth":292,"depth":292,"links":1109},[1110,1111,1121],{"id":74,"depth":292,"text":77},{"id":146,"depth":292,"text":149,"children":1112},[1113,1114,1115,1117,1119,1120],{"id":153,"depth":353,"text":156},{"id":207,"depth":353,"text":210},{"id":506,"depth":353,"text":1116},"defineModel is Now Stable",{"id":592,"depth":353,"text":1118},"v-bind Same-name Shorthand",{"id":792,"depth":353,"text":795},{"id":853,"depth":353,"text":856},{"id":892,"depth":292,"text":895,"children":1122},[1123,1124],{"id":898,"depth":353,"text":901},{"id":1011,"depth":353,"text":1014},"markdown","content:blog:vue-3-4.md","content","blog/vue-3-4.md","blog/vue-3-4","md",{"loc":5},{"_path":1133,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":1134,"description":1135,"date":1136,"author":12,"gravatar":13,"twitter":14,"excerpt":1137,"body":1143,"_type":1125,"_id":1433,"_source":1127,"_file":1434,"_stem":1435,"_extension":1130,"sitemap":1436},"/blog/vue-2-eol","Vue 2 is Approaching End Of Life","With 2024 almost upon us, we would like to take this opportunity to remind the Vue community that Vue 2 will reach End of Life (EOL) on December 31st, 2023.","2023-12-15",{"type":16,"children":1138},[1139],{"type":19,"tag":20,"props":1140,"children":1141},{},[1142],{"type":24,"value":1135},{"type":16,"children":1144,"toc":1423},[1145,1149,1154,1159,1162,1168,1182,1187,1218,1226,1231,1237,1242,1275,1280,1286,1291,1297,1309,1314,1320,1325,1338,1344,1349,1362,1394,1400],{"type":19,"tag":20,"props":1146,"children":1147},{},[1148],{"type":24,"value":1135},{"type":19,"tag":20,"props":1150,"children":1151},{},[1152],{"type":24,"value":1153},"Vue 2.0 was released more than 7 years ago in 2016. It was a major milestone in Vue's journey of becoming a mainstream framework. Many current Vue users started using Vue during the Vue 2 era, and many great things have been built with it.",{"type":19,"tag":20,"props":1155,"children":1156},{},[1157],{"type":24,"value":1158},"However, active maintenance of two major versions in parallel isn't sustainable for us. As Vue 3 and its ecosystem have matured, it is time for the team to move on and focus our energy on the latest major version.",{"type":19,"tag":63,"props":1160,"children":1161},{},[],{"type":19,"tag":72,"props":1163,"children":1165},{"id":1164},"what-actually-happens-on-december-31-2023",[1166],{"type":24,"value":1167},"What Actually Happens on December 31, 2023?",{"type":19,"tag":20,"props":1169,"children":1170},{},[1171,1173,1180],{"type":24,"value":1172},"For the past 18 months since ",{"type":19,"tag":51,"props":1174,"children":1177},{"href":1175,"rel":1176,"target":56},"https://blog.vuejs.org/posts/vue-2-7-naruto",[55,55],[1178],{"type":24,"value":1179},"Vue 2.7",{"type":24,"value":1181},", Vue 2 has received necessary bug and security fixes, but we stopped shipping new features so we can focus our energy on improving Vue 3.",{"type":19,"tag":20,"props":1183,"children":1184},{},[1185],{"type":24,"value":1186},"As we approach this date, the Vue community should prepare for the deprecation of Vue 2. On December 31, we will mark the following packages as deprecated on npm:",{"type":19,"tag":89,"props":1188,"children":1189},{},[1190,1195,1207],{"type":19,"tag":83,"props":1191,"children":1192},{},[1193],{"type":24,"value":1194},"All major and minor versions of Vue 2 core",{"type":19,"tag":83,"props":1196,"children":1197},{},[1198,1205],{"type":19,"tag":51,"props":1199,"children":1202},{"href":1200,"rel":1201,"target":56},"https://www.npmjs.com/package/vue-router",[55,55],[1203],{"type":24,"value":1204},"vue-router",{"type":24,"value":1206}," versions exclusively supporting Vue 2 (3.x and below)",{"type":19,"tag":83,"props":1208,"children":1209},{},[1210,1217],{"type":19,"tag":51,"props":1211,"children":1214},{"href":1212,"rel":1213,"target":56},"https://www.npmjs.com/package/vuex",[55,55],[1215],{"type":24,"value":1216},"vuex",{"type":24,"value":1206},{"type":19,"tag":20,"props":1219,"children":1220},{},[1221],{"type":19,"tag":98,"props":1222,"children":1223},{},[1224],{"type":24,"value":1225},"After December 31, 2023, Vue 2 will no longer receive new features, updates, or fixes, though it will still be available on all existing distribution channels (CDNs, package managers, Github, etc).",{"type":19,"tag":20,"props":1227,"children":1228},{},[1229],{"type":24,"value":1230},"In other words, your applications will continue to work, but you will get deprecation warnings from your package mananger reminding you that Vue 2 is no longer a supported version.",{"type":19,"tag":72,"props":1232,"children":1234},{"id":1233},"whats-next",[1235],{"type":24,"value":1236},"What’s Next",{"type":19,"tag":20,"props":1238,"children":1239},{},[1240],{"type":24,"value":1241},"Vue 3 has been the default version of Vue since February 7, 2022. Users who have migrated have enjoyed:",{"type":19,"tag":89,"props":1243,"children":1244},{},[1245,1250,1255,1260,1265,1270],{"type":19,"tag":83,"props":1246,"children":1247},{},[1248],{"type":24,"value":1249},"Better performance with a smaller bundle size and faster rendering.",{"type":19,"tag":83,"props":1251,"children":1252},{},[1253],{"type":24,"value":1254},"Enhanced TypeScript support for easier large-scale application development.",{"type":19,"tag":83,"props":1256,"children":1257},{},[1258],{"type":24,"value":1259},"More efficient Proxy-based reactivity system.",{"type":19,"tag":83,"props":1261,"children":1262},{},[1263],{"type":24,"value":1264},"New built-in components like Fragment, Teleport, and Suspense.",{"type":19,"tag":83,"props":1266,"children":1267},{},[1268],{"type":24,"value":1269},"Improved build tooling support and Vue Devtools experience.",{"type":19,"tag":83,"props":1271,"children":1272},{},[1273],{"type":24,"value":1274},"…and more!",{"type":19,"tag":20,"props":1276,"children":1277},{},[1278],{"type":24,"value":1279},"When and if you can, consider migrating!",{"type":19,"tag":72,"props":1281,"children":1283},{"id":1282},"still-on-vue-2-here-are-your-options",[1284],{"type":24,"value":1285},"Still on Vue 2? Here Are Your Options.",{"type":19,"tag":20,"props":1287,"children":1288},{},[1289],{"type":24,"value":1290},"Recognizing the various situations that arise during transitions, we are also fully aware that users may need other options until they’re able to migrate, or maybe migration simply isn't a feasible path. Here are some other options to consider.",{"type":19,"tag":151,"props":1292,"children":1294},{"id":1293},"update-to-the-vue-2-final-release",[1295],{"type":24,"value":1296},"Update to the Vue 2 Final Release",{"type":19,"tag":20,"props":1298,"children":1299},{},[1300,1302,1307],{"type":24,"value":1301},"The to-be-released EOL version (2.7.16) below will be the final release of Vue 2. The planned released date is ",{"type":19,"tag":98,"props":1303,"children":1304},{},[1305],{"type":24,"value":1306},"December 23, 2023",{"type":24,"value":1308},". This patch release includes a few final fixes for 2.7 features and improves type alignment with Vue 3. It is currently in beta and we encourage you to try it out and report any possible regressions between this version and 2.7.15.",{"type":19,"tag":20,"props":1310,"children":1311},{},[1312],{"type":24,"value":1313},"We strongly encourage you to update to 2.7.16 once it's out. This will be the starting point for extended support mentioned below.",{"type":19,"tag":151,"props":1315,"children":1317},{"id":1316},"purchase-extended-support-for-vue-2",[1318],{"type":24,"value":1319},"Purchase Extended Support for Vue 2",{"type":19,"tag":20,"props":1321,"children":1322},{},[1323],{"type":24,"value":1324},"If you have to stay on Vue 2 post-EOL, we have partnered with HeroDevs to offer Never-Ending Support (NES). Vue 2 NES provides ongoing updates and security patches for Vue 2 even after EOL so that applications with strict compliance requirements remain secure and compliant. It also guarantees that Vue 2 applications will continue to operate effectively in modern browsers and maintain compatibility with essential libraries like Nuxt, Vuex, and Vuetify 2. Finally, Vue 2 NES has continuous security monitoring and a 14-day SLA for fixes.",{"type":19,"tag":20,"props":1326,"children":1327},{},[1328,1330,1337],{"type":24,"value":1329},"Vue 2 NES is the continuation of the support you’ve enjoyed during the Vue 2 LTS period — but indefinitely. For more detailed information, visit the ",{"type":19,"tag":51,"props":1331,"children":1334},{"href":1332,"rel":1333,"target":56},"https://www.herodevs.com/support/nes-vue?utm_source=vuejs-org&utm_medium=blog&utm_campaign=eol-by-eoy",[55,55],[1335],{"type":24,"value":1336},"HeroDevs Vue 2 NES page",{"type":24,"value":61},{"type":19,"tag":151,"props":1339,"children":1341},{"id":1340},"notify-your-users-of-your-vue-2-post-eol-plan",[1342],{"type":24,"value":1343},"Notify Your Users of your Vue 2 Post-EOL Plan",{"type":19,"tag":20,"props":1345,"children":1346},{},[1347],{"type":24,"value":1348},"If you can’t migrate to Vue 3 or use Vue 2 NES at the moment but still remain on Vue 2, you may need to consider how you will communicate your Vue 2 security plans to your customers.",{"type":19,"tag":20,"props":1350,"children":1351},{},[1352,1354,1360],{"type":24,"value":1353},"This does not apply to all Vue users, but many teams are prohibited from shipping ",{"type":19,"tag":1355,"props":1356,"children":1357},"em",{},[1358],{"type":24,"value":1359},"unsupported software",{"type":24,"value":1361}," by SLAs, Contracts & Agreements, or other obligations to downstream parties. These could be with customers, compliance agencies, or even internal company departments. For an increasing number of industries, governing regulatory bodies are also raising expectations on what software creators are accountable for.",{"type":19,"tag":20,"props":1363,"children":1364},{},[1365,1367,1374,1376,1383,1385,1392],{"type":24,"value":1366},"If you work with such business requirements, You may need to let your customers, managers, CISO, or other relevant stakeholders, know about your plan to manage support and address any potential CVEs. ",{"type":19,"tag":51,"props":1368,"children":1371},{"href":1369,"rel":1370,"target":56},"https://v2.vuejs.org/lts/#:~:text=For%20the%20record%2C%20Vue%202%20hasn%E2%80%99t%20really%20had%20any%20real%20vulnerabilities%20in%20the%20past%2C%20but%20you%20may%20need%20a%20supported%20version%20to%20fullfil%20regulations%20or%20company%20policies.",[55,55],[1372],{"type":24,"value":1373},"Vue 2 hasn’t had major vulnerabilities",{"type":24,"value":1375}," in the past, but CVEs do turn up for even the most mature EOL projects — whether directly or via compromised dependencies. Subscribing to CVE notifications through organizations like ",{"type":19,"tag":51,"props":1377,"children":1380},{"href":1378,"rel":1379,"target":56},"https://www.opencve.io/",[55,55],[1381],{"type":24,"value":1382},"OpenCVE",{"type":24,"value":1384}," and ",{"type":19,"tag":51,"props":1386,"children":1389},{"href":1387,"rel":1388,"target":56},"https://snyk.io",[55,55],[1390],{"type":24,"value":1391},"Snyk",{"type":24,"value":1393}," can be a good way to find out about vulnerabilities as soon as they’re discovered. Browsers may also ship changes that break legacy libraries - this is rare, but it does happen.",{"type":19,"tag":72,"props":1395,"children":1397},{"id":1396},"looking-forward",[1398],{"type":24,"value":1399},"Looking Forward",{"type":19,"tag":20,"props":1401,"children":1402},{},[1403,1405,1412,1414,1421],{"type":24,"value":1404},"It will be an emotional moment for me when Vue 2 finally reaches EOL, but at the same time I am more excited than ever about the future ahead of us. The Vue 3 ecosystem has been thriving with innovation. Vue 3.4 is ",{"type":19,"tag":51,"props":1406,"children":1409},{"href":1407,"rel":1408,"target":56},"https://github.com/vuejs/core/blob/minor/CHANGELOG.md",[55,55],[1410],{"type":24,"value":1411},"currently in beta",{"type":24,"value":1413}," with performance improvements for both the compiler and runtime. We are also making good progress on ",{"type":19,"tag":51,"props":1415,"children":1418},{"href":1416,"rel":1417,"target":56},"https://github.com/vuejs/core-vapor",[55,55],[1419],{"type":24,"value":1420},"Vapor Mode",{"type":24,"value":1422},". The end of Vue 2 only marks a new beginning - 2024 will be an exciting year for Vue!",{"title":8,"searchDepth":292,"depth":292,"links":1424},[1425,1426,1427,1432],{"id":1164,"depth":292,"text":1167},{"id":1233,"depth":292,"text":1236},{"id":1282,"depth":292,"text":1285,"children":1428},[1429,1430,1431],{"id":1293,"depth":353,"text":1296},{"id":1316,"depth":353,"text":1319},{"id":1340,"depth":353,"text":1343},{"id":1396,"depth":292,"text":1399},"content:blog:vue-2-eol.md","blog/vue-2-eol.md","blog/vue-2-eol",{"loc":1133},{"_path":1438,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":1439,"description":1440,"date":1441,"author":12,"gravatar":13,"twitter":14,"excerpt":1442,"body":1469,"_type":1125,"_id":4433,"_source":1127,"_file":4434,"_stem":4435,"_extension":1130,"sitemap":4436},"/blog/vue-3-3","Announcing Vue 3.3","Today we're excited to announce the release of Vue 3.3 \"Rurouni Kenshin\"!","2023-05-11",{"type":16,"children":1443},[1444,1448],{"type":19,"tag":20,"props":1445,"children":1446},{},[1447],{"type":24,"value":1440},{"type":19,"tag":20,"props":1449,"children":1450},{},[1451,1453,1458,1460,1467],{"type":24,"value":1452},"This release is focused on developer experience improvements - in particular, SFC ",{"type":19,"tag":37,"props":1454,"children":1456},{"className":1455},[],[1457],{"type":24,"value":544},{"type":24,"value":1459}," usage with TypeScript. Together with the 1.6 release of ",{"type":19,"tag":51,"props":1461,"children":1464},{"href":1462,"rel":1463,"target":56},"https://github.com/vuejs/language-tools/",[55,55],[1465],{"type":24,"value":1466},"Vue Language Tools",{"type":24,"value":1468}," (previously known as Volar), we have resolved many long-standing pain points when using Vue with TypeScript.",{"type":16,"children":1470,"toc":4411},[1471,1475,1491,1503,1506,1511,1534,1538,1549,1555,1575,1580,1745,1750,1765,1771,1791,1934,1962,2169,2174,2209,2220,2232,2422,2435,2552,2566,2571,2583,2595,2777,2802,2807,2827,2855,2869,2875,2881,2886,2891,3187,3192,3206,3215,3235,3558,3570,3734,3738,3750,3756,3766,3792,3860,3879,3889,3972,3992,4003,4098,4116,4231,4262,4276,4282,4287,4299,4325,4331,4336,4402,4407],{"type":19,"tag":20,"props":1472,"children":1473},{},[1474],{"type":24,"value":1440},{"type":19,"tag":20,"props":1476,"children":1477},{},[1478,1479,1484,1485,1490],{"type":24,"value":1452},{"type":19,"tag":37,"props":1480,"children":1482},{"className":1481},[],[1483],{"type":24,"value":544},{"type":24,"value":1459},{"type":19,"tag":51,"props":1486,"children":1488},{"href":1462,"rel":1487,"target":56},[55,55],[1489],{"type":24,"value":1466},{"type":24,"value":1468},{"type":19,"tag":20,"props":1492,"children":1493},{},[1494,1496,1502],{"type":24,"value":1495},"This post provides an overview of the highlighted features in 3.3. For the full list of changes, please consult\n",{"type":19,"tag":51,"props":1497,"children":1500},{"href":1498,"rel":1499,"target":56},"https://github.com/vuejs/core/blob/main/CHANGELOG.md#330-2023-05-08",[55,55],[1501],{"type":24,"value":59},{"type":24,"value":61},{"type":19,"tag":63,"props":1504,"children":1505},{},[],{"type":19,"tag":20,"props":1507,"children":1508},{},[1509],{"type":24,"value":1510},":::tip Dependency Updates\nWhen upgrading to 3.3, it is recommended to also update the following dependencies:",{"type":19,"tag":89,"props":1512,"children":1513},{},[1514,1519,1524,1529],{"type":19,"tag":83,"props":1515,"children":1516},{},[1517],{"type":24,"value":1518},"volar / vue-tsc@^1.6.4",{"type":19,"tag":83,"props":1520,"children":1521},{},[1522],{"type":24,"value":1523},"vite@^4.3.5",{"type":19,"tag":83,"props":1525,"children":1526},{},[1527],{"type":24,"value":1528},"@vitejs/plugin-vue@^4.2.0",{"type":19,"tag":83,"props":1530,"children":1531},{},[1532],{"type":24,"value":1533},"vue-loader@^17.1.0 (if using webpack or vue-cli)\n:::",{"type":19,"tag":20,"props":1535,"children":1536},{},[1537],{"type":24,"value":70},{"type":19,"tag":72,"props":1539,"children":1541},{"id":1540},"script-setup-typescript-dx-improvements",[1542,1547],{"type":19,"tag":37,"props":1543,"children":1545},{"className":1544},[],[1546],{"type":24,"value":544},{"type":24,"value":1548}," + TypeScript DX Improvements",{"type":19,"tag":151,"props":1550,"children":1552},{"id":1551},"imported-and-complex-types-support-in-macros",[1553],{"type":24,"value":1554},"Imported and Complex Types Support in Macros",{"type":19,"tag":20,"props":1556,"children":1557},{},[1558,1560,1566,1567,1573],{"type":24,"value":1559},"Previously, types used in the type parameter position of ",{"type":19,"tag":37,"props":1561,"children":1563},{"className":1562},[],[1564],{"type":24,"value":1565},"defineProps",{"type":24,"value":1384},{"type":19,"tag":37,"props":1568,"children":1570},{"className":1569},[],[1571],{"type":24,"value":1572},"defineEmits",{"type":24,"value":1574}," were limited to local types, and only supported type literals and interfaces. This is because Vue needs to be able to analyze the properties on the props interface in order to generate corresponding runtime options.",{"type":19,"tag":20,"props":1576,"children":1577},{},[1578],{"type":24,"value":1579},"This limitation is now resolved in 3.3. The compiler can now resolve imported types, and supports a limited set of complex types:",{"type":19,"tag":236,"props":1581,"children":1583},{"className":623,"code":1582,"language":625,"meta":8,"style":8},"\u003Cscript setup lang=\"ts\">\n  import type { Props } from './foo'\n\n  // imported + intersection type\n  defineProps\u003CProps & { extraProp?: string }>()\n\u003C/script>\n",[1584],{"type":19,"tag":37,"props":1585,"children":1586},{"__ignoreMap":8},[1587,1632,1670,1677,1685,1729],{"type":19,"tag":246,"props":1588,"children":1589},{"class":248,"line":249},[1590,1594,1599,1604,1609,1613,1617,1623,1627],{"type":19,"tag":246,"props":1591,"children":1592},{"style":259},[1593],{"type":24,"value":637},{"type":19,"tag":246,"props":1595,"children":1596},{"style":253},[1597],{"type":24,"value":1598},"script",{"type":19,"tag":246,"props":1600,"children":1601},{"style":650},[1602],{"type":24,"value":1603}," setup",{"type":19,"tag":246,"props":1605,"children":1606},{"style":650},[1607],{"type":24,"value":1608}," lang",{"type":19,"tag":246,"props":1610,"children":1611},{"style":253},[1612],{"type":24,"value":267},{"type":19,"tag":246,"props":1614,"children":1615},{"style":660},[1616],{"type":24,"value":663},{"type":19,"tag":246,"props":1618,"children":1620},{"style":1619},"--shiki-default:#E7EE98",[1621],{"type":24,"value":1622},"ts",{"type":19,"tag":246,"props":1624,"children":1625},{"style":660},[1626],{"type":24,"value":663},{"type":19,"tag":246,"props":1628,"children":1629},{"style":259},[1630],{"type":24,"value":1631},">\n",{"type":19,"tag":246,"props":1633,"children":1634},{"class":248,"line":292},[1635,1640,1645,1650,1655,1660,1665],{"type":19,"tag":246,"props":1636,"children":1637},{"style":253},[1638],{"type":24,"value":1639},"  import",{"type":19,"tag":246,"props":1641,"children":1642},{"style":253},[1643],{"type":24,"value":1644}," type",{"type":19,"tag":246,"props":1646,"children":1647},{"style":259},[1648],{"type":24,"value":1649}," { Props } ",{"type":19,"tag":246,"props":1651,"children":1652},{"style":253},[1653],{"type":24,"value":1654},"from",{"type":19,"tag":246,"props":1656,"children":1657},{"style":660},[1658],{"type":24,"value":1659}," '",{"type":19,"tag":246,"props":1661,"children":1662},{"style":1619},[1663],{"type":24,"value":1664},"./foo",{"type":19,"tag":246,"props":1666,"children":1667},{"style":660},[1668],{"type":24,"value":1669},"'\n",{"type":19,"tag":246,"props":1671,"children":1672},{"class":248,"line":353},[1673],{"type":19,"tag":246,"props":1674,"children":1675},{"emptyLinePlaceholder":357},[1676],{"type":24,"value":360},{"type":19,"tag":246,"props":1678,"children":1679},{"class":248,"line":363},[1680],{"type":19,"tag":246,"props":1681,"children":1682},{"style":395},[1683],{"type":24,"value":1684},"  // imported + intersection type\n",{"type":19,"tag":246,"props":1686,"children":1687},{"class":248,"line":401},[1688,1693,1697,1703,1708,1713,1718,1724],{"type":19,"tag":246,"props":1689,"children":1690},{"style":270},[1691],{"type":24,"value":1692},"  defineProps",{"type":19,"tag":246,"props":1694,"children":1695},{"style":259},[1696],{"type":24,"value":637},{"type":19,"tag":246,"props":1698,"children":1700},{"style":1699},"--shiki-default:#FFB86C;--shiki-default-font-style:italic",[1701],{"type":24,"value":1702},"Props",{"type":19,"tag":246,"props":1704,"children":1705},{"style":253},[1706],{"type":24,"value":1707}," &",{"type":19,"tag":246,"props":1709,"children":1710},{"style":259},[1711],{"type":24,"value":1712}," { extraProp",{"type":19,"tag":246,"props":1714,"children":1715},{"style":253},[1716],{"type":24,"value":1717},"?:",{"type":19,"tag":246,"props":1719,"children":1721},{"style":1720},"--shiki-default:#97E1F1;--shiki-default-font-style:italic",[1722],{"type":24,"value":1723}," string",{"type":19,"tag":246,"props":1725,"children":1726},{"style":259},[1727],{"type":24,"value":1728}," }>()\n",{"type":19,"tag":246,"props":1730,"children":1731},{"class":248,"line":409},[1732,1737,1741],{"type":19,"tag":246,"props":1733,"children":1734},{"style":259},[1735],{"type":24,"value":1736},"\u003C/",{"type":19,"tag":246,"props":1738,"children":1739},{"style":253},[1740],{"type":24,"value":1598},{"type":19,"tag":246,"props":1742,"children":1743},{"style":259},[1744],{"type":24,"value":1631},{"type":19,"tag":20,"props":1746,"children":1747},{},[1748],{"type":24,"value":1749},"Do note that complex types support is AST-based and therefore not 100% comprehensive. Some complex types that require actual type analysis, e.g. conditional types, are not supported. You can use conditional types for the type of a single prop, but not the entire props object.",{"type":19,"tag":89,"props":1751,"children":1752},{},[1753],{"type":19,"tag":83,"props":1754,"children":1755},{},[1756,1758],{"type":24,"value":1757},"Details: ",{"type":19,"tag":51,"props":1759,"children":1762},{"href":1760,"rel":1761,"target":56},"https://github.com/vuejs/core/pull/8083",[55,55],[1763],{"type":24,"value":1764},"PR#8083",{"type":19,"tag":151,"props":1766,"children":1768},{"id":1767},"generic-components",[1769],{"type":24,"value":1770},"Generic Components",{"type":19,"tag":20,"props":1772,"children":1773},{},[1774,1776,1781,1783,1789],{"type":24,"value":1775},"Components using ",{"type":19,"tag":37,"props":1777,"children":1779},{"className":1778},[],[1780],{"type":24,"value":544},{"type":24,"value":1782}," can now accept generic type parameters via the ",{"type":19,"tag":37,"props":1784,"children":1786},{"className":1785},[],[1787],{"type":24,"value":1788},"generic",{"type":24,"value":1790}," attribute:",{"type":19,"tag":236,"props":1792,"children":1794},{"className":623,"code":1793,"language":625,"meta":8,"style":8},"\u003Cscript setup lang=\"ts\" generic=\"T\">\n  defineProps\u003C{\n    items: T[]\n    selected: T\n  }>()\n\u003C/script>\n",[1795],{"type":19,"tag":37,"props":1796,"children":1797},{"__ignoreMap":8},[1798,1859,1871,1894,1911,1919],{"type":19,"tag":246,"props":1799,"children":1800},{"class":248,"line":249},[1801,1805,1809,1813,1817,1821,1825,1829,1833,1838,1842,1846,1851,1855],{"type":19,"tag":246,"props":1802,"children":1803},{"style":259},[1804],{"type":24,"value":637},{"type":19,"tag":246,"props":1806,"children":1807},{"style":253},[1808],{"type":24,"value":1598},{"type":19,"tag":246,"props":1810,"children":1811},{"style":650},[1812],{"type":24,"value":1603},{"type":19,"tag":246,"props":1814,"children":1815},{"style":650},[1816],{"type":24,"value":1608},{"type":19,"tag":246,"props":1818,"children":1819},{"style":253},[1820],{"type":24,"value":267},{"type":19,"tag":246,"props":1822,"children":1823},{"style":660},[1824],{"type":24,"value":663},{"type":19,"tag":246,"props":1826,"children":1827},{"style":1619},[1828],{"type":24,"value":1622},{"type":19,"tag":246,"props":1830,"children":1831},{"style":660},[1832],{"type":24,"value":663},{"type":19,"tag":246,"props":1834,"children":1835},{"style":650},[1836],{"type":24,"value":1837}," generic",{"type":19,"tag":246,"props":1839,"children":1840},{"style":253},[1841],{"type":24,"value":267},{"type":19,"tag":246,"props":1843,"children":1844},{"style":660},[1845],{"type":24,"value":663},{"type":19,"tag":246,"props":1847,"children":1848},{"style":1699},[1849],{"type":24,"value":1850},"T",{"type":19,"tag":246,"props":1852,"children":1853},{"style":660},[1854],{"type":24,"value":663},{"type":19,"tag":246,"props":1856,"children":1857},{"style":259},[1858],{"type":24,"value":1631},{"type":19,"tag":246,"props":1860,"children":1861},{"class":248,"line":292},[1862,1866],{"type":19,"tag":246,"props":1863,"children":1864},{"style":270},[1865],{"type":24,"value":1692},{"type":19,"tag":246,"props":1867,"children":1868},{"style":259},[1869],{"type":24,"value":1870},"\u003C{\n",{"type":19,"tag":246,"props":1872,"children":1873},{"class":248,"line":353},[1874,1879,1884,1889],{"type":19,"tag":246,"props":1875,"children":1876},{"style":259},[1877],{"type":24,"value":1878},"    items",{"type":19,"tag":246,"props":1880,"children":1881},{"style":253},[1882],{"type":24,"value":1883},":",{"type":19,"tag":246,"props":1885,"children":1886},{"style":1699},[1887],{"type":24,"value":1888}," T",{"type":19,"tag":246,"props":1890,"children":1891},{"style":259},[1892],{"type":24,"value":1893},"[]\n",{"type":19,"tag":246,"props":1895,"children":1896},{"class":248,"line":363},[1897,1902,1906],{"type":19,"tag":246,"props":1898,"children":1899},{"style":259},[1900],{"type":24,"value":1901},"    selected",{"type":19,"tag":246,"props":1903,"children":1904},{"style":253},[1905],{"type":24,"value":1883},{"type":19,"tag":246,"props":1907,"children":1908},{"style":1699},[1909],{"type":24,"value":1910}," T\n",{"type":19,"tag":246,"props":1912,"children":1913},{"class":248,"line":401},[1914],{"type":19,"tag":246,"props":1915,"children":1916},{"style":259},[1917],{"type":24,"value":1918},"  }>()\n",{"type":19,"tag":246,"props":1920,"children":1921},{"class":248,"line":409},[1922,1926,1930],{"type":19,"tag":246,"props":1923,"children":1924},{"style":259},[1925],{"type":24,"value":1736},{"type":19,"tag":246,"props":1927,"children":1928},{"style":253},[1929],{"type":24,"value":1598},{"type":19,"tag":246,"props":1931,"children":1932},{"style":259},[1933],{"type":24,"value":1631},{"type":19,"tag":20,"props":1935,"children":1936},{},[1937,1939,1944,1946,1952,1954,1960],{"type":24,"value":1938},"The value of ",{"type":19,"tag":37,"props":1940,"children":1942},{"className":1941},[],[1943],{"type":24,"value":1788},{"type":24,"value":1945}," works exactly the same as the parameter list between ",{"type":19,"tag":37,"props":1947,"children":1949},{"className":1948},[],[1950],{"type":24,"value":1951},"\u003C...>",{"type":24,"value":1953}," in TypeScript. For example, you can use multiple parameters, ",{"type":19,"tag":37,"props":1955,"children":1957},{"className":1956},[],[1958],{"type":24,"value":1959},"extends",{"type":24,"value":1961}," constraints, default types, and reference imported types:",{"type":19,"tag":236,"props":1963,"children":1965},{"className":623,"code":1964,"language":625,"meta":8,"style":8},"\u003Cscript setup lang=\"ts\" generic=\"T extends string | number, U extends Item\">\n  import type { Item } from './types'\n  defineProps\u003C{\n    id: T\n    list: U[]\n  }>()\n\u003C/script>\n",[1966],{"type":19,"tag":37,"props":1967,"children":1968},{"__ignoreMap":8},[1969,2065,2098,2109,2125,2146,2153],{"type":19,"tag":246,"props":1970,"children":1971},{"class":248,"line":249},[1972,1976,1980,1984,1988,1992,1996,2000,2004,2008,2012,2016,2020,2025,2029,2034,2039,2043,2048,2052,2057,2061],{"type":19,"tag":246,"props":1973,"children":1974},{"style":259},[1975],{"type":24,"value":637},{"type":19,"tag":246,"props":1977,"children":1978},{"style":253},[1979],{"type":24,"value":1598},{"type":19,"tag":246,"props":1981,"children":1982},{"style":650},[1983],{"type":24,"value":1603},{"type":19,"tag":246,"props":1985,"children":1986},{"style":650},[1987],{"type":24,"value":1608},{"type":19,"tag":246,"props":1989,"children":1990},{"style":253},[1991],{"type":24,"value":267},{"type":19,"tag":246,"props":1993,"children":1994},{"style":660},[1995],{"type":24,"value":663},{"type":19,"tag":246,"props":1997,"children":1998},{"style":1619},[1999],{"type":24,"value":1622},{"type":19,"tag":246,"props":2001,"children":2002},{"style":660},[2003],{"type":24,"value":663},{"type":19,"tag":246,"props":2005,"children":2006},{"style":650},[2007],{"type":24,"value":1837},{"type":19,"tag":246,"props":2009,"children":2010},{"style":253},[2011],{"type":24,"value":267},{"type":19,"tag":246,"props":2013,"children":2014},{"style":660},[2015],{"type":24,"value":663},{"type":19,"tag":246,"props":2017,"children":2018},{"style":1699},[2019],{"type":24,"value":1850},{"type":19,"tag":246,"props":2021,"children":2022},{"style":253},[2023],{"type":24,"value":2024}," extends",{"type":19,"tag":246,"props":2026,"children":2027},{"style":1720},[2028],{"type":24,"value":1723},{"type":19,"tag":246,"props":2030,"children":2031},{"style":253},[2032],{"type":24,"value":2033}," |",{"type":19,"tag":246,"props":2035,"children":2036},{"style":1720},[2037],{"type":24,"value":2038}," number",{"type":19,"tag":246,"props":2040,"children":2041},{"style":259},[2042],{"type":24,"value":474},{"type":19,"tag":246,"props":2044,"children":2045},{"style":1699},[2046],{"type":24,"value":2047},"U",{"type":19,"tag":246,"props":2049,"children":2050},{"style":253},[2051],{"type":24,"value":2024},{"type":19,"tag":246,"props":2053,"children":2054},{"style":1699},[2055],{"type":24,"value":2056}," Item",{"type":19,"tag":246,"props":2058,"children":2059},{"style":660},[2060],{"type":24,"value":663},{"type":19,"tag":246,"props":2062,"children":2063},{"style":259},[2064],{"type":24,"value":1631},{"type":19,"tag":246,"props":2066,"children":2067},{"class":248,"line":292},[2068,2072,2076,2081,2085,2089,2094],{"type":19,"tag":246,"props":2069,"children":2070},{"style":253},[2071],{"type":24,"value":1639},{"type":19,"tag":246,"props":2073,"children":2074},{"style":253},[2075],{"type":24,"value":1644},{"type":19,"tag":246,"props":2077,"children":2078},{"style":259},[2079],{"type":24,"value":2080}," { Item } ",{"type":19,"tag":246,"props":2082,"children":2083},{"style":253},[2084],{"type":24,"value":1654},{"type":19,"tag":246,"props":2086,"children":2087},{"style":660},[2088],{"type":24,"value":1659},{"type":19,"tag":246,"props":2090,"children":2091},{"style":1619},[2092],{"type":24,"value":2093},"./types",{"type":19,"tag":246,"props":2095,"children":2096},{"style":660},[2097],{"type":24,"value":1669},{"type":19,"tag":246,"props":2099,"children":2100},{"class":248,"line":353},[2101,2105],{"type":19,"tag":246,"props":2102,"children":2103},{"style":270},[2104],{"type":24,"value":1692},{"type":19,"tag":246,"props":2106,"children":2107},{"style":259},[2108],{"type":24,"value":1870},{"type":19,"tag":246,"props":2110,"children":2111},{"class":248,"line":363},[2112,2117,2121],{"type":19,"tag":246,"props":2113,"children":2114},{"style":259},[2115],{"type":24,"value":2116},"    id",{"type":19,"tag":246,"props":2118,"children":2119},{"style":253},[2120],{"type":24,"value":1883},{"type":19,"tag":246,"props":2122,"children":2123},{"style":1699},[2124],{"type":24,"value":1910},{"type":19,"tag":246,"props":2126,"children":2127},{"class":248,"line":401},[2128,2133,2137,2142],{"type":19,"tag":246,"props":2129,"children":2130},{"style":259},[2131],{"type":24,"value":2132},"    list",{"type":19,"tag":246,"props":2134,"children":2135},{"style":253},[2136],{"type":24,"value":1883},{"type":19,"tag":246,"props":2138,"children":2139},{"style":1699},[2140],{"type":24,"value":2141}," U",{"type":19,"tag":246,"props":2143,"children":2144},{"style":259},[2145],{"type":24,"value":1893},{"type":19,"tag":246,"props":2147,"children":2148},{"class":248,"line":409},[2149],{"type":19,"tag":246,"props":2150,"children":2151},{"style":259},[2152],{"type":24,"value":1918},{"type":19,"tag":246,"props":2154,"children":2156},{"class":248,"line":2155},7,[2157,2161,2165],{"type":19,"tag":246,"props":2158,"children":2159},{"style":259},[2160],{"type":24,"value":1736},{"type":19,"tag":246,"props":2162,"children":2163},{"style":253},[2164],{"type":24,"value":1598},{"type":19,"tag":246,"props":2166,"children":2167},{"style":259},[2168],{"type":24,"value":1631},{"type":19,"tag":20,"props":2170,"children":2171},{},[2172],{"type":24,"value":2173},"This feature previously required explicit opt-in, but is now enabled by default in the latest version of volar / vue-tsc.",{"type":19,"tag":89,"props":2175,"children":2176},{},[2177,2189],{"type":19,"tag":83,"props":2178,"children":2179},{},[2180,2182],{"type":24,"value":2181},"Discussion: ",{"type":19,"tag":51,"props":2183,"children":2186},{"href":2184,"rel":2185,"target":56},"https://github.com/vuejs/rfcs/discussions/436",[55,55],[2187],{"type":24,"value":2188},"RFC#436",{"type":19,"tag":83,"props":2190,"children":2191},{},[2192,2194],{"type":24,"value":2193},"Related: ",{"type":19,"tag":51,"props":2195,"children":2198},{"href":2196,"rel":2197,"target":56},"https://github.com/vuejs/core/pull/7963",[55,55],[2199,2201,2207],{"type":24,"value":2200},"generic ",{"type":19,"tag":37,"props":2202,"children":2204},{"className":2203},[],[2205],{"type":24,"value":2206},"defineComponent()",{"type":24,"value":2208}," - PR#7963",{"type":19,"tag":151,"props":2210,"children":2212},{"id":2211},"more-ergonomic-defineemits",[2213,2215],{"type":24,"value":2214},"More Ergonomic ",{"type":19,"tag":37,"props":2216,"children":2218},{"className":2217},[],[2219],{"type":24,"value":1572},{"type":19,"tag":20,"props":2221,"children":2222},{},[2223,2225,2230],{"type":24,"value":2224},"Previously, the type parameter for ",{"type":19,"tag":37,"props":2226,"children":2228},{"className":2227},[],[2229],{"type":24,"value":1572},{"type":24,"value":2231}," only supports the call signature syntax:",{"type":19,"tag":236,"props":2233,"children":2236},{"className":2234,"code":2235,"language":1622,"meta":8,"style":8},"language-ts shiki shiki-themes dracula-soft","// BEFORE\nconst emit = defineEmits\u003C{\n  (e: 'foo', id: number): void\n  (e: 'bar', name: string, ...rest: any[]): void\n}>()\n",[2237],{"type":19,"tag":37,"props":2238,"children":2239},{"__ignoreMap":8},[2240,2248,2273,2333,2414],{"type":19,"tag":246,"props":2241,"children":2242},{"class":248,"line":249},[2243],{"type":19,"tag":246,"props":2244,"children":2245},{"style":395},[2246],{"type":24,"value":2247},"// BEFORE\n",{"type":19,"tag":246,"props":2249,"children":2250},{"class":248,"line":292},[2251,2255,2260,2264,2269],{"type":19,"tag":246,"props":2252,"children":2253},{"style":253},[2254],{"type":24,"value":256},{"type":19,"tag":246,"props":2256,"children":2257},{"style":259},[2258],{"type":24,"value":2259}," emit ",{"type":19,"tag":246,"props":2261,"children":2262},{"style":253},[2263],{"type":24,"value":267},{"type":19,"tag":246,"props":2265,"children":2266},{"style":270},[2267],{"type":24,"value":2268}," defineEmits",{"type":19,"tag":246,"props":2270,"children":2271},{"style":259},[2272],{"type":24,"value":1870},{"type":19,"tag":246,"props":2274,"children":2275},{"class":248,"line":353},[2276,2281,2286,2290,2294,2299,2304,2308,2312,2316,2320,2324,2328],{"type":19,"tag":246,"props":2277,"children":2278},{"style":259},[2279],{"type":24,"value":2280},"  (",{"type":19,"tag":246,"props":2282,"children":2283},{"style":1699},[2284],{"type":24,"value":2285},"e",{"type":19,"tag":246,"props":2287,"children":2288},{"style":253},[2289],{"type":24,"value":1883},{"type":19,"tag":246,"props":2291,"children":2292},{"style":660},[2293],{"type":24,"value":1659},{"type":19,"tag":246,"props":2295,"children":2296},{"style":1619},[2297],{"type":24,"value":2298},"foo",{"type":19,"tag":246,"props":2300,"children":2301},{"style":660},[2302],{"type":24,"value":2303},"'",{"type":19,"tag":246,"props":2305,"children":2306},{"style":259},[2307],{"type":24,"value":474},{"type":19,"tag":246,"props":2309,"children":2310},{"style":1699},[2311],{"type":24,"value":653},{"type":19,"tag":246,"props":2313,"children":2314},{"style":253},[2315],{"type":24,"value":1883},{"type":19,"tag":246,"props":2317,"children":2318},{"style":1720},[2319],{"type":24,"value":2038},{"type":19,"tag":246,"props":2321,"children":2322},{"style":259},[2323],{"type":24,"value":104},{"type":19,"tag":246,"props":2325,"children":2326},{"style":253},[2327],{"type":24,"value":1883},{"type":19,"tag":246,"props":2329,"children":2330},{"style":1720},[2331],{"type":24,"value":2332}," void\n",{"type":19,"tag":246,"props":2334,"children":2335},{"class":248,"line":363},[2336,2340,2344,2348,2352,2357,2361,2365,2370,2374,2378,2382,2387,2392,2396,2401,2406,2410],{"type":19,"tag":246,"props":2337,"children":2338},{"style":259},[2339],{"type":24,"value":2280},{"type":19,"tag":246,"props":2341,"children":2342},{"style":1699},[2343],{"type":24,"value":2285},{"type":19,"tag":246,"props":2345,"children":2346},{"style":253},[2347],{"type":24,"value":1883},{"type":19,"tag":246,"props":2349,"children":2350},{"style":660},[2351],{"type":24,"value":1659},{"type":19,"tag":246,"props":2353,"children":2354},{"style":1619},[2355],{"type":24,"value":2356},"bar",{"type":19,"tag":246,"props":2358,"children":2359},{"style":660},[2360],{"type":24,"value":2303},{"type":19,"tag":246,"props":2362,"children":2363},{"style":259},[2364],{"type":24,"value":474},{"type":19,"tag":246,"props":2366,"children":2367},{"style":1699},[2368],{"type":24,"value":2369},"name",{"type":19,"tag":246,"props":2371,"children":2372},{"style":253},[2373],{"type":24,"value":1883},{"type":19,"tag":246,"props":2375,"children":2376},{"style":1720},[2377],{"type":24,"value":1723},{"type":19,"tag":246,"props":2379,"children":2380},{"style":259},[2381],{"type":24,"value":474},{"type":19,"tag":246,"props":2383,"children":2384},{"style":253},[2385],{"type":24,"value":2386},"...",{"type":19,"tag":246,"props":2388,"children":2389},{"style":1699},[2390],{"type":24,"value":2391},"rest",{"type":19,"tag":246,"props":2393,"children":2394},{"style":253},[2395],{"type":24,"value":1883},{"type":19,"tag":246,"props":2397,"children":2398},{"style":1720},[2399],{"type":24,"value":2400}," any",{"type":19,"tag":246,"props":2402,"children":2403},{"style":259},[2404],{"type":24,"value":2405},"[])",{"type":19,"tag":246,"props":2407,"children":2408},{"style":253},[2409],{"type":24,"value":1883},{"type":19,"tag":246,"props":2411,"children":2412},{"style":1720},[2413],{"type":24,"value":2332},{"type":19,"tag":246,"props":2415,"children":2416},{"class":248,"line":401},[2417],{"type":19,"tag":246,"props":2418,"children":2419},{"style":259},[2420],{"type":24,"value":2421},"}>()\n",{"type":19,"tag":20,"props":2423,"children":2424},{},[2425,2427,2433],{"type":24,"value":2426},"The type matches the return type for ",{"type":19,"tag":37,"props":2428,"children":2430},{"className":2429},[],[2431],{"type":24,"value":2432},"emit",{"type":24,"value":2434},", but is a bit verbose and awkward to write. 3.3 introduces a more ergonomic way of declaring emits with types:",{"type":19,"tag":236,"props":2436,"children":2438},{"className":2234,"code":2437,"language":1622,"meta":8,"style":8},"// AFTER\nconst emit = defineEmits\u003C{\n  foo: [id: number]\n  bar: [name: string, ...rest: any[]]\n}>()\n",[2439],{"type":19,"tag":37,"props":2440,"children":2441},{"__ignoreMap":8},[2442,2450,2473,2500,2545],{"type":19,"tag":246,"props":2443,"children":2444},{"class":248,"line":249},[2445],{"type":19,"tag":246,"props":2446,"children":2447},{"style":395},[2448],{"type":24,"value":2449},"// AFTER\n",{"type":19,"tag":246,"props":2451,"children":2452},{"class":248,"line":292},[2453,2457,2461,2465,2469],{"type":19,"tag":246,"props":2454,"children":2455},{"style":253},[2456],{"type":24,"value":256},{"type":19,"tag":246,"props":2458,"children":2459},{"style":259},[2460],{"type":24,"value":2259},{"type":19,"tag":246,"props":2462,"children":2463},{"style":253},[2464],{"type":24,"value":267},{"type":19,"tag":246,"props":2466,"children":2467},{"style":270},[2468],{"type":24,"value":2268},{"type":19,"tag":246,"props":2470,"children":2471},{"style":259},[2472],{"type":24,"value":1870},{"type":19,"tag":246,"props":2474,"children":2475},{"class":248,"line":353},[2476,2481,2485,2490,2495],{"type":19,"tag":246,"props":2477,"children":2478},{"style":259},[2479],{"type":24,"value":2480},"  foo",{"type":19,"tag":246,"props":2482,"children":2483},{"style":253},[2484],{"type":24,"value":1883},{"type":19,"tag":246,"props":2486,"children":2487},{"style":259},[2488],{"type":24,"value":2489}," [id: ",{"type":19,"tag":246,"props":2491,"children":2492},{"style":1720},[2493],{"type":24,"value":2494},"number",{"type":19,"tag":246,"props":2496,"children":2497},{"style":259},[2498],{"type":24,"value":2499},"]\n",{"type":19,"tag":246,"props":2501,"children":2502},{"class":248,"line":363},[2503,2508,2512,2517,2522,2526,2530,2535,2540],{"type":19,"tag":246,"props":2504,"children":2505},{"style":259},[2506],{"type":24,"value":2507},"  bar",{"type":19,"tag":246,"props":2509,"children":2510},{"style":253},[2511],{"type":24,"value":1883},{"type":19,"tag":246,"props":2513,"children":2514},{"style":259},[2515],{"type":24,"value":2516}," [name: ",{"type":19,"tag":246,"props":2518,"children":2519},{"style":1720},[2520],{"type":24,"value":2521},"string",{"type":19,"tag":246,"props":2523,"children":2524},{"style":259},[2525],{"type":24,"value":474},{"type":19,"tag":246,"props":2527,"children":2528},{"style":253},[2529],{"type":24,"value":2386},{"type":19,"tag":246,"props":2531,"children":2532},{"style":259},[2533],{"type":24,"value":2534},"rest: ",{"type":19,"tag":246,"props":2536,"children":2537},{"style":1720},[2538],{"type":24,"value":2539},"any",{"type":19,"tag":246,"props":2541,"children":2542},{"style":259},[2543],{"type":24,"value":2544},"[]]\n",{"type":19,"tag":246,"props":2546,"children":2547},{"class":248,"line":401},[2548],{"type":19,"tag":246,"props":2549,"children":2550},{"style":259},[2551],{"type":24,"value":2421},{"type":19,"tag":20,"props":2553,"children":2554},{},[2555,2557,2564],{"type":24,"value":2556},"In the type literal, the key is the event name and the value is an array type specifying the additional arguments. Although not required, you can use the ",{"type":19,"tag":51,"props":2558,"children":2561},{"href":2559,"rel":2560,"target":56},"https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html#labeled-tuple-elements",[55,55],[2562],{"type":24,"value":2563},"labeled tuple elements",{"type":24,"value":2565}," for explicitness, like in the example above.",{"type":19,"tag":20,"props":2567,"children":2568},{},[2569],{"type":24,"value":2570},"The call signature syntax is still supported.",{"type":19,"tag":151,"props":2572,"children":2574},{"id":2573},"typed-slots-with-defineslots",[2575,2577],{"type":24,"value":2576},"Typed Slots with ",{"type":19,"tag":37,"props":2578,"children":2580},{"className":2579},[],[2581],{"type":24,"value":2582},"defineSlots",{"type":19,"tag":20,"props":2584,"children":2585},{},[2586,2588,2593],{"type":24,"value":2587},"The new ",{"type":19,"tag":37,"props":2589,"children":2591},{"className":2590},[],[2592],{"type":24,"value":2582},{"type":24,"value":2594}," macro can be used to declare expected slots and their respective expected slot props:",{"type":19,"tag":236,"props":2596,"children":2598},{"className":623,"code":2597,"language":625,"meta":8,"style":8},"\u003Cscript setup lang=\"ts\">\n  defineSlots\u003C{\n    default?: (props: { msg: string }) => any\n    item?: (props: { id: number }) => any\n  }>()\n\u003C/script>\n",[2599],{"type":19,"tag":37,"props":2600,"children":2601},{"__ignoreMap":8},[2602,2641,2653,2706,2755,2762],{"type":19,"tag":246,"props":2603,"children":2604},{"class":248,"line":249},[2605,2609,2613,2617,2621,2625,2629,2633,2637],{"type":19,"tag":246,"props":2606,"children":2607},{"style":259},[2608],{"type":24,"value":637},{"type":19,"tag":246,"props":2610,"children":2611},{"style":253},[2612],{"type":24,"value":1598},{"type":19,"tag":246,"props":2614,"children":2615},{"style":650},[2616],{"type":24,"value":1603},{"type":19,"tag":246,"props":2618,"children":2619},{"style":650},[2620],{"type":24,"value":1608},{"type":19,"tag":246,"props":2622,"children":2623},{"style":253},[2624],{"type":24,"value":267},{"type":19,"tag":246,"props":2626,"children":2627},{"style":660},[2628],{"type":24,"value":663},{"type":19,"tag":246,"props":2630,"children":2631},{"style":1619},[2632],{"type":24,"value":1622},{"type":19,"tag":246,"props":2634,"children":2635},{"style":660},[2636],{"type":24,"value":663},{"type":19,"tag":246,"props":2638,"children":2639},{"style":259},[2640],{"type":24,"value":1631},{"type":19,"tag":246,"props":2642,"children":2643},{"class":248,"line":292},[2644,2649],{"type":19,"tag":246,"props":2645,"children":2646},{"style":270},[2647],{"type":24,"value":2648},"  defineSlots",{"type":19,"tag":246,"props":2650,"children":2651},{"style":259},[2652],{"type":24,"value":1870},{"type":19,"tag":246,"props":2654,"children":2655},{"class":248,"line":353},[2656,2661,2665,2670,2675,2679,2684,2688,2692,2697,2701],{"type":19,"tag":246,"props":2657,"children":2658},{"style":270},[2659],{"type":24,"value":2660},"    default",{"type":19,"tag":246,"props":2662,"children":2663},{"style":253},[2664],{"type":24,"value":1717},{"type":19,"tag":246,"props":2666,"children":2667},{"style":259},[2668],{"type":24,"value":2669}," (",{"type":19,"tag":246,"props":2671,"children":2672},{"style":1699},[2673],{"type":24,"value":2674},"props",{"type":19,"tag":246,"props":2676,"children":2677},{"style":253},[2678],{"type":24,"value":1883},{"type":19,"tag":246,"props":2680,"children":2681},{"style":259},[2682],{"type":24,"value":2683}," { msg",{"type":19,"tag":246,"props":2685,"children":2686},{"style":253},[2687],{"type":24,"value":1883},{"type":19,"tag":246,"props":2689,"children":2690},{"style":1720},[2691],{"type":24,"value":1723},{"type":19,"tag":246,"props":2693,"children":2694},{"style":259},[2695],{"type":24,"value":2696}," }) ",{"type":19,"tag":246,"props":2698,"children":2699},{"style":253},[2700],{"type":24,"value":321},{"type":19,"tag":246,"props":2702,"children":2703},{"style":1720},[2704],{"type":24,"value":2705}," any\n",{"type":19,"tag":246,"props":2707,"children":2708},{"class":248,"line":363},[2709,2714,2718,2722,2726,2730,2735,2739,2743,2747,2751],{"type":19,"tag":246,"props":2710,"children":2711},{"style":270},[2712],{"type":24,"value":2713},"    item",{"type":19,"tag":246,"props":2715,"children":2716},{"style":253},[2717],{"type":24,"value":1717},{"type":19,"tag":246,"props":2719,"children":2720},{"style":259},[2721],{"type":24,"value":2669},{"type":19,"tag":246,"props":2723,"children":2724},{"style":1699},[2725],{"type":24,"value":2674},{"type":19,"tag":246,"props":2727,"children":2728},{"style":253},[2729],{"type":24,"value":1883},{"type":19,"tag":246,"props":2731,"children":2732},{"style":259},[2733],{"type":24,"value":2734}," { id",{"type":19,"tag":246,"props":2736,"children":2737},{"style":253},[2738],{"type":24,"value":1883},{"type":19,"tag":246,"props":2740,"children":2741},{"style":1720},[2742],{"type":24,"value":2038},{"type":19,"tag":246,"props":2744,"children":2745},{"style":259},[2746],{"type":24,"value":2696},{"type":19,"tag":246,"props":2748,"children":2749},{"style":253},[2750],{"type":24,"value":321},{"type":19,"tag":246,"props":2752,"children":2753},{"style":1720},[2754],{"type":24,"value":2705},{"type":19,"tag":246,"props":2756,"children":2757},{"class":248,"line":401},[2758],{"type":19,"tag":246,"props":2759,"children":2760},{"style":259},[2761],{"type":24,"value":1918},{"type":19,"tag":246,"props":2763,"children":2764},{"class":248,"line":409},[2765,2769,2773],{"type":19,"tag":246,"props":2766,"children":2767},{"style":259},[2768],{"type":24,"value":1736},{"type":19,"tag":246,"props":2770,"children":2771},{"style":253},[2772],{"type":24,"value":1598},{"type":19,"tag":246,"props":2774,"children":2775},{"style":259},[2776],{"type":24,"value":1631},{"type":19,"tag":20,"props":2778,"children":2779},{},[2780,2786,2788,2793,2795,2801],{"type":19,"tag":37,"props":2781,"children":2783},{"className":2782},[],[2784],{"type":24,"value":2785},"defineSlots()",{"type":24,"value":2787}," only accepts a type parameter and no runtime arguments. The type parameter should be a type literal where the property key is the slot name, and the value is a slot function. The first argument of the function is the props the slot expects to receive, and its type will be used for slot props in the template. The returning value of ",{"type":19,"tag":37,"props":2789,"children":2791},{"className":2790},[],[2792],{"type":24,"value":2582},{"type":24,"value":2794}," is the same slots object returned from ",{"type":19,"tag":37,"props":2796,"children":2798},{"className":2797},[],[2799],{"type":24,"value":2800},"useSlots",{"type":24,"value":61},{"type":19,"tag":20,"props":2803,"children":2804},{},[2805],{"type":24,"value":2806},"Some current limitations:",{"type":19,"tag":89,"props":2808,"children":2809},{},[2810,2815],{"type":19,"tag":83,"props":2811,"children":2812},{},[2813],{"type":24,"value":2814},"Required slots checking is not yet implemented in volar / vue-tsc.",{"type":19,"tag":83,"props":2816,"children":2817},{},[2818,2820,2825],{"type":24,"value":2819},"Slot function return type is currently ignored and can be ",{"type":19,"tag":37,"props":2821,"children":2823},{"className":2822},[],[2824],{"type":24,"value":2539},{"type":24,"value":2826},", but we may leverage it for slot content checking in the future.",{"type":19,"tag":20,"props":2828,"children":2829},{},[2830,2832,2838,2840,2846,2848,2854],{"type":24,"value":2831},"There is also a corresponding ",{"type":19,"tag":37,"props":2833,"children":2835},{"className":2834},[],[2836],{"type":24,"value":2837},"slots",{"type":24,"value":2839}," option for ",{"type":19,"tag":37,"props":2841,"children":2843},{"className":2842},[],[2844],{"type":24,"value":2845},"defineComponent",{"type":24,"value":2847}," usage. Both APIs have no runtime implications and serve purely as type hints for IDEs and ",{"type":19,"tag":37,"props":2849,"children":2851},{"className":2850},[],[2852],{"type":24,"value":2853},"vue-tsc",{"type":24,"value":61},{"type":19,"tag":89,"props":2856,"children":2857},{},[2858],{"type":19,"tag":83,"props":2859,"children":2860},{},[2861,2862],{"type":24,"value":1757},{"type":19,"tag":51,"props":2863,"children":2866},{"href":2864,"rel":2865,"target":56},"https://github.com/vuejs/core/issues/7982",[55,55],[2867],{"type":24,"value":2868},"PR#7982",{"type":19,"tag":72,"props":2870,"children":2872},{"id":2871},"experimental-features",[2873],{"type":24,"value":2874},"Experimental Features",{"type":19,"tag":151,"props":2876,"children":2878},{"id":2877},"reactive-props-destructure",[2879],{"type":24,"value":2880},"Reactive Props Destructure",{"type":19,"tag":20,"props":2882,"children":2883},{},[2884],{"type":24,"value":2885},"Previously part of the now-dropped Reactivity Transform, reactive props destructure has been split into a separate feature.",{"type":19,"tag":20,"props":2887,"children":2888},{},[2889],{"type":24,"value":2890},"The feature allows destructured props to retain reactivity, and provides a more ergonomic way to declare props default values:",{"type":19,"tag":236,"props":2892,"children":2894},{"className":623,"code":2893,"language":625,"meta":8,"style":8},"\u003Cscript setup>\n  import { watchEffect } from 'vue'\n\n  const { msg = 'hello' } = defineProps(['msg'])\n\n  watchEffect(() => {\n    // accessing `msg` in watchers and computed getters\n    // tracks it as a dependency, just like accessing `props.msg`\n    console.log(`msg is: ${msg}`)\n  })\n\u003C/script>\n\n\u003Ctemplate>{{ msg }}\u003C/template>\n",[2895],{"type":19,"tag":37,"props":2896,"children":2897},{"__ignoreMap":8},[2898,2917,2945,2952,3019,3026,3047,3055,3064,3109,3118,3134,3142],{"type":19,"tag":246,"props":2899,"children":2900},{"class":248,"line":249},[2901,2905,2909,2913],{"type":19,"tag":246,"props":2902,"children":2903},{"style":259},[2904],{"type":24,"value":637},{"type":19,"tag":246,"props":2906,"children":2907},{"style":253},[2908],{"type":24,"value":1598},{"type":19,"tag":246,"props":2910,"children":2911},{"style":650},[2912],{"type":24,"value":1603},{"type":19,"tag":246,"props":2914,"children":2915},{"style":259},[2916],{"type":24,"value":1631},{"type":19,"tag":246,"props":2918,"children":2919},{"class":248,"line":292},[2920,2924,2929,2933,2937,2941],{"type":19,"tag":246,"props":2921,"children":2922},{"style":253},[2923],{"type":24,"value":1639},{"type":19,"tag":246,"props":2925,"children":2926},{"style":259},[2927],{"type":24,"value":2928}," { watchEffect } ",{"type":19,"tag":246,"props":2930,"children":2931},{"style":253},[2932],{"type":24,"value":1654},{"type":19,"tag":246,"props":2934,"children":2935},{"style":660},[2936],{"type":24,"value":1659},{"type":19,"tag":246,"props":2938,"children":2939},{"style":1619},[2940],{"type":24,"value":625},{"type":19,"tag":246,"props":2942,"children":2943},{"style":660},[2944],{"type":24,"value":1669},{"type":19,"tag":246,"props":2946,"children":2947},{"class":248,"line":353},[2948],{"type":19,"tag":246,"props":2949,"children":2950},{"emptyLinePlaceholder":357},[2951],{"type":24,"value":360},{"type":19,"tag":246,"props":2953,"children":2954},{"class":248,"line":363},[2955,2960,2965,2969,2973,2978,2982,2987,2991,2996,3001,3005,3010,3014],{"type":19,"tag":246,"props":2956,"children":2957},{"style":253},[2958],{"type":24,"value":2959},"  const",{"type":19,"tag":246,"props":2961,"children":2962},{"style":259},[2963],{"type":24,"value":2964}," { msg ",{"type":19,"tag":246,"props":2966,"children":2967},{"style":253},[2968],{"type":24,"value":267},{"type":19,"tag":246,"props":2970,"children":2971},{"style":660},[2972],{"type":24,"value":1659},{"type":19,"tag":246,"props":2974,"children":2975},{"style":1619},[2976],{"type":24,"value":2977},"hello",{"type":19,"tag":246,"props":2979,"children":2980},{"style":660},[2981],{"type":24,"value":2303},{"type":19,"tag":246,"props":2983,"children":2984},{"style":259},[2985],{"type":24,"value":2986}," } ",{"type":19,"tag":246,"props":2988,"children":2989},{"style":253},[2990],{"type":24,"value":267},{"type":19,"tag":246,"props":2992,"children":2993},{"style":270},[2994],{"type":24,"value":2995}," defineProps",{"type":19,"tag":246,"props":2997,"children":2998},{"style":259},[2999],{"type":24,"value":3000},"([",{"type":19,"tag":246,"props":3002,"children":3003},{"style":660},[3004],{"type":24,"value":2303},{"type":19,"tag":246,"props":3006,"children":3007},{"style":1619},[3008],{"type":24,"value":3009},"msg",{"type":19,"tag":246,"props":3011,"children":3012},{"style":660},[3013],{"type":24,"value":2303},{"type":19,"tag":246,"props":3015,"children":3016},{"style":259},[3017],{"type":24,"value":3018},"])\n",{"type":19,"tag":246,"props":3020,"children":3021},{"class":248,"line":401},[3022],{"type":19,"tag":246,"props":3023,"children":3024},{"emptyLinePlaceholder":357},[3025],{"type":24,"value":360},{"type":19,"tag":246,"props":3027,"children":3028},{"class":248,"line":409},[3029,3034,3038,3042],{"type":19,"tag":246,"props":3030,"children":3031},{"style":270},[3032],{"type":24,"value":3033},"  watchEffect",{"type":19,"tag":246,"props":3035,"children":3036},{"style":259},[3037],{"type":24,"value":316},{"type":19,"tag":246,"props":3039,"children":3040},{"style":253},[3041],{"type":24,"value":321},{"type":19,"tag":246,"props":3043,"children":3044},{"style":259},[3045],{"type":24,"value":3046}," {\n",{"type":19,"tag":246,"props":3048,"children":3049},{"class":248,"line":2155},[3050],{"type":19,"tag":246,"props":3051,"children":3052},{"style":395},[3053],{"type":24,"value":3054},"    // accessing `msg` in watchers and computed getters\n",{"type":19,"tag":246,"props":3056,"children":3058},{"class":248,"line":3057},8,[3059],{"type":19,"tag":246,"props":3060,"children":3061},{"style":395},[3062],{"type":24,"value":3063},"    // tracks it as a dependency, just like accessing `props.msg`\n",{"type":19,"tag":246,"props":3065,"children":3067},{"class":248,"line":3066},9,[3068,3073,3077,3081,3086,3091,3095,3100,3105],{"type":19,"tag":246,"props":3069,"children":3070},{"style":259},[3071],{"type":24,"value":3072},"    console.",{"type":19,"tag":246,"props":3074,"children":3075},{"style":270},[3076],{"type":24,"value":387},{"type":19,"tag":246,"props":3078,"children":3079},{"style":259},[3080],{"type":24,"value":278},{"type":19,"tag":246,"props":3082,"children":3083},{"style":1619},[3084],{"type":24,"value":3085},"`msg is: ",{"type":19,"tag":246,"props":3087,"children":3088},{"style":253},[3089],{"type":24,"value":3090},"${",{"type":19,"tag":246,"props":3092,"children":3093},{"style":259},[3094],{"type":24,"value":3009},{"type":19,"tag":246,"props":3096,"children":3097},{"style":253},[3098],{"type":24,"value":3099},"}",{"type":19,"tag":246,"props":3101,"children":3102},{"style":1619},[3103],{"type":24,"value":3104},"`",{"type":19,"tag":246,"props":3106,"children":3107},{"style":259},[3108],{"type":24,"value":289},{"type":19,"tag":246,"props":3110,"children":3112},{"class":248,"line":3111},10,[3113],{"type":19,"tag":246,"props":3114,"children":3115},{"style":259},[3116],{"type":24,"value":3117},"  })\n",{"type":19,"tag":246,"props":3119,"children":3121},{"class":248,"line":3120},11,[3122,3126,3130],{"type":19,"tag":246,"props":3123,"children":3124},{"style":259},[3125],{"type":24,"value":1736},{"type":19,"tag":246,"props":3127,"children":3128},{"style":253},[3129],{"type":24,"value":1598},{"type":19,"tag":246,"props":3131,"children":3132},{"style":259},[3133],{"type":24,"value":1631},{"type":19,"tag":246,"props":3135,"children":3137},{"class":248,"line":3136},12,[3138],{"type":19,"tag":246,"props":3139,"children":3140},{"emptyLinePlaceholder":357},[3141],{"type":24,"value":360},{"type":19,"tag":246,"props":3143,"children":3145},{"class":248,"line":3144},13,[3146,3150,3155,3160,3165,3170,3175,3179,3183],{"type":19,"tag":246,"props":3147,"children":3148},{"style":259},[3149],{"type":24,"value":637},{"type":19,"tag":246,"props":3151,"children":3152},{"style":253},[3153],{"type":24,"value":3154},"template",{"type":19,"tag":246,"props":3156,"children":3157},{"style":259},[3158],{"type":24,"value":3159},">",{"type":19,"tag":246,"props":3161,"children":3162},{"style":253},[3163],{"type":24,"value":3164},"{{",{"type":19,"tag":246,"props":3166,"children":3167},{"style":259},[3168],{"type":24,"value":3169}," msg ",{"type":19,"tag":246,"props":3171,"children":3172},{"style":253},[3173],{"type":24,"value":3174},"}}",{"type":19,"tag":246,"props":3176,"children":3177},{"style":259},[3178],{"type":24,"value":1736},{"type":19,"tag":246,"props":3180,"children":3181},{"style":253},[3182],{"type":24,"value":3154},{"type":19,"tag":246,"props":3184,"children":3185},{"style":259},[3186],{"type":24,"value":1631},{"type":19,"tag":20,"props":3188,"children":3189},{},[3190],{"type":24,"value":3191},"This feature is experimental and requires explicit opt-in.",{"type":19,"tag":89,"props":3193,"children":3194},{},[3195],{"type":19,"tag":83,"props":3196,"children":3197},{},[3198,3199],{"type":24,"value":1757},{"type":19,"tag":51,"props":3200,"children":3203},{"href":3201,"rel":3202,"target":56},"https://github.com/vuejs/rfcs/discussions/502",[55,55],[3204],{"type":24,"value":3205},"RFC#502",{"type":19,"tag":151,"props":3207,"children":3209},{"id":3208},"definemodel",[3210],{"type":19,"tag":37,"props":3211,"children":3213},{"className":3212},[],[3214],{"type":24,"value":42},{"type":19,"tag":20,"props":3216,"children":3217},{},[3218,3220,3225,3227,3233],{"type":24,"value":3219},"Previously, for a component to support two-way binding with ",{"type":19,"tag":37,"props":3221,"children":3223},{"className":3222},[],[3224],{"type":24,"value":552},{"type":24,"value":3226},", it needs to (1) declare a prop and (2) emit a corresponding ",{"type":19,"tag":37,"props":3228,"children":3230},{"className":3229},[],[3231],{"type":24,"value":3232},"update:propName",{"type":24,"value":3234}," event when it intends to update the prop:",{"type":19,"tag":236,"props":3236,"children":3238},{"className":623,"code":3237,"language":625,"meta":8,"style":8},"\u003C!-- BEFORE -->\n\u003Cscript setup>\n  const props = defineProps(['modelValue'])\n  const emit = defineEmits(['update:modelValue'])\n  console.log(props.modelValue)\n\n  function onInput(e) {\n    emit('update:modelValue', e.target.value)\n  }\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cinput :value=\"modelValue\" @input=\"onInput\" />\n\u003C/template>\n",[3239],{"type":19,"tag":37,"props":3240,"children":3241},{"__ignoreMap":8},[3242,3250,3269,3310,3350,3367,3374,3400,3429,3437,3452,3459,3474,3542],{"type":19,"tag":246,"props":3243,"children":3244},{"class":248,"line":249},[3245],{"type":19,"tag":246,"props":3246,"children":3247},{"style":395},[3248],{"type":24,"value":3249},"\u003C!-- BEFORE -->\n",{"type":19,"tag":246,"props":3251,"children":3252},{"class":248,"line":292},[3253,3257,3261,3265],{"type":19,"tag":246,"props":3254,"children":3255},{"style":259},[3256],{"type":24,"value":637},{"type":19,"tag":246,"props":3258,"children":3259},{"style":253},[3260],{"type":24,"value":1598},{"type":19,"tag":246,"props":3262,"children":3263},{"style":650},[3264],{"type":24,"value":1603},{"type":19,"tag":246,"props":3266,"children":3267},{"style":259},[3268],{"type":24,"value":1631},{"type":19,"tag":246,"props":3270,"children":3271},{"class":248,"line":353},[3272,3276,3281,3285,3289,3293,3297,3302,3306],{"type":19,"tag":246,"props":3273,"children":3274},{"style":253},[3275],{"type":24,"value":2959},{"type":19,"tag":246,"props":3277,"children":3278},{"style":259},[3279],{"type":24,"value":3280}," props ",{"type":19,"tag":246,"props":3282,"children":3283},{"style":253},[3284],{"type":24,"value":267},{"type":19,"tag":246,"props":3286,"children":3287},{"style":270},[3288],{"type":24,"value":2995},{"type":19,"tag":246,"props":3290,"children":3291},{"style":259},[3292],{"type":24,"value":3000},{"type":19,"tag":246,"props":3294,"children":3295},{"style":660},[3296],{"type":24,"value":2303},{"type":19,"tag":246,"props":3298,"children":3299},{"style":1619},[3300],{"type":24,"value":3301},"modelValue",{"type":19,"tag":246,"props":3303,"children":3304},{"style":660},[3305],{"type":24,"value":2303},{"type":19,"tag":246,"props":3307,"children":3308},{"style":259},[3309],{"type":24,"value":3018},{"type":19,"tag":246,"props":3311,"children":3312},{"class":248,"line":363},[3313,3317,3321,3325,3329,3333,3337,3342,3346],{"type":19,"tag":246,"props":3314,"children":3315},{"style":253},[3316],{"type":24,"value":2959},{"type":19,"tag":246,"props":3318,"children":3319},{"style":259},[3320],{"type":24,"value":2259},{"type":19,"tag":246,"props":3322,"children":3323},{"style":253},[3324],{"type":24,"value":267},{"type":19,"tag":246,"props":3326,"children":3327},{"style":270},[3328],{"type":24,"value":2268},{"type":19,"tag":246,"props":3330,"children":3331},{"style":259},[3332],{"type":24,"value":3000},{"type":19,"tag":246,"props":3334,"children":3335},{"style":660},[3336],{"type":24,"value":2303},{"type":19,"tag":246,"props":3338,"children":3339},{"style":1619},[3340],{"type":24,"value":3341},"update:modelValue",{"type":19,"tag":246,"props":3343,"children":3344},{"style":660},[3345],{"type":24,"value":2303},{"type":19,"tag":246,"props":3347,"children":3348},{"style":259},[3349],{"type":24,"value":3018},{"type":19,"tag":246,"props":3351,"children":3352},{"class":248,"line":401},[3353,3358,3362],{"type":19,"tag":246,"props":3354,"children":3355},{"style":259},[3356],{"type":24,"value":3357},"  console.",{"type":19,"tag":246,"props":3359,"children":3360},{"style":270},[3361],{"type":24,"value":387},{"type":19,"tag":246,"props":3363,"children":3364},{"style":259},[3365],{"type":24,"value":3366},"(props.modelValue)\n",{"type":19,"tag":246,"props":3368,"children":3369},{"class":248,"line":409},[3370],{"type":19,"tag":246,"props":3371,"children":3372},{"emptyLinePlaceholder":357},[3373],{"type":24,"value":360},{"type":19,"tag":246,"props":3375,"children":3376},{"class":248,"line":2155},[3377,3382,3387,3391,3395],{"type":19,"tag":246,"props":3378,"children":3379},{"style":253},[3380],{"type":24,"value":3381},"  function",{"type":19,"tag":246,"props":3383,"children":3384},{"style":270},[3385],{"type":24,"value":3386}," onInput",{"type":19,"tag":246,"props":3388,"children":3389},{"style":259},[3390],{"type":24,"value":278},{"type":19,"tag":246,"props":3392,"children":3393},{"style":1699},[3394],{"type":24,"value":2285},{"type":19,"tag":246,"props":3396,"children":3397},{"style":259},[3398],{"type":24,"value":3399},") {\n",{"type":19,"tag":246,"props":3401,"children":3402},{"class":248,"line":3057},[3403,3408,3412,3416,3420,3424],{"type":19,"tag":246,"props":3404,"children":3405},{"style":270},[3406],{"type":24,"value":3407},"    emit",{"type":19,"tag":246,"props":3409,"children":3410},{"style":259},[3411],{"type":24,"value":278},{"type":19,"tag":246,"props":3413,"children":3414},{"style":660},[3415],{"type":24,"value":2303},{"type":19,"tag":246,"props":3417,"children":3418},{"style":1619},[3419],{"type":24,"value":3341},{"type":19,"tag":246,"props":3421,"children":3422},{"style":660},[3423],{"type":24,"value":2303},{"type":19,"tag":246,"props":3425,"children":3426},{"style":259},[3427],{"type":24,"value":3428},", e.target.value)\n",{"type":19,"tag":246,"props":3430,"children":3431},{"class":248,"line":3066},[3432],{"type":19,"tag":246,"props":3433,"children":3434},{"style":259},[3435],{"type":24,"value":3436},"  }\n",{"type":19,"tag":246,"props":3438,"children":3439},{"class":248,"line":3111},[3440,3444,3448],{"type":19,"tag":246,"props":3441,"children":3442},{"style":259},[3443],{"type":24,"value":1736},{"type":19,"tag":246,"props":3445,"children":3446},{"style":253},[3447],{"type":24,"value":1598},{"type":19,"tag":246,"props":3449,"children":3450},{"style":259},[3451],{"type":24,"value":1631},{"type":19,"tag":246,"props":3453,"children":3454},{"class":248,"line":3120},[3455],{"type":19,"tag":246,"props":3456,"children":3457},{"emptyLinePlaceholder":357},[3458],{"type":24,"value":360},{"type":19,"tag":246,"props":3460,"children":3461},{"class":248,"line":3136},[3462,3466,3470],{"type":19,"tag":246,"props":3463,"children":3464},{"style":259},[3465],{"type":24,"value":637},{"type":19,"tag":246,"props":3467,"children":3468},{"style":253},[3469],{"type":24,"value":3154},{"type":19,"tag":246,"props":3471,"children":3472},{"style":259},[3473],{"type":24,"value":1631},{"type":19,"tag":246,"props":3475,"children":3476},{"class":248,"line":3144},[3477,3482,3487,3491,3496,3500,3504,3508,3512,3517,3521,3525,3529,3534,3538],{"type":19,"tag":246,"props":3478,"children":3479},{"style":259},[3480],{"type":24,"value":3481},"  \u003C",{"type":19,"tag":246,"props":3483,"children":3484},{"style":253},[3485],{"type":24,"value":3486},"input",{"type":19,"tag":246,"props":3488,"children":3489},{"style":259},[3490],{"type":24,"value":647},{"type":19,"tag":246,"props":3492,"children":3493},{"style":650},[3494],{"type":24,"value":3495},"value",{"type":19,"tag":246,"props":3497,"children":3498},{"style":253},[3499],{"type":24,"value":267},{"type":19,"tag":246,"props":3501,"children":3502},{"style":660},[3503],{"type":24,"value":663},{"type":19,"tag":246,"props":3505,"children":3506},{"style":259},[3507],{"type":24,"value":3301},{"type":19,"tag":246,"props":3509,"children":3510},{"style":660},[3511],{"type":24,"value":663},{"type":19,"tag":246,"props":3513,"children":3514},{"style":259},[3515],{"type":24,"value":3516}," @",{"type":19,"tag":246,"props":3518,"children":3519},{"style":650},[3520],{"type":24,"value":3486},{"type":19,"tag":246,"props":3522,"children":3523},{"style":253},[3524],{"type":24,"value":267},{"type":19,"tag":246,"props":3526,"children":3527},{"style":660},[3528],{"type":24,"value":663},{"type":19,"tag":246,"props":3530,"children":3531},{"style":259},[3532],{"type":24,"value":3533},"onInput",{"type":19,"tag":246,"props":3535,"children":3536},{"style":660},[3537],{"type":24,"value":663},{"type":19,"tag":246,"props":3539,"children":3540},{"style":259},[3541],{"type":24,"value":726},{"type":19,"tag":246,"props":3543,"children":3545},{"class":248,"line":3544},14,[3546,3550,3554],{"type":19,"tag":246,"props":3547,"children":3548},{"style":259},[3549],{"type":24,"value":1736},{"type":19,"tag":246,"props":3551,"children":3552},{"style":253},[3553],{"type":24,"value":3154},{"type":19,"tag":246,"props":3555,"children":3556},{"style":259},[3557],{"type":24,"value":1631},{"type":19,"tag":20,"props":3559,"children":3560},{},[3561,3563,3568],{"type":24,"value":3562},"3.3 simplifies the usage with the new ",{"type":19,"tag":37,"props":3564,"children":3566},{"className":3565},[],[3567],{"type":24,"value":42},{"type":24,"value":3569}," macro. The macro automatically registers a prop, and returns a ref that can be directly mutated:",{"type":19,"tag":236,"props":3571,"children":3573},{"className":623,"code":3572,"language":625,"meta":8,"style":8},"\u003C!-- AFTER -->\n\u003Cscript setup>\n  const modelValue = defineModel()\n  console.log(modelValue.value)\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cinput v-model=\"modelValue\" />\n\u003C/template>\n",[3574],{"type":19,"tag":37,"props":3575,"children":3576},{"__ignoreMap":8},[3577,3585,3604,3630,3646,3661,3668,3683,3719],{"type":19,"tag":246,"props":3578,"children":3579},{"class":248,"line":249},[3580],{"type":19,"tag":246,"props":3581,"children":3582},{"style":395},[3583],{"type":24,"value":3584},"\u003C!-- AFTER -->\n",{"type":19,"tag":246,"props":3586,"children":3587},{"class":248,"line":292},[3588,3592,3596,3600],{"type":19,"tag":246,"props":3589,"children":3590},{"style":259},[3591],{"type":24,"value":637},{"type":19,"tag":246,"props":3593,"children":3594},{"style":253},[3595],{"type":24,"value":1598},{"type":19,"tag":246,"props":3597,"children":3598},{"style":650},[3599],{"type":24,"value":1603},{"type":19,"tag":246,"props":3601,"children":3602},{"style":259},[3603],{"type":24,"value":1631},{"type":19,"tag":246,"props":3605,"children":3606},{"class":248,"line":353},[3607,3611,3616,3620,3625],{"type":19,"tag":246,"props":3608,"children":3609},{"style":253},[3610],{"type":24,"value":2959},{"type":19,"tag":246,"props":3612,"children":3613},{"style":259},[3614],{"type":24,"value":3615}," modelValue ",{"type":19,"tag":246,"props":3617,"children":3618},{"style":253},[3619],{"type":24,"value":267},{"type":19,"tag":246,"props":3621,"children":3622},{"style":270},[3623],{"type":24,"value":3624}," defineModel",{"type":19,"tag":246,"props":3626,"children":3627},{"style":259},[3628],{"type":24,"value":3629},"()\n",{"type":19,"tag":246,"props":3631,"children":3632},{"class":248,"line":363},[3633,3637,3641],{"type":19,"tag":246,"props":3634,"children":3635},{"style":259},[3636],{"type":24,"value":3357},{"type":19,"tag":246,"props":3638,"children":3639},{"style":270},[3640],{"type":24,"value":387},{"type":19,"tag":246,"props":3642,"children":3643},{"style":259},[3644],{"type":24,"value":3645},"(modelValue.value)\n",{"type":19,"tag":246,"props":3647,"children":3648},{"class":248,"line":401},[3649,3653,3657],{"type":19,"tag":246,"props":3650,"children":3651},{"style":259},[3652],{"type":24,"value":1736},{"type":19,"tag":246,"props":3654,"children":3655},{"style":253},[3656],{"type":24,"value":1598},{"type":19,"tag":246,"props":3658,"children":3659},{"style":259},[3660],{"type":24,"value":1631},{"type":19,"tag":246,"props":3662,"children":3663},{"class":248,"line":409},[3664],{"type":19,"tag":246,"props":3665,"children":3666},{"emptyLinePlaceholder":357},[3667],{"type":24,"value":360},{"type":19,"tag":246,"props":3669,"children":3670},{"class":248,"line":2155},[3671,3675,3679],{"type":19,"tag":246,"props":3672,"children":3673},{"style":259},[3674],{"type":24,"value":637},{"type":19,"tag":246,"props":3676,"children":3677},{"style":253},[3678],{"type":24,"value":3154},{"type":19,"tag":246,"props":3680,"children":3681},{"style":259},[3682],{"type":24,"value":1631},{"type":19,"tag":246,"props":3684,"children":3685},{"class":248,"line":3057},[3686,3690,3694,3699,3703,3707,3711,3715],{"type":19,"tag":246,"props":3687,"children":3688},{"style":259},[3689],{"type":24,"value":3481},{"type":19,"tag":246,"props":3691,"children":3692},{"style":253},[3693],{"type":24,"value":3486},{"type":19,"tag":246,"props":3695,"children":3696},{"style":650},[3697],{"type":24,"value":3698}," v-model",{"type":19,"tag":246,"props":3700,"children":3701},{"style":253},[3702],{"type":24,"value":267},{"type":19,"tag":246,"props":3704,"children":3705},{"style":660},[3706],{"type":24,"value":663},{"type":19,"tag":246,"props":3708,"children":3709},{"style":259},[3710],{"type":24,"value":3301},{"type":19,"tag":246,"props":3712,"children":3713},{"style":660},[3714],{"type":24,"value":663},{"type":19,"tag":246,"props":3716,"children":3717},{"style":259},[3718],{"type":24,"value":726},{"type":19,"tag":246,"props":3720,"children":3721},{"class":248,"line":3066},[3722,3726,3730],{"type":19,"tag":246,"props":3723,"children":3724},{"style":259},[3725],{"type":24,"value":1736},{"type":19,"tag":246,"props":3727,"children":3728},{"style":253},[3729],{"type":24,"value":3154},{"type":19,"tag":246,"props":3731,"children":3732},{"style":259},[3733],{"type":24,"value":1631},{"type":19,"tag":20,"props":3735,"children":3736},{},[3737],{"type":24,"value":3191},{"type":19,"tag":89,"props":3739,"children":3740},{},[3741],{"type":19,"tag":83,"props":3742,"children":3743},{},[3744,3745],{"type":24,"value":1757},{"type":19,"tag":51,"props":3746,"children":3748},{"href":524,"rel":3747,"target":56},[55,55],[3749],{"type":24,"value":528},{"type":19,"tag":72,"props":3751,"children":3753},{"id":3752},"other-notable-features",[3754],{"type":24,"value":3755},"Other Notable Features",{"type":19,"tag":151,"props":3757,"children":3759},{"id":3758},"defineoptions",[3760],{"type":19,"tag":37,"props":3761,"children":3763},{"className":3762},[],[3764],{"type":24,"value":3765},"defineOptions",{"type":19,"tag":20,"props":3767,"children":3768},{},[3769,3770,3775,3777,3782,3784,3790],{"type":24,"value":2587},{"type":19,"tag":37,"props":3771,"children":3773},{"className":3772},[],[3774],{"type":24,"value":3765},{"type":24,"value":3776}," macro allows declaring component options directly in ",{"type":19,"tag":37,"props":3778,"children":3780},{"className":3779},[],[3781],{"type":24,"value":544},{"type":24,"value":3783},", without requiring a separate ",{"type":19,"tag":37,"props":3785,"children":3787},{"className":3786},[],[3788],{"type":24,"value":3789},"\u003Cscript>",{"type":24,"value":3791}," block:",{"type":19,"tag":236,"props":3793,"children":3795},{"className":623,"code":3794,"language":625,"meta":8,"style":8},"\u003Cscript setup>\n  defineOptions({ inheritAttrs: false })\n\u003C/script>\n",[3796],{"type":19,"tag":37,"props":3797,"children":3798},{"__ignoreMap":8},[3799,3818,3845],{"type":19,"tag":246,"props":3800,"children":3801},{"class":248,"line":249},[3802,3806,3810,3814],{"type":19,"tag":246,"props":3803,"children":3804},{"style":259},[3805],{"type":24,"value":637},{"type":19,"tag":246,"props":3807,"children":3808},{"style":253},[3809],{"type":24,"value":1598},{"type":19,"tag":246,"props":3811,"children":3812},{"style":650},[3813],{"type":24,"value":1603},{"type":19,"tag":246,"props":3815,"children":3816},{"style":259},[3817],{"type":24,"value":1631},{"type":19,"tag":246,"props":3819,"children":3820},{"class":248,"line":292},[3821,3826,3831,3835,3840],{"type":19,"tag":246,"props":3822,"children":3823},{"style":270},[3824],{"type":24,"value":3825},"  defineOptions",{"type":19,"tag":246,"props":3827,"children":3828},{"style":259},[3829],{"type":24,"value":3830},"({ inheritAttrs",{"type":19,"tag":246,"props":3832,"children":3833},{"style":253},[3834],{"type":24,"value":1883},{"type":19,"tag":246,"props":3836,"children":3837},{"style":281},[3838],{"type":24,"value":3839}," false",{"type":19,"tag":246,"props":3841,"children":3842},{"style":259},[3843],{"type":24,"value":3844}," })\n",{"type":19,"tag":246,"props":3846,"children":3847},{"class":248,"line":353},[3848,3852,3856],{"type":19,"tag":246,"props":3849,"children":3850},{"style":259},[3851],{"type":24,"value":1736},{"type":19,"tag":246,"props":3853,"children":3854},{"style":253},[3855],{"type":24,"value":1598},{"type":19,"tag":246,"props":3857,"children":3858},{"style":259},[3859],{"type":24,"value":1631},{"type":19,"tag":151,"props":3861,"children":3863},{"id":3862},"better-getter-support-with-toref-and-tovalue",[3864,3866,3872,3873],{"type":24,"value":3865},"Better Getter Support with ",{"type":19,"tag":37,"props":3867,"children":3869},{"className":3868},[],[3870],{"type":24,"value":3871},"toRef",{"type":24,"value":1384},{"type":19,"tag":37,"props":3874,"children":3876},{"className":3875},[],[3877],{"type":24,"value":3878},"toValue",{"type":19,"tag":20,"props":3880,"children":3881},{},[3882,3887],{"type":19,"tag":37,"props":3883,"children":3885},{"className":3884},[],[3886],{"type":24,"value":3871},{"type":24,"value":3888}," has been enhanced to support normalizing values / getters / existing refs into refs:",{"type":19,"tag":236,"props":3890,"children":3892},{"className":238,"code":3891,"language":240,"meta":8,"style":8},"// equivalent to ref(1)\ntoRef(1)\n// creates a readonly ref that calls the getter on .value access\ntoRef(() => props.foo)\n// returns existing refs as-is\ntoRef(existingRef)\n",[3893],{"type":19,"tag":37,"props":3894,"children":3895},{"__ignoreMap":8},[3896,3904,3924,3932,3952,3960],{"type":19,"tag":246,"props":3897,"children":3898},{"class":248,"line":249},[3899],{"type":19,"tag":246,"props":3900,"children":3901},{"style":395},[3902],{"type":24,"value":3903},"// equivalent to ref(1)\n",{"type":19,"tag":246,"props":3905,"children":3906},{"class":248,"line":292},[3907,3911,3915,3920],{"type":19,"tag":246,"props":3908,"children":3909},{"style":270},[3910],{"type":24,"value":3871},{"type":19,"tag":246,"props":3912,"children":3913},{"style":259},[3914],{"type":24,"value":278},{"type":19,"tag":246,"props":3916,"children":3917},{"style":281},[3918],{"type":24,"value":3919},"1",{"type":19,"tag":246,"props":3921,"children":3922},{"style":259},[3923],{"type":24,"value":289},{"type":19,"tag":246,"props":3925,"children":3926},{"class":248,"line":353},[3927],{"type":19,"tag":246,"props":3928,"children":3929},{"style":395},[3930],{"type":24,"value":3931},"// creates a readonly ref that calls the getter on .value access\n",{"type":19,"tag":246,"props":3933,"children":3934},{"class":248,"line":363},[3935,3939,3943,3947],{"type":19,"tag":246,"props":3936,"children":3937},{"style":270},[3938],{"type":24,"value":3871},{"type":19,"tag":246,"props":3940,"children":3941},{"style":259},[3942],{"type":24,"value":316},{"type":19,"tag":246,"props":3944,"children":3945},{"style":253},[3946],{"type":24,"value":321},{"type":19,"tag":246,"props":3948,"children":3949},{"style":259},[3950],{"type":24,"value":3951}," props.foo)\n",{"type":19,"tag":246,"props":3953,"children":3954},{"class":248,"line":401},[3955],{"type":19,"tag":246,"props":3956,"children":3957},{"style":395},[3958],{"type":24,"value":3959},"// returns existing refs as-is\n",{"type":19,"tag":246,"props":3961,"children":3962},{"class":248,"line":409},[3963,3967],{"type":19,"tag":246,"props":3964,"children":3965},{"style":270},[3966],{"type":24,"value":3871},{"type":19,"tag":246,"props":3968,"children":3969},{"style":259},[3970],{"type":24,"value":3971},"(existingRef)\n",{"type":19,"tag":20,"props":3973,"children":3974},{},[3975,3977,3982,3984,3990],{"type":24,"value":3976},"Calling ",{"type":19,"tag":37,"props":3978,"children":3980},{"className":3979},[],[3981],{"type":24,"value":3871},{"type":24,"value":3983}," with a getter is similar to ",{"type":19,"tag":37,"props":3985,"children":3987},{"className":3986},[],[3988],{"type":24,"value":3989},"computed",{"type":24,"value":3991},", but can be more efficient when the getter is just performing property access with no expensive computations.",{"type":19,"tag":20,"props":3993,"children":3994},{},[3995,3996,4001],{"type":24,"value":2587},{"type":19,"tag":37,"props":3997,"children":3999},{"className":3998},[],[4000],{"type":24,"value":3878},{"type":24,"value":4002}," utility method provides the opposite, normalizing values / getters / refs into values:",{"type":19,"tag":236,"props":4004,"children":4006},{"className":238,"code":4005,"language":240,"meta":8,"style":8},"toValue(1) //       --> 1\ntoValue(ref(1)) //  --> 1\ntoValue(() => 1) // --> 1\n",[4007],{"type":19,"tag":37,"props":4008,"children":4009},{"__ignoreMap":8},[4010,4035,4069],{"type":19,"tag":246,"props":4011,"children":4012},{"class":248,"line":249},[4013,4017,4021,4025,4030],{"type":19,"tag":246,"props":4014,"children":4015},{"style":270},[4016],{"type":24,"value":3878},{"type":19,"tag":246,"props":4018,"children":4019},{"style":259},[4020],{"type":24,"value":278},{"type":19,"tag":246,"props":4022,"children":4023},{"style":281},[4024],{"type":24,"value":3919},{"type":19,"tag":246,"props":4026,"children":4027},{"style":259},[4028],{"type":24,"value":4029},") ",{"type":19,"tag":246,"props":4031,"children":4032},{"style":395},[4033],{"type":24,"value":4034},"//       --> 1\n",{"type":19,"tag":246,"props":4036,"children":4037},{"class":248,"line":292},[4038,4042,4046,4051,4055,4059,4064],{"type":19,"tag":246,"props":4039,"children":4040},{"style":270},[4041],{"type":24,"value":3878},{"type":19,"tag":246,"props":4043,"children":4044},{"style":259},[4045],{"type":24,"value":278},{"type":19,"tag":246,"props":4047,"children":4048},{"style":270},[4049],{"type":24,"value":4050},"ref",{"type":19,"tag":246,"props":4052,"children":4053},{"style":259},[4054],{"type":24,"value":278},{"type":19,"tag":246,"props":4056,"children":4057},{"style":281},[4058],{"type":24,"value":3919},{"type":19,"tag":246,"props":4060,"children":4061},{"style":259},[4062],{"type":24,"value":4063},")) ",{"type":19,"tag":246,"props":4065,"children":4066},{"style":395},[4067],{"type":24,"value":4068},"//  --> 1\n",{"type":19,"tag":246,"props":4070,"children":4071},{"class":248,"line":353},[4072,4076,4080,4084,4089,4093],{"type":19,"tag":246,"props":4073,"children":4074},{"style":270},[4075],{"type":24,"value":3878},{"type":19,"tag":246,"props":4077,"children":4078},{"style":259},[4079],{"type":24,"value":316},{"type":19,"tag":246,"props":4081,"children":4082},{"style":253},[4083],{"type":24,"value":321},{"type":19,"tag":246,"props":4085,"children":4086},{"style":281},[4087],{"type":24,"value":4088}," 1",{"type":19,"tag":246,"props":4090,"children":4091},{"style":259},[4092],{"type":24,"value":4029},{"type":19,"tag":246,"props":4094,"children":4095},{"style":395},[4096],{"type":24,"value":4097},"// --> 1\n",{"type":19,"tag":20,"props":4099,"children":4100},{},[4101,4106,4108,4114],{"type":19,"tag":37,"props":4102,"children":4104},{"className":4103},[],[4105],{"type":24,"value":3878},{"type":24,"value":4107}," can be used in composables in place of ",{"type":19,"tag":37,"props":4109,"children":4111},{"className":4110},[],[4112],{"type":24,"value":4113},"unref",{"type":24,"value":4115}," so that your composable can accept getters as reactive data sources:",{"type":19,"tag":236,"props":4117,"children":4119},{"className":238,"code":4118,"language":240,"meta":8,"style":8},"// before: allocating unnecessary intermediate refs\nuseFeature(computed(() => props.foo))\nuseFeature(toRef(props, 'foo'))\n\n// after: more efficient and succinct\nuseFeature(() => props.foo)\n",[4120],{"type":19,"tag":37,"props":4121,"children":4122},{"__ignoreMap":8},[4123,4131,4160,4197,4204,4212],{"type":19,"tag":246,"props":4124,"children":4125},{"class":248,"line":249},[4126],{"type":19,"tag":246,"props":4127,"children":4128},{"style":395},[4129],{"type":24,"value":4130},"// before: allocating unnecessary intermediate refs\n",{"type":19,"tag":246,"props":4132,"children":4133},{"class":248,"line":292},[4134,4139,4143,4147,4151,4155],{"type":19,"tag":246,"props":4135,"children":4136},{"style":270},[4137],{"type":24,"value":4138},"useFeature",{"type":19,"tag":246,"props":4140,"children":4141},{"style":259},[4142],{"type":24,"value":278},{"type":19,"tag":246,"props":4144,"children":4145},{"style":270},[4146],{"type":24,"value":3989},{"type":19,"tag":246,"props":4148,"children":4149},{"style":259},[4150],{"type":24,"value":316},{"type":19,"tag":246,"props":4152,"children":4153},{"style":253},[4154],{"type":24,"value":321},{"type":19,"tag":246,"props":4156,"children":4157},{"style":259},[4158],{"type":24,"value":4159}," props.foo))\n",{"type":19,"tag":246,"props":4161,"children":4162},{"class":248,"line":353},[4163,4167,4171,4175,4180,4184,4188,4192],{"type":19,"tag":246,"props":4164,"children":4165},{"style":270},[4166],{"type":24,"value":4138},{"type":19,"tag":246,"props":4168,"children":4169},{"style":259},[4170],{"type":24,"value":278},{"type":19,"tag":246,"props":4172,"children":4173},{"style":270},[4174],{"type":24,"value":3871},{"type":19,"tag":246,"props":4176,"children":4177},{"style":259},[4178],{"type":24,"value":4179},"(props, ",{"type":19,"tag":246,"props":4181,"children":4182},{"style":660},[4183],{"type":24,"value":2303},{"type":19,"tag":246,"props":4185,"children":4186},{"style":1619},[4187],{"type":24,"value":2298},{"type":19,"tag":246,"props":4189,"children":4190},{"style":660},[4191],{"type":24,"value":2303},{"type":19,"tag":246,"props":4193,"children":4194},{"style":259},[4195],{"type":24,"value":4196},"))\n",{"type":19,"tag":246,"props":4198,"children":4199},{"class":248,"line":363},[4200],{"type":19,"tag":246,"props":4201,"children":4202},{"emptyLinePlaceholder":357},[4203],{"type":24,"value":360},{"type":19,"tag":246,"props":4205,"children":4206},{"class":248,"line":401},[4207],{"type":19,"tag":246,"props":4208,"children":4209},{"style":395},[4210],{"type":24,"value":4211},"// after: more efficient and succinct\n",{"type":19,"tag":246,"props":4213,"children":4214},{"class":248,"line":409},[4215,4219,4223,4227],{"type":19,"tag":246,"props":4216,"children":4217},{"style":270},[4218],{"type":24,"value":4138},{"type":19,"tag":246,"props":4220,"children":4221},{"style":259},[4222],{"type":24,"value":316},{"type":19,"tag":246,"props":4224,"children":4225},{"style":253},[4226],{"type":24,"value":321},{"type":19,"tag":246,"props":4228,"children":4229},{"style":259},[4230],{"type":24,"value":3951},{"type":19,"tag":20,"props":4232,"children":4233},{},[4234,4236,4241,4242,4247,4249,4254,4255,4260],{"type":24,"value":4235},"The relationship between ",{"type":19,"tag":37,"props":4237,"children":4239},{"className":4238},[],[4240],{"type":24,"value":3871},{"type":24,"value":1384},{"type":19,"tag":37,"props":4243,"children":4245},{"className":4244},[],[4246],{"type":24,"value":3878},{"type":24,"value":4248}," is similar to that between ",{"type":19,"tag":37,"props":4250,"children":4252},{"className":4251},[],[4253],{"type":24,"value":4050},{"type":24,"value":1384},{"type":19,"tag":37,"props":4256,"children":4258},{"className":4257},[],[4259],{"type":24,"value":4113},{"type":24,"value":4261},", with the main difference being the special handling of getter functions.",{"type":19,"tag":89,"props":4263,"children":4264},{},[4265],{"type":19,"tag":83,"props":4266,"children":4267},{},[4268,4269],{"type":24,"value":1757},{"type":19,"tag":51,"props":4270,"children":4273},{"href":4271,"rel":4272,"target":56},"https://github.com/vuejs/core/pull/7997",[55,55],[4274],{"type":24,"value":4275},"PR#7997",{"type":19,"tag":151,"props":4277,"children":4279},{"id":4278},"jsx-import-source-support",[4280],{"type":24,"value":4281},"JSX Import Source Support",{"type":19,"tag":20,"props":4283,"children":4284},{},[4285],{"type":24,"value":4286},"Currently, Vue's types automatically registers global JSX typing. This may cause conflict with used together with other libraries that needs JSX type inference, in particular React.",{"type":19,"tag":20,"props":4288,"children":4289},{},[4290,4292,4297],{"type":24,"value":4291},"Starting in 3.3, Vue supports specifying JSX namespace via TypeScript's ",{"type":19,"tag":51,"props":4293,"children":4295},{"href":930,"rel":4294,"target":56},[55,55],[4296],{"type":24,"value":934},{"type":24,"value":4298}," option. This allows the users to choose global or per-file opt-in based on their use case.",{"type":19,"tag":20,"props":4300,"children":4301},{},[4302,4304,4309,4311,4316,4318,4323],{"type":24,"value":4303},"For backwards compatibility, 3.3 still registers JSX namespace globally. ",{"type":19,"tag":98,"props":4305,"children":4306},{},[4307],{"type":24,"value":4308},"We plan to remove the default global registration in 3.4.",{"type":24,"value":4310}," If you are using TSX with Vue, you should add explicit ",{"type":19,"tag":37,"props":4312,"children":4314},{"className":4313},[],[4315],{"type":24,"value":934},{"type":24,"value":4317}," to your ",{"type":19,"tag":37,"props":4319,"children":4321},{"className":4320},[],[4322],{"type":24,"value":950},{"type":24,"value":4324}," after upgrading to 3.3 to avoid breakage in 3.4.",{"type":19,"tag":72,"props":4326,"children":4328},{"id":4327},"maintenance-infrastructure-improvements",[4329],{"type":24,"value":4330},"Maintenance Infrastructure Improvements",{"type":19,"tag":20,"props":4332,"children":4333},{},[4334],{"type":24,"value":4335},"This release builds upon many maintenance infrastructure improvements that allow us to move faster with more confidence:",{"type":19,"tag":89,"props":4337,"children":4338},{},[4339,4358,4371,4390],{"type":19,"tag":83,"props":4340,"children":4341},{},[4342,4344,4350,4351,4357],{"type":24,"value":4343},"10x faster builds by separating type checking from the rollup build and moving from ",{"type":19,"tag":37,"props":4345,"children":4347},{"className":4346},[],[4348],{"type":24,"value":4349},"rollup-plugin-typescript2",{"type":24,"value":936},{"type":19,"tag":37,"props":4352,"children":4354},{"className":4353},[],[4355],{"type":24,"value":4356},"rollup-plugin-esbuild",{"type":24,"value":61},{"type":19,"tag":83,"props":4359,"children":4360},{},[4361,4363,4370],{"type":24,"value":4362},"Faster tests by moving from Jest to ",{"type":19,"tag":51,"props":4364,"children":4367},{"href":4365,"rel":4366,"target":56},"https://vitest.dev",[55,55],[4368],{"type":24,"value":4369},"Vitest",{"type":24,"value":61},{"type":19,"tag":83,"props":4372,"children":4373},{},[4374,4376,4382,4383,4389],{"type":24,"value":4375},"Faster types generation by moving from ",{"type":19,"tag":37,"props":4377,"children":4379},{"className":4378},[],[4380],{"type":24,"value":4381},"@microsoft/api-extractor",{"type":24,"value":936},{"type":19,"tag":37,"props":4384,"children":4386},{"className":4385},[],[4387],{"type":24,"value":4388},"rollup-plugin-dts",{"type":24,"value":61},{"type":19,"tag":83,"props":4391,"children":4392},{},[4393,4395,4400],{"type":24,"value":4394},"Comprehensive regression tests via ",{"type":19,"tag":51,"props":4396,"children":4398},{"href":188,"rel":4397,"target":56},[55,55],[4399],{"type":24,"value":192},{"type":24,"value":4401}," - catches regressions in major ecosystem dependents before releases!",{"type":19,"tag":20,"props":4403,"children":4404},{},[4405],{"type":24,"value":4406},"As planned, we aim to start making smaller and more frequent feature releases in 2023. Stay tuned!",{"type":19,"tag":1103,"props":4408,"children":4409},{},[4410],{"type":24,"value":1107},{"title":8,"searchDepth":292,"depth":292,"links":4412},[4413,4422,4426,4432],{"id":1540,"depth":292,"text":4414,"children":4415},"\u003Cscript setup> + TypeScript DX Improvements",[4416,4417,4418,4420],{"id":1551,"depth":353,"text":1554},{"id":1767,"depth":353,"text":1770},{"id":2211,"depth":353,"text":4419},"More Ergonomic defineEmits",{"id":2573,"depth":353,"text":4421},"Typed Slots with defineSlots",{"id":2871,"depth":292,"text":2874,"children":4423},[4424,4425],{"id":2877,"depth":353,"text":2880},{"id":3208,"depth":353,"text":42},{"id":3752,"depth":292,"text":3755,"children":4427},[4428,4429,4431],{"id":3758,"depth":353,"text":3765},{"id":3862,"depth":353,"text":4430},"Better Getter Support with toRef and toValue",{"id":4278,"depth":353,"text":4281},{"id":4327,"depth":292,"text":4330},"content:blog:vue-3-3.md","blog/vue-3-3.md","blog/vue-3-3",{"loc":1438},{"_path":4438,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":4439,"description":4440,"date":4441,"author":4442,"avatar":4443,"twitter":4444,"excerpt":4445,"body":4451,"_type":1125,"_id":5025,"_source":1127,"_file":5026,"_stem":5027,"_extension":1130,"sitemap":5028},"/blog/volar-a-new-beginning","Volar: a New Beginning","Most users of Volar know it as the official Vue.js VSCode extension. It started as a personal project when the official recommendation was still Vetur, and over time got adopted as the new official extension due to improved architecture and performance.","2023-02-08","Johnson Chu","https://avatars.githubusercontent.com/u/16279759?v=4","@johnsoncodehk",{"type":16,"children":4446},[4447],{"type":19,"tag":20,"props":4448,"children":4449},{},[4450],{"type":24,"value":4440},{"type":16,"children":4452,"toc":5012},[4453,4457,4471,4476,4479,4485,4490,4508,4521,4526,4531,4536,4542,4567,4588,4594,4608,4630,4650,4755,4760,4775,4780,4786,4791,4797,4810,4816,4821,4826,4831,4836,4842,4856,4861,4866,4872,4877,4882,4887,4892,4898,4903,4908,4913,4933,4938,4944,4956,4961,4964,4986,4998],{"type":19,"tag":20,"props":4454,"children":4455},{},[4456],{"type":24,"value":4440},{"type":19,"tag":20,"props":4458,"children":4459},{},[4460,4462,4469],{"type":24,"value":4461},"As a project created to improve the quality of life for developers, we spent over two years before ",{"type":19,"tag":51,"props":4463,"children":4466},{"href":4464,"rel":4465,"target":56},"https://blog.vuejs.org/posts/volar-1.0.html",[55,55],[4467],{"type":24,"value":4468},"reaching 1.0",{"type":24,"value":4470},", and have been continuously shipping stability improvements.",{"type":19,"tag":20,"props":4472,"children":4473},{},[4474],{"type":24,"value":4475},"But we've still got more work to do, and there are exciting plans for 2023.",{"type":19,"tag":63,"props":4477,"children":4478},{},[],{"type":19,"tag":72,"props":4480,"children":4482},{"id":4481},"volarjs-the-embedded-language-tooling-framework",[4483],{"type":24,"value":4484},"Volar.js: the Embedded Language Tooling Framework",{"type":19,"tag":20,"props":4486,"children":4487},{},[4488],{"type":24,"value":4489},"Although initially designed for the specific needs of Vue Single-File Components, Volar's codebase contains many parts that are not specific to Vue, such as:",{"type":19,"tag":89,"props":4491,"children":4492},{},[4493,4498,4503],{"type":19,"tag":83,"props":4494,"children":4495},{},[4496],{"type":24,"value":4497},"Processing of embedded programming languages (a common problem for multiple meta frameworks)",{"type":19,"tag":83,"props":4499,"children":4500},{},[4501],{"type":24,"value":4502},"The Vue Language Server is actually a fully-fledged TypeScript Language Server",{"type":19,"tag":83,"props":4504,"children":4505},{},[4506],{"type":24,"value":4507},"Code for handling interaction with LSP / Web / Embedded Language Services, and more",{"type":19,"tag":20,"props":4509,"children":4510},{},[4511,4513,4520],{"type":24,"value":4512},"We have now extracted these common parts out into a framework-agnostic set of tools. These tools are now maintained as a new, separate project: ",{"type":19,"tag":51,"props":4514,"children":4517},{"href":4515,"rel":4516,"target":56},"https://volarjs.github.io/",[55,55],[4518],{"type":24,"value":4519},"Volar.js",{"type":24,"value":61},{"type":19,"tag":20,"props":4522,"children":4523},{},[4524],{"type":24,"value":4525},"Volar.js is architected to support any file format that involves embedded languages - not just Vue, but also Astro, Svelte, or even Angular. It is also capable of implementing regular single-language LSP servers such as TypeScript, CSS, and HTML.",{"type":19,"tag":20,"props":4527,"children":4528},{},[4529],{"type":24,"value":4530},"Another major focus of Volar.js is performance. It aims to minimize the overhead to achieve the performance of a native embedded language service. There are many issues and optimization opportunities that could only be discovered over time with a sizable user base, and Volar.js is optimized based on the learnings we have accumulated from millions of downloads.",{"type":19,"tag":20,"props":4532,"children":4533},{},[4534],{"type":24,"value":4535},"As an example, ByteDance's Lynx team, an early adopter of Volar.js, shipped a whole set of language tools supporting their in-house framework with two weeks of work from a single developer. That would have taken months if it were built from scratch even with a team.",{"type":19,"tag":72,"props":4537,"children":4539},{"id":4538},"the-old-volar-is-now-vuejslanguage-tools",[4540],{"type":24,"value":4541},"The old Volar is now vuejs/language-tools",{"type":19,"tag":20,"props":4543,"children":4544},{},[4545,4547,4552,4554,4565],{"type":24,"value":4546},"With the core extracted, the codebase for the original Volar extension and ",{"type":19,"tag":37,"props":4548,"children":4550},{"className":4549},[],[4551],{"type":24,"value":2853},{"type":24,"value":4553}," has been moved to the ",{"type":19,"tag":51,"props":4555,"children":4558},{"href":4556,"rel":4557,"target":56},"https://github.com/vuejs/language-tools",[55,55],[4559],{"type":19,"tag":37,"props":4560,"children":4562},{"className":4561},[],[4563],{"type":24,"value":4564},"vuejs/language-tools",{"type":24,"value":4566}," repo. This repo now depends on Volar.js and contains code for Vue-specific support.",{"type":19,"tag":20,"props":4568,"children":4569},{},[4570,4572,4578,4580,4586],{"type":24,"value":4571},"We will also move some npm packages from the ",{"type":19,"tag":37,"props":4573,"children":4575},{"className":4574},[],[4576],{"type":24,"value":4577},"@volar",{"type":24,"value":4579}," npm organization to ",{"type":19,"tag":37,"props":4581,"children":4583},{"className":4582},[],[4584],{"type":24,"value":4585},"@vue",{"type":24,"value":4587}," - but these changes should not affect end users.",{"type":19,"tag":72,"props":4589,"children":4591},{"id":4590},"team-and-organization",[4592],{"type":24,"value":4593},"Team and Organization",{"type":19,"tag":20,"props":4595,"children":4596},{},[4597,4599,4606],{"type":24,"value":4598},"Similar to how ",{"type":19,"tag":51,"props":4600,"children":4603},{"href":4601,"rel":4602,"target":56},"https://vitejs.dev/",[55,55],[4604],{"type":24,"value":4605},"Vite",{"type":24,"value":4607}," was born out of the Vue ecosystem and eventually grew into its own community that connects users from the entire web dev ecosystem, Volar.js hopes to follow the same path.",{"type":19,"tag":20,"props":4609,"children":4610},{},[4611,4613,4619,4621,4628],{"type":24,"value":4612},"I (",{"type":19,"tag":51,"props":4614,"children":4617},{"href":4615,"rel":4616,"target":56},"https://github.com/johnsoncodehk",[55,55],[4618],{"type":24,"value":4444},{"type":24,"value":4620},") have established the Volar.js Core Team with Erika (",{"type":19,"tag":51,"props":4622,"children":4625},{"href":4623,"rel":4624,"target":56},"https://elk.zone/mastodon.gamedevalliance.fr/@erika",[55,55],[4626],{"type":24,"value":4627},"@erika",{"type":24,"value":4629},"), an Astro core team member. Erika shares my vision and dedication towards improving people's development experience. We will work together to improve the DX for all web devs, not just Vue and Astro.",{"type":19,"tag":20,"props":4631,"children":4632},{},[4633,4635,4648],{"type":24,"value":4634},"We have created the ",{"type":19,"tag":51,"props":4636,"children":4639},{"href":4637,"rel":4638,"target":56},"https://github.com/volarjs",[55,55],[4640,4646],{"type":19,"tag":37,"props":4641,"children":4643},{"className":4642},[],[4644],{"type":24,"value":4645},"volarjs",{"type":24,"value":4647}," organization",{"type":24,"value":4649}," to maintain the framework and related repos.",{"type":19,"tag":89,"props":4651,"children":4652},{},[4653,4665,4685,4696,4708,4719,4731,4743],{"type":19,"tag":83,"props":4654,"children":4655},{},[4656,4663],{"type":19,"tag":51,"props":4657,"children":4660},{"href":4658,"rel":4659,"target":56},"https://github.com/volarjs/volar.js",[55,55],[4661],{"type":24,"value":4662},"volar.js",{"type":24,"value":4664},": Core of the framework",{"type":19,"tag":83,"props":4666,"children":4667},{},[4668,4675,4677,4683],{"type":19,"tag":51,"props":4669,"children":4672},{"href":4670,"rel":4671,"target":56},"https://github.com/volarjs/plugins",[55,55],[4673],{"type":24,"value":4674},"plugins",{"type":24,"value":4676},": Can be used in ",{"type":19,"tag":37,"props":4678,"children":4680},{"className":4679},[],[4681],{"type":24,"value":4682},"volar.config.js",{"type":24,"value":4684}," or plugins of the framework",{"type":19,"tag":83,"props":4686,"children":4687},{},[4688,4694],{"type":19,"tag":51,"props":4689,"children":4691},{"href":4515,"rel":4690,"target":56},[55,55],[4692],{"type":24,"value":4693},"volarjs.github.io",{"type":24,"value":4695},": Official website",{"type":19,"tag":83,"props":4697,"children":4698},{},[4699,4706],{"type":19,"tag":51,"props":4700,"children":4703},{"href":4701,"rel":4702,"target":56},"https://github.com/volarjs/language-tools-starter",[55,55],[4704],{"type":24,"value":4705},"language-tools-starter",{"type":24,"value":4707},": Template for starting building a language server with Volar.js",{"type":19,"tag":83,"props":4709,"children":4710},{},[4711,4717],{"type":19,"tag":51,"props":4712,"children":4715},{"href":4713,"rel":4714,"target":56},"https://github.com/volarjs/ecosystem-ci",[55,55],[4716],{"type":24,"value":192},{"type":24,"value":4718},": Used to run integration tests for volar ecosystem projects",{"type":19,"tag":83,"props":4720,"children":4721},{},[4722,4729],{"type":19,"tag":51,"props":4723,"children":4726},{"href":4724,"rel":4725,"target":56},"https://github.com/volarjs/pug-language-tools",[55,55],[4727],{"type":24,"value":4728},"pug-language-tools",{"type":24,"value":4730},": Pug tools based on language-tools-starter",{"type":19,"tag":83,"props":4732,"children":4733},{},[4734,4741],{"type":19,"tag":51,"props":4735,"children":4738},{"href":4736,"rel":4737,"target":56},"https://github.com/volarjs/angular-language-tools",[55,55],[4739],{"type":24,"value":4740},"angular-language-tools",{"type":24,"value":4742},": Angular example based on language-tools-starter",{"type":19,"tag":83,"props":4744,"children":4745},{},[4746,4753],{"type":19,"tag":51,"props":4747,"children":4750},{"href":4748,"rel":4749,"target":56},"https://github.com/volarjs/svelte-language-tools",[55,55],[4751],{"type":24,"value":4752},"svelte-language-tools",{"type":24,"value":4754},": Svelte example based on language-tools-starter",{"type":19,"tag":20,"props":4756,"children":4757},{},[4758],{"type":24,"value":4759},"In addition, I'm thrilled to announce that:",{"type":19,"tag":20,"props":4761,"children":4762},{},[4763],{"type":19,"tag":98,"props":4764,"children":4765},{},[4766,4773],{"type":19,"tag":51,"props":4767,"children":4770},{"href":4768,"rel":4769,"target":56},"https://stackblitz.com/",[55,55],[4771],{"type":24,"value":4772},"StackBlitz",{"type":24,"value":4774}," will be supporting me full time to work on Volar.js!",{"type":19,"tag":20,"props":4776,"children":4777},{},[4778],{"type":24,"value":4779},"We are excited about the future and can't wait to see what we can achieve in the coming months!",{"type":19,"tag":72,"props":4781,"children":4783},{"id":4782},"next-steps",[4784],{"type":24,"value":4785},"Next Steps",{"type":19,"tag":20,"props":4787,"children":4788},{},[4789],{"type":24,"value":4790},"We are just getting started so we don't have a clear long-term roadmap yet, but here are some major directions that we plan to explore and work on next.",{"type":19,"tag":151,"props":4792,"children":4794},{"id":4793},"monaco-support",[4795],{"type":24,"value":4796},"Monaco Support",{"type":19,"tag":20,"props":4798,"children":4799},{},[4800,4802,4808],{"type":24,"value":4801},"Monaco's support for Vue is currently implemented by ",{"type":19,"tag":37,"props":4803,"children":4805},{"className":4804},[],[4806],{"type":24,"value":4807},"monaco-volar",{"type":24,"value":4809},", and we plan to support it in the framework, so all language servers based on Volar.js will be able to take advantage of it easily.",{"type":19,"tag":151,"props":4811,"children":4813},{"id":4812},"support-for-ides-other-than-vscode",[4814],{"type":24,"value":4815},"Support for IDEs other than VSCode",{"type":19,"tag":20,"props":4817,"children":4818},{},[4819],{"type":24,"value":4820},"Many generous contributors have implemented language clients for other IDEs such as Vim, Sublime, Atom, Emacs, Nova, Lapce, etc. for Volar, in addition to VSCode.",{"type":19,"tag":20,"props":4822,"children":4823},{},[4824],{"type":24,"value":4825},"Having a full set of IDE support can be of great reference value, as very few people can be proficient in all of these IDEs.",{"type":19,"tag":20,"props":4827,"children":4828},{},[4829],{"type":24,"value":4830},"We will look for ways to leverage the efforts of these contributors to reduce the workload of framework adopters for implementing language clients outside of VSCode.",{"type":19,"tag":20,"props":4832,"children":4833},{},[4834],{"type":24,"value":4835},"Additionally, although IntelliJ does not have first-class LSP support, we will look into whether it is possible to integrate it with the framework.",{"type":19,"tag":151,"props":4837,"children":4839},{"id":4838},"bun-base-language-server",[4840],{"type":24,"value":4841},"Bun-base Language Server",{"type":19,"tag":20,"props":4843,"children":4844},{},[4845,4847,4854],{"type":24,"value":4846},"Theoretically, the performance of Volar can only be infinitely close to, but not faster than the vanilla TS language server. However, if the Volar language server can get a performance boost by running in ",{"type":19,"tag":51,"props":4848,"children":4851},{"href":4849,"rel":4850,"target":56},"https://bun.sh/",[55,55],[4852],{"type":24,"value":4853},"Bun",{"type":24,"value":4855},", it might be a game changer.",{"type":19,"tag":20,"props":4857,"children":4858},{},[4859],{"type":24,"value":4860},"Previously Bun's runtime was not yet compatible with Node.js-based LSP servers. We will keep an eye on related issues and try again when they are resolved.",{"type":19,"tag":20,"props":4862,"children":4863},{},[4864],{"type":24,"value":4865},"Similarly, all language servers based on Volar.js will be able to benefit directly from this.",{"type":19,"tag":151,"props":4867,"children":4869},{"id":4868},"monoserver",[4870],{"type":24,"value":4871},"Monoserver",{"type":19,"tag":20,"props":4873,"children":4874},{},[4875],{"type":24,"value":4876},"Imagine a scenario where every language would need to support some TypeScript features, so each language's language server would run its own expensive TypeScript Language Service instance, making things a bit scary, because both memory and CPU usage will increase doubly, and this situation has already happened today.",{"type":19,"tag":20,"props":4878,"children":4879},{},[4880],{"type":24,"value":4881},"If some of these language servers were based on Volar.js, we might have some way for them to decide to only activate one language server, and then share the features of the rest of the language servers to the activated one, so that in the end we would only need to run TypeScript Language Service in one language server instance instead of multiple language servers.",{"type":19,"tag":20,"props":4883,"children":4884},{},[4885],{"type":24,"value":4886},"This could also solve some use cases that TypeScript Plugins are not able to support.",{"type":19,"tag":20,"props":4888,"children":4889},{},[4890],{"type":24,"value":4891},"Based on the Volar.js architecture, we are already very close to this goal, and I and Erika will explore this feature for the Vue and Astro language servers.",{"type":19,"tag":151,"props":4893,"children":4895},{"id":4894},"rules-api-built-in-linter",[4896],{"type":24,"value":4897},"Rules API (Built-in Linter)",{"type":19,"tag":20,"props":4899,"children":4900},{},[4901],{"type":24,"value":4902},"You may have been tripped up when using ESLint and Prettier together, and our past attempts based on the Plugin API have not done a good job of avoiding this problem.",{"type":19,"tag":20,"props":4904,"children":4905},{},[4906],{"type":24,"value":4907},"The Rules API is another attempt to avoid conflicts between different linting tools, while also ensures that performance and features are perfectly integrated with the IDE.",{"type":19,"tag":20,"props":4909,"children":4910},{},[4911],{"type":24,"value":4912},"For meta-frameworks, they would need to implement their own parser for ESLint and Prettier, but with the Rules API they don't even need to do that, because we can reuse the parser from Volar language server.",{"type":19,"tag":20,"props":4914,"children":4915},{},[4916,4918,4923,4925,4931],{"type":24,"value":4917},"So if you write a TS rule, it will be available for TypeScript code in Vue's ",{"type":19,"tag":37,"props":4919,"children":4921},{"className":4920},[],[4922],{"type":24,"value":3789},{"type":24,"value":4924}," and template's ",{"type":19,"tag":37,"props":4926,"children":4928},{"className":4927},[],[4929],{"type":24,"value":4930},"{{ }}",{"type":24,"value":4932}," directly through the Rules API, without the need for extra parsers.",{"type":19,"tag":20,"props":4934,"children":4935},{},[4936],{"type":24,"value":4937},"This doesn't mean you need to rewrite all the rules; the Rules API is just an API, not a separate linter, so it is still possible to reuse some rules from ESLint, TSLint, and even Rome.",{"type":19,"tag":151,"props":4939,"children":4941},{"id":4940},"scripts-api",[4942],{"type":24,"value":4943},"Scripts API",{"type":19,"tag":20,"props":4945,"children":4946},{},[4947,4949,4954],{"type":24,"value":4948},"For Vue we have ",{"type":19,"tag":37,"props":4950,"children":4952},{"className":4951},[],[4953],{"type":24,"value":2853},{"type":24,"value":4955}," for checking TS code, and sometimes we also would like to check both CSS and Vue Template code at the same time in CI.",{"type":19,"tag":20,"props":4957,"children":4958},{},[4959],{"type":24,"value":4960},"The Scripts API is designed to expose the formatting and linting capabilities of the language server so that they can be used in scripts, allowing you to use it in CI or git pre-commit hooks and get the same results as you would in an IDE.",{"type":19,"tag":63,"props":4962,"children":4963},{},[],{"type":19,"tag":20,"props":4965,"children":4966},{},[4967,4969,4975,4977,4984],{"type":24,"value":4968},"I am very thankful to all the current and past sponsors. On top of hiring me to work full time on Volar for 6 months, Evan You (",{"type":19,"tag":51,"props":4970,"children":4973},{"href":4971,"rel":4972,"target":56},"https://twitter.com/youyuxi",[55,55],[4974],{"type":24,"value":14},{"type":24,"value":4976},") continues to be a gold sponsor. ",{"type":19,"tag":51,"props":4978,"children":4981},{"href":4979,"rel":4980,"target":56},"https://nuxtlabs.com/",[55,55],[4982],{"type":24,"value":4983},"NuxtLabs",{"type":24,"value":4985}," has also generously extended their Platinum sponsorship. Without their support we wouldn't have shipped Volar 1.0.",{"type":19,"tag":20,"props":4987,"children":4988},{},[4989,4991,4996],{"type":24,"value":4990},"And of course, big thanks to ",{"type":19,"tag":51,"props":4992,"children":4994},{"href":4768,"rel":4993,"target":56},[55,55],[4995],{"type":24,"value":4772},{"type":24,"value":4997}," for making it possible for me to work on it full-time.",{"type":19,"tag":20,"props":4999,"children":5000},{},[5001,5003,5010],{"type":24,"value":5002},"If you want to support the vision of the Volar.js community, don't hesitate to ",{"type":19,"tag":51,"props":5004,"children":5007},{"href":5005,"rel":5006,"target":56},"https://github.com/sponsors/johnsoncodehk",[55,55],[5008],{"type":24,"value":5009},"become a sponsor",{"type":24,"value":5011},". I hope in addition to Volar, you can also benefit from Volar.js in the future.",{"title":8,"searchDepth":292,"depth":292,"links":5013},[5014,5015,5016,5017],{"id":4481,"depth":292,"text":4484},{"id":4538,"depth":292,"text":4541},{"id":4590,"depth":292,"text":4593},{"id":4782,"depth":292,"text":4785,"children":5018},[5019,5020,5021,5022,5023,5024],{"id":4793,"depth":353,"text":4796},{"id":4812,"depth":353,"text":4815},{"id":4838,"depth":353,"text":4841},{"id":4868,"depth":353,"text":4871},{"id":4894,"depth":353,"text":4897},{"id":4940,"depth":353,"text":4943},"content:blog:volar-a-new-beginning.md","blog/volar-a-new-beginning.md","blog/volar-a-new-beginning",{"loc":4438},{"_path":5030,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":5031,"description":5032,"date":5033,"author":12,"gravatar":13,"twitter":14,"excerpt":5034,"body":5040,"_type":1125,"_id":5420,"_source":1127,"_file":5421,"_stem":5422,"_extension":1130,"sitemap":5423},"/blog/2022-year-in-review","2022 Year In Review","Happy new year, Vue community! With 2023 upon us, we would like to take this opportunity to recap what happened in 2022, and discuss what to expect in 2023.","2023-01-01",{"type":16,"children":5035},[5036],{"type":19,"tag":20,"props":5037,"children":5038},{},[5039],{"type":24,"value":5032},{"type":16,"children":5041,"toc":5411},[5042,5046,5049,5055,5068,5088,5183,5195,5201,5207,5212,5226,5238,5243,5261,5266,5271,5276,5290,5320,5325,5331,5336,5380,5385,5391],{"type":19,"tag":20,"props":5043,"children":5044},{},[5045],{"type":24,"value":5032},{"type":19,"tag":63,"props":5047,"children":5048},{},[],{"type":19,"tag":72,"props":5050,"children":5052},{"id":5051},"recap-for-2022",[5053],{"type":24,"value":5054},"Recap for 2022",{"type":19,"tag":20,"props":5056,"children":5057},{},[5058,5060,5066],{"type":24,"value":5059},"In February 2022, we ",{"type":19,"tag":51,"props":5061,"children":5063},{"href":5062},"/blog/vue-3-as-the-new-default",[5064],{"type":24,"value":5065},"switched Vue's default version to 3.x",{"type":24,"value":5067},". The switch marked the readiness of all the official parts of the framework for v3, including a major revamp of the documentation that provides guidance on latest best practices.",{"type":19,"tag":20,"props":5069,"children":5070},{},[5071,5073,5079,5081,5087],{"type":24,"value":5072},"We are still in a transition period for the ecosystem to move to Vue 3. So after the switch, we focused more on improving Vue's developer experience by investing in tooling. Our team members have been actively involved in the development of ",{"type":19,"tag":51,"props":5074,"children":5077},{"href":5075,"rel":5076,"target":56},"https://vitejs.dev",[55,55],[5078],{"type":24,"value":4605},{"type":24,"value":5080},", and we made significant improvement to Vue's IDE and TypeScript support by shipping ",{"type":19,"tag":51,"props":5082,"children":5084},{"href":5083},"/blog/volar-1.0",[5085],{"type":24,"value":5086},"Volar 1.0",{"type":24,"value":61},{"type":19,"tag":20,"props":5089,"children":5090},{},[5091,5093,5098,5100,5107,5108,5115,5117,5124,5126,5133,5134,5141,5142,5149,5150,5157,5158,5165,5166,5173,5175,5182],{"type":24,"value":5092},"Over the course of 2022, we saw the NPM usage of Vue 3 grew by ",{"type":19,"tag":98,"props":5094,"children":5095},{},[5096],{"type":24,"value":5097},"almost 200%",{"type":24,"value":5099},". On the community side, the Vue 3 ecosystem is now ripe with great solutions to help boost your productivity. Both ",{"type":19,"tag":51,"props":5101,"children":5104},{"href":5102,"rel":5103,"target":56},"https://nuxt.com",[55,55],[5105],{"type":24,"value":5106},"Nuxt 3",{"type":24,"value":1384},{"type":19,"tag":51,"props":5109,"children":5112},{"href":5110,"rel":5111,"target":56},"https://vuetifyjs.com",[55,55],[5113],{"type":24,"value":5114},"Vuetify 3",{"type":24,"value":5116}," reached stable status in November 2022, and ",{"type":19,"tag":51,"props":5118,"children":5121},{"href":5119,"rel":5120,"target":56},"https://github.com/nativescript-vue/nativescript-vue",[55,55],[5122],{"type":24,"value":5123},"NativeScript for Vue 3",{"type":24,"value":5125}," recently launched beta. In addition, we want to give a shout out to other great projects that had already supported Vue 3 for quite some time: ",{"type":19,"tag":51,"props":5127,"children":5130},{"href":5128,"rel":5129,"target":56},"https://quasar.dev/",[55,55],[5131],{"type":24,"value":5132},"Quasar",{"type":24,"value":474},{"type":19,"tag":51,"props":5135,"children":5138},{"href":5136,"rel":5137,"target":56},"https://www.naiveui.com/",[55,55],[5139],{"type":24,"value":5140},"NaiveUI",{"type":24,"value":474},{"type":19,"tag":51,"props":5143,"children":5146},{"href":5144,"rel":5145,"target":56},"https://ionicframework.com/docs/vue/overview",[55,55],[5147],{"type":24,"value":5148},"Ionic Vue",{"type":24,"value":474},{"type":19,"tag":51,"props":5151,"children":5154},{"href":5152,"rel":5153,"target":56},"https://www.primefaces.org/primevue/",[55,55],[5155],{"type":24,"value":5156},"PrimeVue",{"type":24,"value":474},{"type":19,"tag":51,"props":5159,"children":5162},{"href":5160,"rel":5161,"target":56},"https://www.inkline.io/",[55,55],[5163],{"type":24,"value":5164},"InkLine",{"type":24,"value":474},{"type":19,"tag":51,"props":5167,"children":5170},{"href":5168,"rel":5169,"target":56},"https://element-plus.org/",[55,55],[5171],{"type":24,"value":5172},"ElementPlus",{"type":24,"value":5174},", and ",{"type":19,"tag":51,"props":5176,"children":5179},{"href":5177,"rel":5178,"target":56},"https://twitter.com/vuejs/status/1599706412086878208",[55,55],[5180],{"type":24,"value":5181},"more",{"type":24,"value":61},{"type":19,"tag":20,"props":5184,"children":5185},{},[5186,5188,5193],{"type":24,"value":5187},"Despite Vue 3 being now the default, we understand that many users have to stay on Vue 2 due to the cost of migration. To ensure that Vue 2 users benefit from the advancement of the framework, we decided to move Vue 2's source code to TypeScript and back-ported some of the most important Vue 3 features in ",{"type":19,"tag":51,"props":5189,"children":5191},{"href":5190},"/blog/vue-2-7-naruto",[5192],{"type":24,"value":1179},{"type":24,"value":5194},". We also made sure that Vite, Vue Devtools and Volar all simultaneously support Vue 2 and Vue 3.",{"type":19,"tag":72,"props":5196,"children":5198},{"id":5197},"what-to-expect-in-2023",[5199],{"type":24,"value":5200},"What to Expect in 2023",{"type":19,"tag":151,"props":5202,"children":5204},{"id":5203},"smaller-and-more-frequent-minor-releases",[5205],{"type":24,"value":5206},"Smaller and More Frequent Minor Releases",{"type":19,"tag":20,"props":5208,"children":5209},{},[5210],{"type":24,"value":5211},"With the last Vue 2 minor release (2.7) out of the door, we expect to be full steam ahead shipping features for Vue 3 core in 2023. We have quite a long list of features that we are excited to work on!",{"type":19,"tag":20,"props":5213,"children":5214},{},[5215,5217,5224],{"type":24,"value":5216},"One thing we would like to improve is our release cadence. Vue follows ",{"type":19,"tag":51,"props":5218,"children":5221},{"href":5219,"rel":5220,"target":56},"https://semver.org/",[55,55],[5222],{"type":24,"value":5223},"semver",{"type":24,"value":5225},", which means we should only ship features in minor versions. In the past, we did a \"big minor\" approach where we group many features together in big, infrequent minor releases. This has resulted in quite some low-complexity features being blocked while we worked on other high-complexity ones. In 2023, we want to do smaller and more frequent minor releases so that we can get more features out, faster.",{"type":19,"tag":20,"props":5227,"children":5228},{},[5229,5231,5236],{"type":24,"value":5230},"This also means we will be adjusting what goes into 3.3. Originally, we planned to graduate Suspense and Reactivity Transform from experimental status in 3.3. However, we feel that both still need further RFC discussion, and they should not block other more straightforward features to land. Now, the goal of 3.3 is to land proposed / planned features that are clear wins and do not require RFC discussion - for example, supporting externally imported types in ",{"type":19,"tag":37,"props":5232,"children":5234},{"className":5233},[],[5235],{"type":24,"value":544},{"type":24,"value":5237}," macros.",{"type":19,"tag":20,"props":5239,"children":5240},{},[5241],{"type":24,"value":5242},"In parallel to that, we will:",{"type":19,"tag":79,"props":5244,"children":5245},{},[5246,5251,5256],{"type":19,"tag":83,"props":5247,"children":5248},{},[5249],{"type":24,"value":5250},"Further evaluate the readiness of Suspense and Reactivity Transform.",{"type":19,"tag":83,"props":5252,"children":5253},{},[5254],{"type":24,"value":5255},"Spend time to evaluate outstanding user-submitted RFCs and feature requests.",{"type":19,"tag":83,"props":5257,"children":5258},{},[5259],{"type":24,"value":5260},"Post RFCs for features that we intend to land in 3.4 and beyond, for example SSR lazy hydration.",{"type":19,"tag":20,"props":5262,"children":5263},{},[5264],{"type":24,"value":5265},"Expect more details later this month.",{"type":19,"tag":20,"props":5267,"children":5268},{},[5269],{"type":24,"value":5270},"Another thing to note is there is no plan for big breaking changes for the foreseeable future. Acknowledging the challenges users faced during the v2 to v3 transition, we want to have a better long term upgrade story for Vue going forward.",{"type":19,"tag":151,"props":5272,"children":5274},{"id":5273},"vapor-mode",[5275],{"type":24,"value":1420},{"type":19,"tag":20,"props":5277,"children":5278},{},[5279,5281,5288],{"type":24,"value":5280},"Vapor Mode is an alternative compilation strategy that we have been experimenting with, inspired by ",{"type":19,"tag":51,"props":5282,"children":5285},{"href":5283,"rel":5284,"target":56},"https://www.solidjs.com/",[55,55],[5286],{"type":24,"value":5287},"Solid",{"type":24,"value":5289},". Given the same Vue SFC, Vapor Mode compiles it into JavaScript output that is more performant, uses less memory, and requires less runtime support code compared to the current Virtual DOM based output. It is still in early phase, but here are some high level points:",{"type":19,"tag":89,"props":5291,"children":5292},{},[5293,5298,5303,5308],{"type":19,"tag":83,"props":5294,"children":5295},{},[5296],{"type":24,"value":5297},"Vapor Mode is intended for use cases where performance is the primary concern. It is opt-in and does not affect existing codebases.",{"type":19,"tag":83,"props":5299,"children":5300},{},[5301],{"type":24,"value":5302},"At the very least, you will be able to embed a Vapor component subtree into any existing Vue 3 app. Ideally, we hope to achieve granular opt-in at the component level, which means freely mixing Vapor and non-Vapor components in the same app.",{"type":19,"tag":83,"props":5304,"children":5305},{},[5306],{"type":24,"value":5307},"Building an app with only Vapor components allows you to drop the Virtual DOM runtime from the bundle, significantly reducing the baseline runtime size.",{"type":19,"tag":83,"props":5309,"children":5310},{},[5311,5313,5318],{"type":24,"value":5312},"In order to achieve the best performance, Vapor Mode will only support a subset of Vue features. In particular, Vapor Mode components will only support Composition API and ",{"type":19,"tag":37,"props":5314,"children":5316},{"className":5315},[],[5317],{"type":24,"value":544},{"type":24,"value":5319},". However, this supported subset will work exactly the same between Vapor and non-Vapor components.",{"type":19,"tag":20,"props":5321,"children":5322},{},[5323],{"type":24,"value":5324},"We will share more details as we make more progress later in the year.",{"type":19,"tag":151,"props":5326,"children":5328},{"id":5327},"conferences",[5329],{"type":24,"value":5330},"Conferences",{"type":19,"tag":20,"props":5332,"children":5333},{},[5334],{"type":24,"value":5335},"There are already many in-person Vue conferences lined up for 2023:",{"type":19,"tag":89,"props":5337,"children":5338},{},[5339,5351,5363,5375],{"type":19,"tag":83,"props":5340,"children":5341},{},[5342,5349],{"type":19,"tag":51,"props":5343,"children":5346},{"href":5344,"rel":5345,"target":56},"https://vuejs.amsterdam/",[55,55],[5347],{"type":24,"value":5348},"Vue.js Amsterdam",{"type":24,"value":5350}," - Feb 9-10, Amsterdam, The Netherlands",{"type":19,"tag":83,"props":5352,"children":5353},{},[5354,5361],{"type":19,"tag":51,"props":5355,"children":5358},{"href":5356,"rel":5357,"target":56},"https://vuejslive.com/",[55,55],[5359],{"type":24,"value":5360},"Vue.js Live",{"type":24,"value":5362}," - May 12 & 15th, London, UK",{"type":19,"tag":83,"props":5364,"children":5365},{},[5366,5373],{"type":19,"tag":51,"props":5367,"children":5370},{"href":5368,"rel":5369,"target":56},"https://us.vuejs.org/",[55,55],[5371],{"type":24,"value":5372},"VueConf US",{"type":24,"value":5374}," - May 24-26th, New Orleans, USA",{"type":19,"tag":83,"props":5376,"children":5377},{},[5378],{"type":24,"value":5379},"VueFes Japan - October 28th, Tokyo, Japan (info TBA)",{"type":19,"tag":20,"props":5381,"children":5382},{},[5383],{"type":24,"value":5384},"I (Evan) plan to attend all of these in person. After almost 3 years of absence, I can't wait to meet the community again - please come say hi!",{"type":19,"tag":151,"props":5386,"children":5388},{"id":5387},"one-year-until-vue-2-eol",[5389],{"type":24,"value":5390},"One Year Until Vue 2 EOL",{"type":19,"tag":20,"props":5392,"children":5393},{},[5394,5396,5401,5403,5410],{"type":24,"value":5395},"As a reminder, today marks ",{"type":19,"tag":98,"props":5397,"children":5398},{},[5399],{"type":24,"value":5400},"exactly one year until the end of Vue 2 support",{"type":24,"value":5402},". We have created a page explaining the implication of this and outlining the options for those who expect to be using Vue 2 beyond the EOL date: ",{"type":19,"tag":51,"props":5404,"children":5407},{"href":5405,"rel":5406,"target":56},"https://v2.vuejs.org/lts/",[55,55],[5408],{"type":24,"value":5409},"Details on Vue 2 EOL and Extended Support",{"type":24,"value":61},{"title":8,"searchDepth":292,"depth":292,"links":5412},[5413,5414],{"id":5051,"depth":292,"text":5054},{"id":5197,"depth":292,"text":5200,"children":5415},[5416,5417,5418,5419],{"id":5203,"depth":353,"text":5206},{"id":5273,"depth":353,"text":1420},{"id":5327,"depth":353,"text":5330},{"id":5387,"depth":353,"text":5390},"content:blog:2022-year-in-review.md","blog/2022-year-in-review.md","blog/2022-year-in-review",{"loc":5030},{"_path":5425,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":5426,"description":5427,"date":5428,"author":12,"gravatar":13,"twitter":14,"excerpt":5429,"body":5445,"_type":1125,"_id":6115,"_source":1127,"_file":6116,"_stem":6117,"_extension":1130,"sitemap":6118},"/blog/on-migration","On Escape's Vue 2 to Svelte Migration","Recently, folks at Escape shared a blog post talking about their migration from Vue 2 to Svelte, and compared Vue 3 with Svelte. We found that the article contained a number of inaccuracies. In this post, we will share some thoughts from our perspective and hope to clarify the potential misconceptions the post could give rise to.","2022-12-05",{"type":16,"children":5430},[5431],{"type":19,"tag":20,"props":5432,"children":5433},{},[5434,5436,5443],{"type":24,"value":5435},"Recently, folks at Escape shared a ",{"type":19,"tag":51,"props":5437,"children":5440},{"href":5438,"rel":5439,"target":56},"https://escape.tech/blog/from-vue2-to-svelte/",[55,55],[5441],{"type":24,"value":5442},"blog post",{"type":24,"value":5444}," talking about their migration from Vue 2 to Svelte, and compared Vue 3 with Svelte. We found that the article contained a number of inaccuracies. In this post, we will share some thoughts from our perspective and hope to clarify the potential misconceptions the post could give rise to.",{"type":16,"children":5446,"toc":6101},[5447,5457,5460,5465,5471,5476,5484,5490,5499,5513,5518,5524,5532,5546,5552,5560,5587,5593,5607,5620,5626,5634,5645,5651,5656,5662,5667,5680,5685,5732,5744,5964,5969,5975,5980,6003,6017,6030,6036,6041,6046,6051,6056,6061,6067,6072,6075,6097],{"type":19,"tag":20,"props":5448,"children":5449},{},[5450,5451,5456],{"type":24,"value":5435},{"type":19,"tag":51,"props":5452,"children":5454},{"href":5438,"rel":5453,"target":56},[55,55],[5455],{"type":24,"value":5442},{"type":24,"value":5444},{"type":19,"tag":63,"props":5458,"children":5459},{},[],{"type":19,"tag":20,"props":5461,"children":5462},{},[5463],{"type":24,"value":5464},"Before we dive into the details, we would like to emphasize that we respect developers' choice of technology and believe that you should use what makes you more productive. We also have immense respect for the Svelte team, especially for their pursuit of simplicity and conciseness in API design.",{"type":19,"tag":72,"props":5466,"children":5468},{"id":5467},"clarification-points",[5469],{"type":24,"value":5470},"Clarification Points",{"type":19,"tag":20,"props":5472,"children":5473},{},[5474],{"type":24,"value":5475},"The original post included a comparison chart that contains a number of issues that deserves clarification:",{"type":19,"tag":20,"props":5477,"children":5478},{},[5479],{"type":19,"tag":642,"props":5480,"children":5483},{"alt":5481,"src":5482},"comparison-chart","/compare.png",[],{"type":19,"tag":151,"props":5485,"children":5487},{"id":5486},"typing",[5488],{"type":24,"value":5489},"Typing",{"type":19,"tag":5491,"props":5492,"children":5493},"blockquote",{},[5494],{"type":19,"tag":20,"props":5495,"children":5496},{},[5497],{"type":24,"value":5498},"Vue 3 does not supported typed events",{"type":19,"tag":20,"props":5500,"children":5501},{},[5502,5504,5511],{"type":24,"value":5503},"This has been available since 3.2 (",{"type":19,"tag":51,"props":5505,"children":5508},{"href":5506,"rel":5507,"target":56},"https://vuejs.org/guide/typescript/composition-api.html#typing-component-emits",[55,55],[5509],{"type":24,"value":5510},"relevant documentation",{"type":24,"value":5512},").",{"type":19,"tag":20,"props":5514,"children":5515},{},[5516],{"type":24,"value":5517},"Aside from this, we disagree with the conclusion that \"Svelte offers a better typing experience\". To our best knowledge, TypeScript support for Vue 3 and Svelte in their current state are fairly comparable.",{"type":19,"tag":151,"props":5519,"children":5521},{"id":5520},"restricted-global-access",[5522],{"type":24,"value":5523},"Restricted Global Access",{"type":19,"tag":5491,"props":5525,"children":5526},{},[5527],{"type":19,"tag":20,"props":5528,"children":5529},{},[5530],{"type":24,"value":5531},"Cannot import and use TypeScript enums in a Vue component",{"type":19,"tag":20,"props":5533,"children":5534},{},[5535,5537,5544],{"type":24,"value":5536},"This is incorrect. Here is ",{"type":19,"tag":51,"props":5538,"children":5541},{"href":5539,"rel":5540,"target":56},"https://sfc.vuejs.org/#eNpVjz0OwjAMha9iZWGBZK8qJBZOkaWNDLQiP4pdQKpyd5y0AyxWPsfPz29Vl5T0a0HVqZ5cnhIDIS/pbMPkU8wMK1xjhAK3HD0ctGEk1kwHG3qzKWRWgNGn58AoBLA2lR6glB8c/9E17GXjrlRHtZme/JD0TDHIWWtV2P2DrOqgdWpP7q5s1YM5UWcM3VwNM5OO+W7kpfMSePKokfxpzPFNmGWxVXWFmBex3AOJFX5aYhcDMWBYfIve7IZjrWOrrurKF/sKa48=",[55,55],[5542],{"type":24,"value":5543},"an example",{"type":24,"value":5545},". In fact, it works exactly the same between Vue and Svelte.",{"type":19,"tag":151,"props":5547,"children":5549},{"id":5548},"external-reactive-objects",[5550],{"type":24,"value":5551},"External Reactive Objects",{"type":19,"tag":5491,"props":5553,"children":5554},{},[5555],{"type":19,"tag":20,"props":5556,"children":5557},{},[5558],{"type":24,"value":5559},"Partial (for objects only)",{"type":19,"tag":20,"props":5561,"children":5562},{},[5563,5565,5572,5574,5579,5580,5585],{"type":24,"value":5564},"This is a bit vague and was not explained further in the post, but all Vue's ",{"type":19,"tag":51,"props":5566,"children":5569},{"href":5567,"rel":5568,"target":56},"https://vuejs.org/api/reactivity-core.html",[55,55],[5570],{"type":24,"value":5571},"reactivity APIs",{"type":24,"value":5573},", including ",{"type":19,"tag":37,"props":5575,"children":5577},{"className":5576},[],[5578],{"type":24,"value":4050},{"type":24,"value":474},{"type":19,"tag":37,"props":5581,"children":5583},{"className":5582},[],[5584],{"type":24,"value":3989},{"type":24,"value":5586}," and watchers, can be used outside of components to serve as simple cross-component stores.",{"type":19,"tag":151,"props":5588,"children":5590},{"id":5589},"error-boundaries",[5591],{"type":24,"value":5592},"Error Boundaries",{"type":19,"tag":20,"props":5594,"children":5595},{},[5596,5598,5605],{"type":24,"value":5597},"Vue has always provided the capability of capturing errors thrown from descendent component trees in an ancestor component, through the ",{"type":19,"tag":51,"props":5599,"children":5602},{"href":5600,"rel":5601,"target":56},"https://vuejs.org/api/composition-api-lifecycle.html#onerrorcaptured",[55,55],[5603],{"type":24,"value":5604},"onErrorCaptured",{"type":24,"value":5606}," lifecycle hook. This includes errors thrown from async event handlers and lifecycle hooks as well.",{"type":19,"tag":20,"props":5608,"children":5609},{},[5610,5612,5619],{"type":24,"value":5611},"Vue does not have a built-in for handling Promise state directly in the template, but this can be easily achieved with libraries such as ",{"type":19,"tag":51,"props":5613,"children":5616},{"href":5614,"rel":5615,"target":56},"https://github.com/posva/vue-promised",[55,55],[5617],{"type":24,"value":5618},"vue-promised",{"type":24,"value":61},{"type":19,"tag":151,"props":5621,"children":5623},{"id":5622},"integrating-with-libraries",[5624],{"type":24,"value":5625},"Integrating with Libraries",{"type":19,"tag":5491,"props":5627,"children":5628},{},[5629],{"type":19,"tag":20,"props":5630,"children":5631},{},[5632],{"type":24,"value":5633},"It's simpler to add pure js plugins in Svelte",{"type":19,"tag":20,"props":5635,"children":5636},{},[5637,5639,5644],{"type":24,"value":5638},"The post included an example of integrating with Prism.js to support this point. However, in Vue it would work exactly the same when using ",{"type":19,"tag":37,"props":5640,"children":5642},{"className":5641},[],[5643],{"type":24,"value":544},{"type":24,"value":61},{"type":19,"tag":151,"props":5646,"children":5648},{"id":5647},"meta-frameworks",[5649],{"type":24,"value":5650},"Meta Frameworks",{"type":19,"tag":20,"props":5652,"children":5653},{},[5654],{"type":24,"value":5655},"The post also compares meta frameworks built on top of Vue and Svelte, namely Nuxt and SvelteKit, and lists Vite as an advantage for SvelteKit. However, Nuxt 3 has just reached stable and also uses Vite by default. Both the Nuxt team and the SvelteKit team have close working relationship with the Vite team.",{"type":19,"tag":72,"props":5657,"children":5659},{"id":5658},"syntax",[5660],{"type":24,"value":5661},"Syntax",{"type":19,"tag":20,"props":5663,"children":5664},{},[5665],{"type":24,"value":5666},"We respect different syntax preferences, but it is also important to discuss the trade-offs between the designs.",{"type":19,"tag":20,"props":5668,"children":5669},{},[5670,5672,5678],{"type":24,"value":5671},"First of all, we do not believe that differences like single vs. double curly braces, element-bound directives vs. mustache-style control flows, or the need of an extra ",{"type":19,"tag":37,"props":5673,"children":5675},{"className":5674},[],[5676],{"type":24,"value":5677},"\u003Ctemplate>",{"type":24,"value":5679}," tag will have substantial impact on your long term productivity. Template syntax is something that will be quickly internalized over time.",{"type":19,"tag":20,"props":5681,"children":5682},{},[5683],{"type":24,"value":5684},"When it comes to reactivity, Svelte does offer a very succinct syntax for declaring and mutating component state, and there are several points worth discussing:",{"type":19,"tag":79,"props":5686,"children":5687},{},[5688,5722,5727],{"type":19,"tag":83,"props":5689,"children":5690},{},[5691,5693,5699,5701,5706,5707,5713,5715,5720],{"type":24,"value":5692},"For expressing reactivity, there are three basic concepts: state, derived state, and effects. Svelte uses plain variables for state, and the magic ",{"type":19,"tag":37,"props":5694,"children":5696},{"className":5695},[],[5697],{"type":24,"value":5698},"$",{"type":24,"value":5700}," symbol for both derived state and effects. Vue uses explicit APIs for declaring each (",{"type":19,"tag":37,"props":5702,"children":5704},{"className":5703},[],[5705],{"type":24,"value":4050},{"type":24,"value":474},{"type":19,"tag":37,"props":5708,"children":5710},{"className":5709},[],[5711],{"type":24,"value":5712},"computed,",{"type":24,"value":5714}," ",{"type":19,"tag":37,"props":5716,"children":5718},{"className":5717},[],[5719],{"type":24,"value":369},{"type":24,"value":5721},"). Some users may prefer magical syntax, while others may prefer explicit APIs - there is room for both camps.",{"type":19,"tag":83,"props":5723,"children":5724},{},[5725],{"type":24,"value":5726},"Svelte's compiler-based reactivity limits where such syntax can be used. It cannot be used outside of Svelte components, or in use cases where a build step is not possible. Whereas for Vue, the Composition API can be used the same way in and out of components, or even in no-build-step setups.",{"type":19,"tag":83,"props":5728,"children":5729},{},[5730],{"type":24,"value":5731},"Because of (2), Svelte needs to provide an additional set of API (stores) for managing the same reactivity concepts outside of components. Since the two syntaxes are not easily convertible into one another, it creates friction for moving / refactoring logic out of components.",{"type":19,"tag":20,"props":5733,"children":5734},{},[5735,5737,5742],{"type":24,"value":5736},"With that said, we have been experimenting with a feature called ",{"type":19,"tag":51,"props":5738,"children":5740},{"href":1023,"rel":5739,"target":56},[55,55],[5741],{"type":24,"value":1027},{"type":24,"value":5743}," in Vue, which allows you to author Vue components like this:",{"type":19,"tag":236,"props":5745,"children":5747},{"className":623,"code":5746,"language":625,"meta":8,"style":8},"\u003Cscript setup>\n  let count = ref(0)\n\n  function increment() {\n    count++\n  }\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cbutton @click=\"increment\">{{ count }}\u003C/button>\n\u003C/template>\n",[5748],{"type":19,"tag":37,"props":5749,"children":5750},{"__ignoreMap":8},[5751,5770,5802,5809,5826,5839,5846,5861,5868,5883,5949],{"type":19,"tag":246,"props":5752,"children":5753},{"class":248,"line":249},[5754,5758,5762,5766],{"type":19,"tag":246,"props":5755,"children":5756},{"style":259},[5757],{"type":24,"value":637},{"type":19,"tag":246,"props":5759,"children":5760},{"style":253},[5761],{"type":24,"value":1598},{"type":19,"tag":246,"props":5763,"children":5764},{"style":650},[5765],{"type":24,"value":1603},{"type":19,"tag":246,"props":5767,"children":5768},{"style":259},[5769],{"type":24,"value":1631},{"type":19,"tag":246,"props":5771,"children":5772},{"class":248,"line":292},[5773,5778,5782,5786,5790,5794,5798],{"type":19,"tag":246,"props":5774,"children":5775},{"style":253},[5776],{"type":24,"value":5777},"  let",{"type":19,"tag":246,"props":5779,"children":5780},{"style":259},[5781],{"type":24,"value":262},{"type":19,"tag":246,"props":5783,"children":5784},{"style":253},[5785],{"type":24,"value":267},{"type":19,"tag":246,"props":5787,"children":5788},{"style":270},[5789],{"type":24,"value":273},{"type":19,"tag":246,"props":5791,"children":5792},{"style":259},[5793],{"type":24,"value":278},{"type":19,"tag":246,"props":5795,"children":5796},{"style":281},[5797],{"type":24,"value":284},{"type":19,"tag":246,"props":5799,"children":5800},{"style":259},[5801],{"type":24,"value":289},{"type":19,"tag":246,"props":5803,"children":5804},{"class":248,"line":353},[5805],{"type":19,"tag":246,"props":5806,"children":5807},{"emptyLinePlaceholder":357},[5808],{"type":24,"value":360},{"type":19,"tag":246,"props":5810,"children":5811},{"class":248,"line":363},[5812,5816,5821],{"type":19,"tag":246,"props":5813,"children":5814},{"style":253},[5815],{"type":24,"value":3381},{"type":19,"tag":246,"props":5817,"children":5818},{"style":270},[5819],{"type":24,"value":5820}," increment",{"type":19,"tag":246,"props":5822,"children":5823},{"style":259},[5824],{"type":24,"value":5825},"() {\n",{"type":19,"tag":246,"props":5827,"children":5828},{"class":248,"line":401},[5829,5834],{"type":19,"tag":246,"props":5830,"children":5831},{"style":259},[5832],{"type":24,"value":5833},"    count",{"type":19,"tag":246,"props":5835,"children":5836},{"style":253},[5837],{"type":24,"value":5838},"++\n",{"type":19,"tag":246,"props":5840,"children":5841},{"class":248,"line":409},[5842],{"type":19,"tag":246,"props":5843,"children":5844},{"style":259},[5845],{"type":24,"value":3436},{"type":19,"tag":246,"props":5847,"children":5848},{"class":248,"line":2155},[5849,5853,5857],{"type":19,"tag":246,"props":5850,"children":5851},{"style":259},[5852],{"type":24,"value":1736},{"type":19,"tag":246,"props":5854,"children":5855},{"style":253},[5856],{"type":24,"value":1598},{"type":19,"tag":246,"props":5858,"children":5859},{"style":259},[5860],{"type":24,"value":1631},{"type":19,"tag":246,"props":5862,"children":5863},{"class":248,"line":3057},[5864],{"type":19,"tag":246,"props":5865,"children":5866},{"emptyLinePlaceholder":357},[5867],{"type":24,"value":360},{"type":19,"tag":246,"props":5869,"children":5870},{"class":248,"line":3066},[5871,5875,5879],{"type":19,"tag":246,"props":5872,"children":5873},{"style":259},[5874],{"type":24,"value":637},{"type":19,"tag":246,"props":5876,"children":5877},{"style":253},[5878],{"type":24,"value":3154},{"type":19,"tag":246,"props":5880,"children":5881},{"style":259},[5882],{"type":24,"value":1631},{"type":19,"tag":246,"props":5884,"children":5885},{"class":248,"line":3111},[5886,5890,5895,5899,5904,5908,5912,5917,5921,5925,5929,5933,5937,5941,5945],{"type":19,"tag":246,"props":5887,"children":5888},{"style":259},[5889],{"type":24,"value":3481},{"type":19,"tag":246,"props":5891,"children":5892},{"style":253},[5893],{"type":24,"value":5894},"button",{"type":19,"tag":246,"props":5896,"children":5897},{"style":259},[5898],{"type":24,"value":3516},{"type":19,"tag":246,"props":5900,"children":5901},{"style":650},[5902],{"type":24,"value":5903},"click",{"type":19,"tag":246,"props":5905,"children":5906},{"style":253},[5907],{"type":24,"value":267},{"type":19,"tag":246,"props":5909,"children":5910},{"style":660},[5911],{"type":24,"value":663},{"type":19,"tag":246,"props":5913,"children":5914},{"style":259},[5915],{"type":24,"value":5916},"increment",{"type":19,"tag":246,"props":5918,"children":5919},{"style":660},[5920],{"type":24,"value":663},{"type":19,"tag":246,"props":5922,"children":5923},{"style":259},[5924],{"type":24,"value":3159},{"type":19,"tag":246,"props":5926,"children":5927},{"style":253},[5928],{"type":24,"value":3164},{"type":19,"tag":246,"props":5930,"children":5931},{"style":259},[5932],{"type":24,"value":262},{"type":19,"tag":246,"props":5934,"children":5935},{"style":253},[5936],{"type":24,"value":3174},{"type":19,"tag":246,"props":5938,"children":5939},{"style":259},[5940],{"type":24,"value":1736},{"type":19,"tag":246,"props":5942,"children":5943},{"style":253},[5944],{"type":24,"value":5894},{"type":19,"tag":246,"props":5946,"children":5947},{"style":259},[5948],{"type":24,"value":1631},{"type":19,"tag":246,"props":5950,"children":5951},{"class":248,"line":3120},[5952,5956,5960],{"type":19,"tag":246,"props":5953,"children":5954},{"style":259},[5955],{"type":24,"value":1736},{"type":19,"tag":246,"props":5957,"children":5958},{"style":253},[5959],{"type":24,"value":3154},{"type":19,"tag":246,"props":5961,"children":5962},{"style":259},[5963],{"type":24,"value":1631},{"type":19,"tag":20,"props":5965,"children":5966},{},[5967],{"type":24,"value":5968},"It provides a level of brevity similar to Svelte, but is also usable in plain JS/TS files. It's also straightforward to automatically de-sugar the syntax into plain Composition API code.",{"type":19,"tag":72,"props":5970,"children":5972},{"id":5971},"performance-and-bundle-size",[5973],{"type":24,"value":5974},"Performance and Bundle Size",{"type":19,"tag":20,"props":5976,"children":5977},{},[5978],{"type":24,"value":5979},"Improved performance and bundle size was mentioned as one of the reasons for the migration. While there is no doubt Svelte is highly performant and lightweight, an improvement over other frameworks isn't necessarily guaranteed. In reality, it could depend on other factors, including actual implementations, room for optimization, and scale of the app.",{"type":19,"tag":20,"props":5981,"children":5982},{},[5983,5985,5992,5994,6001],{"type":24,"value":5984},"For reference, Vue 3 is able to outperform Svelte in the ",{"type":19,"tag":51,"props":5986,"children":5989},{"href":5987,"rel":5988,"target":56},"https://krausest.github.io/js-framework-benchmark/index.html",[55,55],[5990],{"type":24,"value":5991},"js-framework-benchmark",{"type":24,"value":5993}," with a small amount of optimization. Vue 3 achieves this with a runtime / compiler hybrid rendering model which we call ",{"type":19,"tag":51,"props":5995,"children":5998},{"href":5996,"rel":5997,"target":56},"https://vuejs.org/guide/extras/rendering-mechanism.html#compiler-informed-virtual-dom",[55,55],[5999],{"type":24,"value":6000},"Compiler-Informed Virtual DOM",{"type":24,"value":6002},". It leverages information that can be known at compile time to optimize runtime performance, while retaining compatibility with manually-written render functions.",{"type":19,"tag":20,"props":6004,"children":6005},{},[6006,6008,6015],{"type":24,"value":6007},"In terms of bundle size, Svelte is great for generating widgets or web components that contain only a single or a few components, but its light runtime size can be offset by its more verbose per-component code output compared to other frameworks. ",{"type":19,"tag":51,"props":6009,"children":6012},{"href":6010,"rel":6011,"target":56},"https://github.com/yyx990803/vue-svelte-size-analysis",[55,55],[6013],{"type":24,"value":6014},"This research",{"type":24,"value":6016}," shows that Svelte's app bundle size can become a disadvantage in larger scale apps, especially with SSR hydration enabled.",{"type":19,"tag":20,"props":6018,"children":6019},{},[6020,6022,6028],{"type":24,"value":6021},"It should be noted that both Svelte and Vue 3 are most likely performant enough for your use case, and that both frameworks will continue to evolve and improve. The Svelte team has mentioned plans for improved per-component code output size in Svelte 4. On the Vue side, we are also exploring an alternative, more performant compilation strategy (codename: Vapor) that is inspired by ",{"type":19,"tag":51,"props":6023,"children":6025},{"href":5283,"rel":6024,"target":56},[55,55],[6026],{"type":24,"value":6027},"Solid.js",{"type":24,"value":6029},". Vapor mode will allow Vue components to be compiled into a format that does not involve the Virtual DOM runtime. It is currently still in research phase, and we will share more details about it in 2023.",{"type":19,"tag":72,"props":6031,"children":6033},{"id":6032},"retention-data-in-the-state-of-js-survey",[6034],{"type":24,"value":6035},"Retention Data in the State of JS Survey",{"type":19,"tag":20,"props":6037,"children":6038},{},[6039],{"type":24,"value":6040},"In addition, a major point of consideration mentioned involved the satisfaction rating from the State of JavaScript survey. While Svelte definitely deserves its high rating in the survey, using such ratings to decide whether you should migrate your app can impact your team negatively since there are lots of missing context.",{"type":19,"tag":20,"props":6042,"children":6043},{},[6044],{"type":24,"value":6045},"In the survey, the satisfaction rating of a framework is defined as the ratio of number of users who would use it again, compared to those who would not. Note this number is only calculated based on the responses from the users who have used a framework. It should be fair to say that this formula naturally favors newer technologies. In theory, if a framework has only one user and that user reports that they would use it again, the framework would get a perfect 100% score!",{"type":19,"tag":20,"props":6047,"children":6048},{},[6049],{"type":24,"value":6050},"A technology in its early phase primarily attracts users who like the technology by itself. When it goes mainstream, however, it starts to get adopted in larger scale organizations where the tech choice decision is made top-down. This means there will be more and more users who have to work with it regardless of their personal preferences. It also attracts more drive-by users who try it purely out of its popularity, but may not be the target audience. Furthermore, wider adoption challenges the tech in a wider range of scenarios, exposing issues that may only arise in more demanding cases.",{"type":19,"tag":20,"props":6052,"children":6053},{},[6054],{"type":24,"value":6055},"On the other hand, a newer technology will probably not even make it into the survey if it fails to obtain a higher score than existing ones among its early adopters.",{"type":19,"tag":20,"props":6057,"children":6058},{},[6059],{"type":24,"value":6060},"This is in no way meant to diminish the accomplishments of Svelte, nor is it an excuse for us. The Vue 2 to Vue 3 transition didn't go as smoothly as it could, and has definitely affected the satisfaction score. We hope we can turn it around by continuing to improve Vue 3. But hopefully you get the point: the number alone does not fully represent how \"good\" a framework is, let alone how it suits your use case. Remember that surveys are often subject to many confounding variables and contexts which may not apply to your situation, so be cautious of referring to them as gospel.",{"type":19,"tag":72,"props":6062,"children":6064},{"id":6063},"conclusion",[6065],{"type":24,"value":6066},"Conclusion",{"type":19,"tag":20,"props":6068,"children":6069},{},[6070],{"type":24,"value":6071},"At the end of the day, we think Svelte is a great framework and we wish Escape all the best with their work with Svelte! After all, while we wanted to clarify some of the comparison points made, we're all part of the same community and want to help people build amazing products for users.",{"type":19,"tag":63,"props":6073,"children":6074},{},[],{"type":19,"tag":20,"props":6076,"children":6077},{},[6078,6080,6087,6089,6096],{"type":24,"value":6079},"Finally, if you have a codebase on Vue 2 and are concerned about the approaching end of life (EOY 2023), migrating isn't necessarily the only choice. Vue 2 is a stable, proven, and battle-tested piece of technology that will continue to work. Make sure to evaluate what your real gains and cost would be before committing to big migrations. For those that need to deal with security compliance, we are partnering with ",{"type":19,"tag":51,"props":6081,"children":6084},{"href":6082,"rel":6083,"target":56},"https://www.herodevs.com/",[55,55],[6085],{"type":24,"value":6086},"HeroDevs",{"type":24,"value":6088}," to provide paid extended support for Vue 2. If this is something your team will need, please register your interest ",{"type":19,"tag":51,"props":6090,"children":6093},{"href":6091,"rel":6092,"target":56},"https://airtable.com/shrj37Zf4ZIfrxFzh",[55,55],[6094],{"type":24,"value":6095},"here",{"type":24,"value":61},{"type":19,"tag":1103,"props":6098,"children":6099},{},[6100],{"type":24,"value":1107},{"title":8,"searchDepth":292,"depth":292,"links":6102},[6103,6111,6112,6113,6114],{"id":5467,"depth":292,"text":5470,"children":6104},[6105,6106,6107,6108,6109,6110],{"id":5486,"depth":353,"text":5489},{"id":5520,"depth":353,"text":5523},{"id":5548,"depth":353,"text":5551},{"id":5589,"depth":353,"text":5592},{"id":5622,"depth":353,"text":5625},{"id":5647,"depth":353,"text":5650},{"id":5658,"depth":292,"text":5661},{"id":5971,"depth":292,"text":5974},{"id":6032,"depth":292,"text":6035},{"id":6063,"depth":292,"text":6066},"content:blog:on-migration.md","blog/on-migration.md","blog/on-migration",{"loc":5425},{"_path":6120,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":6121,"description":6122,"date":6123,"author":4442,"avatar":4443,"twitter":4444,"excerpt":6124,"body":6130,"_type":1125,"_id":7465,"_source":1127,"_file":7466,"_stem":7467,"_extension":1130,"sitemap":7468},"/blog/volar-1-0","Volar 1.0 \"Nika\" Released!","We are happy to announce that we have released v1.0 of Volar, the official IDE/TS tooling support for Vue! 🎉","2022-10-10",{"type":16,"children":6125},[6126],{"type":19,"tag":20,"props":6127,"children":6128},{},[6129],{"type":24,"value":6122},{"type":16,"children":6131,"toc":7442},[6132,6136,6141,6146,6149,6162,6167,6173,6246,6252,6332,6338,6394,6400,6489,6495,6546,6560,6566,6571,6600,6613,6619,6632,6682,6688,6707,6718,6724,6775,6780,6785,6790,6823,6828,6841,6857,6862,6865,6870,6875,6880,6885,6890,6944,6949,7011,7017,7050,7056,7105,7110,7148,7161,7167,7172,7206,7218,7223,7235,7275,7280,7299,7309,7314,7360,7365,7370,7375,7408,7413,7425,7437],{"type":19,"tag":20,"props":6133,"children":6134},{},[6135],{"type":24,"value":6122},{"type":19,"tag":20,"props":6137,"children":6138},{},[6139],{"type":24,"value":6140},"This major version ships with tons of improvements across the board. In addition to improving UX, performance, and package size, we also released Plugin API v1 and refactored the core code to be framework-agnostic.",{"type":19,"tag":20,"props":6142,"children":6143},{},[6144],{"type":24,"value":6145},"注：結尾附有中文版本 (There is Chinese version of this post at the end)。",{"type":19,"tag":63,"props":6147,"children":6148},{},[],{"type":19,"tag":20,"props":6150,"children":6151},{},[6152,6154,6160],{"type":24,"value":6153},"Earlier this year in March, Vue creator Evan You started sponsoring me (",{"type":19,"tag":51,"props":6155,"children":6158},{"href":6156,"rel":6157,"target":56},"https://twitter.com/johnsoncodehk",[55,55],[6159],{"type":24,"value":4444},{"type":24,"value":6161},") to work full-time on the development of Volar, with the goal of pushing it towards 1.0. After 7 months of hard work, we have finally achieved this goal!",{"type":19,"tag":20,"props":6163,"children":6164},{},[6165],{"type":24,"value":6166},"There are so many updates that you most likely missed some. Below we have summarized the most significant changes from the past 7 months:",{"type":19,"tag":151,"props":6168,"children":6170},{"id":6169},"feature-updates",[6171],{"type":24,"value":6172},"Feature Updates",{"type":19,"tag":89,"props":6174,"children":6175},{},[6176,6196,6207,6220,6225],{"type":19,"tag":83,"props":6177,"children":6178},{},[6179,6181,6187,6188,6194],{"type":24,"value":6180},"Implemented ",{"type":19,"tag":37,"props":6182,"children":6184},{"className":6183},[],[6185],{"type":24,"value":6186},"Goto Code",{"type":24,"value":1384},{"type":19,"tag":37,"props":6189,"children":6191},{"className":6190},[],[6192],{"type":24,"value":6193},"Highlight Selection Dom Elements",{"type":24,"value":6195}," for Vite and Nuxt 3 Preview (highly recommend you try it out!)",{"type":19,"tag":83,"props":6197,"children":6198},{},[6199,6200],{"type":24,"value":6180},{"type":19,"tag":51,"props":6201,"children":6204},{"href":6202,"rel":6203,"target":56},"https://github.com/johnsoncodehk/volar/discussions/1511",[55,55],[6205],{"type":24,"value":6206},"Component Preview",{"type":19,"tag":83,"props":6208,"children":6209},{},[6210,6212,6218],{"type":24,"value":6211},"Added setting ",{"type":19,"tag":37,"props":6213,"children":6215},{"className":6214},[],[6216],{"type":24,"value":6217},"format.initialIndent",{"type":24,"value":6219}," to specify the initial indent of SFC blocks",{"type":19,"tag":83,"props":6221,"children":6222},{},[6223],{"type":24,"value":6224},"Implemented support for Web IDE",{"type":19,"tag":83,"props":6226,"children":6227},{},[6228,6230,6236,6238,6245],{"type":24,"value":6229},"No longer built-in support for ",{"type":19,"tag":37,"props":6231,"children":6233},{"className":6232},[],[6234],{"type":24,"value":6235},"\u003Ctemplate lang=\"pug\">",{"type":24,"value":6237}," (In v1.0 you need to install ",{"type":19,"tag":51,"props":6239,"children":6242},{"href":6240,"rel":6241,"target":56},"https://www.npmjs.com/package/@volar/vue-language-plugin-pug",[55,55],[6243],{"type":24,"value":6244},"@volar/vue-language-plugin-pug",{"type":24,"value":104},{"type":19,"tag":151,"props":6247,"children":6249},{"id":6248},"out-of-the-box-usage-improvements",[6250],{"type":24,"value":6251},"Out-of-the-Box Usage Improvements",{"type":19,"tag":89,"props":6253,"children":6254},{},[6255,6283,6303,6308,6320],{"type":19,"tag":83,"props":6256,"children":6257},{},[6258,6260,6266,6268,6274,6276,6282],{"type":24,"value":6259},"No longer needs ",{"type":19,"tag":37,"props":6261,"children":6263},{"className":6262},[],[6264],{"type":24,"value":6265},"\"jsx\": \"preserve\"",{"type":24,"value":6267}," by default, and also will no longer conflict with ",{"type":19,"tag":37,"props":6269,"children":6271},{"className":6270},[],[6272],{"type":24,"value":6273},"@types/react",{"type":24,"value":6275}," (unless explicitly enabled in ",{"type":19,"tag":37,"props":6277,"children":6279},{"className":6278},[],[6280],{"type":24,"value":6281},"vueCompilerOptions.jsxTemplates",{"type":24,"value":104},{"type":19,"tag":83,"props":6284,"children":6285},{},[6286,6288,6293,6295,6301],{"type":24,"value":6287},"Always wraps component options in ",{"type":19,"tag":37,"props":6289,"children":6291},{"className":6290},[],[6292],{"type":24,"value":2206},{"type":24,"value":6294}," or ",{"type":19,"tag":37,"props":6296,"children":6298},{"className":6297},[],[6299],{"type":24,"value":6300},"Vue.extend",{"type":24,"value":6302}," by default so that you can simply export an object literal.",{"type":19,"tag":83,"props":6304,"children":6305},{},[6306],{"type":24,"value":6307},"Unknown component tags is not in warning color anymore.",{"type":19,"tag":83,"props":6309,"children":6310},{},[6311,6313,6318],{"type":24,"value":6312},"TypeScript support is improved in ",{"type":19,"tag":37,"props":6314,"children":6316},{"className":6315},[],[6317],{"type":24,"value":5677},{"type":24,"value":6319}," block for JS components",{"type":19,"tag":83,"props":6321,"children":6322},{},[6323,6325,6331],{"type":24,"value":6324},"Reduce the need to read the README for new users. Common project setup problems will be automatically detected and prompted in status bar (such as incorrectly setting ",{"type":19,"tag":37,"props":6326,"children":6328},{"className":6327},[],[6329],{"type":24,"value":6330},"vueCompilerOptions.target",{"type":24,"value":104},{"type":19,"tag":151,"props":6333,"children":6335},{"id":6334},"ux-dx-improvements",[6336],{"type":24,"value":6337},"UX / DX Improvements",{"type":19,"tag":89,"props":6339,"children":6340},{},[6341,6346,6367,6379,6384,6389],{"type":19,"tag":83,"props":6342,"children":6343},{},[6344],{"type":24,"value":6345},"Takeover mode no longer shows a pop-up when enabled",{"type":19,"tag":83,"props":6347,"children":6348},{},[6349,6351,6357,6359,6365],{"type":24,"value":6350},"There is a new faster command to use when user needs to restart server: ",{"type":19,"tag":37,"props":6352,"children":6354},{"className":6353},[],[6355],{"type":24,"value":6356},"Reload Project",{"type":24,"value":6358},". This command won't restart the server but will clear the cache. ",{"type":19,"tag":37,"props":6360,"children":6362},{"className":6361},[],[6363],{"type":24,"value":6364},"Restart Vue Server",{"type":24,"value":6366}," is still available to hard-reload the server.",{"type":19,"tag":83,"props":6368,"children":6369},{},[6370,6372,6378],{"type":24,"value":6371},"\"Show Virtual Scripts\" command is added. Check out how it works ",{"type":19,"tag":51,"props":6373,"children":6376},{"href":6374,"rel":6375,"target":56},"https://twitter.com/johnsoncodehk/status/1577046525490126848",[55,55],[6377],{"type":24,"value":6095},{"type":24,"value":61},{"type":19,"tag":83,"props":6380,"children":6381},{},[6382],{"type":24,"value":6383},"Incrementally calculate error range for old diagnostic results to prevent annoying flickering problem",{"type":19,"tag":83,"props":6385,"children":6386},{},[6387],{"type":24,"value":6388},"Added support for adding and switching workspaces without restarting the server",{"type":19,"tag":83,"props":6390,"children":6391},{},[6392],{"type":24,"value":6393},"Simplified display of name casing tool in the status bar, and also supports prop name casing conversion",{"type":19,"tag":151,"props":6395,"children":6397},{"id":6396},"typescript-improvements",[6398],{"type":24,"value":6399},"TypeScript Improvements",{"type":19,"tag":89,"props":6401,"children":6402},{},[6403,6414,6426,6437,6448,6459,6476],{"type":19,"tag":83,"props":6404,"children":6405},{},[6406,6408],{"type":24,"value":6407},"vue-tsc supports ",{"type":19,"tag":37,"props":6409,"children":6411},{"className":6410},[],[6412],{"type":24,"value":6413},"--watch",{"type":19,"tag":83,"props":6415,"children":6416},{},[6417,6418,6424],{"type":24,"value":6407},{"type":19,"tag":37,"props":6419,"children":6421},{"className":6420},[],[6422],{"type":24,"value":6423},"--declaration --emitDeclarationOnly",{"type":24,"value":6425}," to emit dts for components",{"type":19,"tag":83,"props":6427,"children":6428},{},[6429,6431],{"type":24,"value":6430},"Support for ",{"type":19,"tag":37,"props":6432,"children":6434},{"className":6433},[],[6435],{"type":24,"value":6436},"Inlay Hints",{"type":19,"tag":83,"props":6438,"children":6439},{},[6440,6442],{"type":24,"value":6441},"Support ",{"type":19,"tag":37,"props":6443,"children":6445},{"className":6444},[],[6446],{"type":24,"value":6447},"Find File References",{"type":19,"tag":83,"props":6449,"children":6450},{},[6451,6452],{"type":24,"value":6430},{"type":19,"tag":51,"props":6453,"children":6456},{"href":6454,"rel":6455,"target":56},"https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-next",[55,55],[6457],{"type":24,"value":6458},"JavaScript and TypeScript Nightly",{"type":19,"tag":83,"props":6460,"children":6461},{},[6462,6464,6469,6471],{"type":24,"value":6463},"Fixed ",{"type":19,"tag":37,"props":6465,"children":6467},{"className":6466},[],[6468],{"type":24,"value":3789},{"type":24,"value":6470}," types could not be used in ",{"type":19,"tag":37,"props":6472,"children":6474},{"className":6473},[],[6475],{"type":24,"value":5677},{"type":19,"tag":83,"props":6477,"children":6478},{},[6479,6481,6487],{"type":24,"value":6480},"Added ",{"type":19,"tag":37,"props":6482,"children":6484},{"className":6483},[],[6485],{"type":24,"value":6486},"vueCompilerOptions.strictTemplates",{"type":24,"value":6488}," option to support stricter template type checking for report unknown component tag and props",{"type":19,"tag":151,"props":6490,"children":6492},{"id":6491},"performance-improvements",[6493],{"type":24,"value":6494},"Performance Improvements",{"type":19,"tag":89,"props":6496,"children":6497},{},[6498,6503,6521,6526,6531,6536,6541],{"type":19,"tag":83,"props":6499,"children":6500},{},[6501],{"type":24,"value":6502},"Much faster SourceMap mapping",{"type":19,"tag":83,"props":6504,"children":6505},{},[6506,6508,6514,6515],{"type":24,"value":6507},"Implemented incremental update for ",{"type":19,"tag":37,"props":6509,"children":6511},{"className":6510},[],[6512],{"type":24,"value":6513},"SFC AST",{"type":24,"value":1384},{"type":19,"tag":37,"props":6516,"children":6518},{"className":6517},[],[6519],{"type":24,"value":6520},"Template AST",{"type":19,"tag":83,"props":6522,"children":6523},{},[6524],{"type":24,"value":6525},"Template codegen simplified to reduce the memory footprint for each Vue file",{"type":19,"tag":83,"props":6527,"children":6528},{},[6529],{"type":24,"value":6530},"When a Monorepo has multiple TS projects, TS SourceFile instance is reused to reduce memory usage.",{"type":19,"tag":83,"props":6532,"children":6533},{},[6534],{"type":24,"value":6535},"Implemented auto import cache of tsserver in LSP server to speedup autocomplete",{"type":19,"tag":83,"props":6537,"children":6538},{},[6539],{"type":24,"value":6540},"Implemented named pipe base cancellation token of tsserver in LSP server",{"type":19,"tag":83,"props":6542,"children":6543},{},[6544],{"type":24,"value":6545},"Optimized Bundle to reduce the package size, and extension startup faster",{"type":19,"tag":20,"props":6547,"children":6548},{},[6549,6551,6558],{"type":24,"value":6550},"In addition, some performance issues with larger projects may be due to tsconfig including too many unneeded files, we also have a new ",{"type":19,"tag":51,"props":6552,"children":6555},{"href":6553,"rel":6554,"target":56},"https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.vscode-tsconfig-helper",[55,55],[6556],{"type":24,"value":6557},"VSCode plugin",{"type":24,"value":6559}," to check what files your tsconfig contains.",{"type":19,"tag":151,"props":6561,"children":6563},{"id":6562},"generic-language-server-framework",[6564],{"type":24,"value":6565},"Generic Language Server Framework",{"type":19,"tag":20,"props":6567,"children":6568},{},[6569],{"type":24,"value":6570},"Volar core modules is now framework-agnostic, and you can use Volar to implement language servers other than Vue framework.",{"type":19,"tag":20,"props":6572,"children":6573},{},[6574,6576,6583,6585,6591,6592,6598],{"type":24,"value":6575},"In this ",{"type":19,"tag":51,"props":6577,"children":6580},{"href":6578,"rel":6579,"target":56},"https://github.com/johnsoncodehk/volar/tree/master/examples",[55,55],[6581],{"type":24,"value":6582},"example repo",{"type":24,"value":6584},", we have implemented ",{"type":19,"tag":37,"props":6586,"children":6588},{"className":6587},[],[6589],{"type":24,"value":6590},"svelte-tsc",{"type":24,"value":474},{"type":19,"tag":37,"props":6593,"children":6595},{"className":6594},[],[6596],{"type":24,"value":6597},"svelte-langauge-server",{"type":24,"value":6599}," and other examples based on svelte2tsx.",{"type":19,"tag":20,"props":6601,"children":6602},{},[6603,6605,6611],{"type":24,"value":6604},"There is also a ",{"type":19,"tag":37,"props":6606,"children":6608},{"className":6607},[],[6609],{"type":24,"value":6610},"vue-and-svelte-language-server",{"type":24,"value":6612}," example, which supports both Vue and Svelte in a single Language Server, avoiding the establishment of multiple Language Servers to establish expensive TypeScript LanguageService instances. It may helpful for framework like Astro which supports multiple languages.",{"type":19,"tag":151,"props":6614,"children":6616},{"id":6615},"vuelanguageplugin-api",[6617],{"type":24,"value":6618},"VueLanguagePlugin API",{"type":19,"tag":20,"props":6620,"children":6621},{},[6622,6624,6630],{"type":24,"value":6623},"Now supported ",{"type":19,"tag":37,"props":6625,"children":6627},{"className":6626},[],[6628],{"type":24,"value":6629},"vueCompilerOptions.plugins",{"type":24,"value":6631}," option to specify additional plugins to alter virtual code generation.",{"type":19,"tag":20,"props":6633,"children":6634},{},[6635,6637,6643,6645,6651,6653,6659,6660,6665,6667,6672,6674,6680],{"type":24,"value":6636},"The codegen API of ",{"type":19,"tag":37,"props":6638,"children":6640},{"className":6639},[],[6641],{"type":24,"value":6642},"VueLanguagePlugin",{"type":24,"value":6644}," uses ",{"type":19,"tag":37,"props":6646,"children":6648},{"className":6647},[],[6649],{"type":24,"value":6650},"muggle-string",{"type":24,"value":6652}," instead of ",{"type":19,"tag":37,"props":6654,"children":6656},{"className":6655},[],[6657],{"type":24,"value":6658},"magic-string",{"type":24,"value":474},{"type":19,"tag":37,"props":6661,"children":6663},{"className":6662},[],[6664],{"type":24,"value":6650},{"type":24,"value":6666}," is still lacking major features in earlier versions, but it is decoupled from Volar so it can be developed independently, if you need to develop in ",{"type":19,"tag":37,"props":6668,"children":6670},{"className":6669},[],[6671],{"type":24,"value":6642},{"type":24,"value":6673},", please track for ",{"type":19,"tag":51,"props":6675,"children":6678},{"href":6676,"rel":6677,"target":56},"https://github.com/johnsoncodehk/muggle-string",[55,55],[6679],{"type":24,"value":6676},{"type":24,"value":6681}," update.",{"type":19,"tag":151,"props":6683,"children":6685},{"id":6684},"languageserviceplugin-api",[6686],{"type":24,"value":6687},"LanguageServicePlugin API",{"type":19,"tag":20,"props":6689,"children":6690},{},[6691,6693,6698,6700,6705],{"type":24,"value":6692},"You can setup plugin to ",{"type":19,"tag":37,"props":6694,"children":6696},{"className":6695},[],[6697],{"type":24,"value":4682},{"type":24,"value":6699}," to change the language server behavior, for example you can change the formatter used by ",{"type":19,"tag":37,"props":6701,"children":6703},{"className":6702},[],[6704],{"type":24,"value":5677},{"type":24,"value":6706}," to Prettier.",{"type":19,"tag":20,"props":6708,"children":6709},{},[6710,6712],{"type":24,"value":6711},"We have a single repo for maintaining common plugins: ",{"type":19,"tag":51,"props":6713,"children":6716},{"href":6714,"rel":6715,"target":56},"https://github.com/johnsoncodehk/volar-plugins",[55,55],[6717],{"type":24,"value":6714},{"type":19,"tag":151,"props":6719,"children":6721},{"id":6720},"external-tools-support",[6722],{"type":24,"value":6723},"External Tools Support",{"type":19,"tag":89,"props":6725,"children":6726},{},[6727,6744,6763],{"type":19,"tag":83,"props":6728,"children":6729},{},[6730,6736,6738],{"type":19,"tag":37,"props":6731,"children":6733},{"className":6732},[],[6734],{"type":24,"value":6735},"@volar/vue-typescript",{"type":24,"value":6737}," exposed organizeImports API for ",{"type":19,"tag":37,"props":6739,"children":6741},{"className":6740},[],[6742],{"type":24,"value":6743},"prettier-plugin-organize-imports",{"type":19,"tag":83,"props":6745,"children":6746},{},[6747,6753,6755,6761],{"type":19,"tag":37,"props":6748,"children":6750},{"className":6749},[],[6751],{"type":24,"value":6752},"@volar/vue-language-core",{"type":24,"value":6754}," exposed ",{"type":19,"tag":37,"props":6756,"children":6758},{"className":6757},[],[6759],{"type":24,"value":6760},"vue-tsconfig.schema.json",{"type":24,"value":6762}," for IDEs other than VSCode",{"type":19,"tag":83,"props":6764,"children":6765},{},[6766,6767,6773],{"type":24,"value":6180},{"type":19,"tag":37,"props":6768,"children":6770},{"className":6769},[],[6771],{"type":24,"value":6772},"vue-component-meta",{"type":24,"value":6774}," for UI Library documentation generation",{"type":19,"tag":72,"props":6776,"children":6777},{"id":1233},[6778],{"type":24,"value":6779},"What's Next",{"type":19,"tag":20,"props":6781,"children":6782},{},[6783],{"type":24,"value":6784},"Volar has been developed for more than two years so far. The development cost is huge for it just a VSCode plugin at beginning, and its project scope may also frighten some people who planned to make tools for other languages, so I hope to improve the core framework in v2.0 to make it easier for other languages that need to implement tooling to take advantage of the efforts made by Volar.",{"type":19,"tag":20,"props":6786,"children":6787},{},[6788],{"type":24,"value":6789},"In addition there are some other things planned to do:",{"type":19,"tag":89,"props":6791,"children":6792},{},[6793,6798,6803,6808,6813,6818],{"type":19,"tag":83,"props":6794,"children":6795},{},[6796],{"type":24,"value":6797},"Documentation website",{"type":19,"tag":83,"props":6799,"children":6800},{},[6801],{"type":24,"value":6802},"Improve the bug report process",{"type":19,"tag":83,"props":6804,"children":6805},{},[6806],{"type":24,"value":6807},"Support global installation of LangaugeServicePlugin",{"type":19,"tag":83,"props":6809,"children":6810},{},[6811],{"type":24,"value":6812},"Bun base Language Server",{"type":19,"tag":83,"props":6814,"children":6815},{},[6816],{"type":24,"value":6817},"Incremental update template codegen",{"type":19,"tag":83,"props":6819,"children":6820},{},[6821],{"type":24,"value":6822},"Explore performance improvements in TypeScript and LSP source code",{"type":19,"tag":20,"props":6824,"children":6825},{},[6826],{"type":24,"value":6827},"After v1.0 is released I will go back to working full time and starting some other personal projects, while continuing to work on these in my spare time.",{"type":19,"tag":20,"props":6829,"children":6830},{},[6831,6833,6839],{"type":24,"value":6832},"I also want to give a big shout out to ",{"type":19,"tag":51,"props":6834,"children":6837},{"href":6835,"rel":6836,"target":56},"https://nuxtjs.org/",[55,55],[6838],{"type":24,"value":4983},{"type":24,"value":6840},", who have been Platinum Sponsor since May, and all my other sponsors 🙌. Your support ensures that I will be able to continue maintaining Volar after 1.0 to improve your Vue development experience!",{"type":19,"tag":20,"props":6842,"children":6844},{"align":6843},"center",[6845,6847],{"type":24,"value":6846},"\n\t",{"type":19,"tag":51,"props":6848,"children":6850},{"href":6849},"https://cdn.jsdelivr.net/gh/johnsoncodehk/sponsors/sponsors.svg",[6851,6853,6856],{"type":24,"value":6852},"\n\t\t",{"type":19,"tag":642,"props":6854,"children":6855},{"src":6849},[],{"type":24,"value":6846},{"type":19,"tag":20,"props":6858,"children":6859},{},[6860],{"type":24,"value":6861},"Thank you for reading this blog!",{"type":19,"tag":63,"props":6863,"children":6864},{},[],{"type":19,"tag":20,"props":6866,"children":6867},{},[6868],{"type":24,"value":6869},"很高興宣布在今天完成了所有主要功能並發佈了 v1.0 版本。🎉",{"type":19,"tag":20,"props":6871,"children":6872},{},[6873],{"type":24,"value":6874},"這個主要版本全方面改進了工具，除了改進 UX、性能、包大小，我們還發佈了 Plugin API v1，以及重構了架構使核心代碼與框架無關。",{"type":19,"tag":20,"props":6876,"children":6877},{},[6878],{"type":24,"value":6879},"今年初我與 Vue 的作者 Evan 達成協議，他在 3 月開始資助我全職開發 Volar 直至完成 1.0 版本，經過 7 個月的努力我們終於做到了這個目標！",{"type":19,"tag":20,"props":6881,"children":6882},{},[6883],{"type":24,"value":6884},"如果你沒有追蹤每個版本的 changelog，你可能不知道發生了什麼，我會簡單總結在這半年間對你較有明顯影響的更改：",{"type":19,"tag":151,"props":6886,"children":6888},{"id":6887},"功能更新",[6889],{"type":24,"value":6887},{"type":19,"tag":89,"props":6891,"children":6892},{},[6893,6898,6908,6920,6925],{"type":19,"tag":83,"props":6894,"children":6895},{},[6896],{"type":24,"value":6897},"為 Vite 和 Nuxt 3 Preview 實現了 Goto Code 和 Highlight Selection Dom Elements（非常推薦你試一試！）",{"type":19,"tag":83,"props":6899,"children":6900},{},[6901,6903],{"type":24,"value":6902},"實現了 ",{"type":19,"tag":51,"props":6904,"children":6906},{"href":6202,"rel":6905,"target":56},[55,55],[6907],{"type":24,"value":6206},{"type":19,"tag":83,"props":6909,"children":6910},{},[6911,6913,6918],{"type":24,"value":6912},"新增 ",{"type":19,"tag":37,"props":6914,"children":6916},{"className":6915},[],[6917],{"type":24,"value":6217},{"type":24,"value":6919}," 設置以指定 SFC blocks 的初始縮進",{"type":19,"tag":83,"props":6921,"children":6922},{},[6923],{"type":24,"value":6924},"實現了 Web IDE 支持",{"type":19,"tag":83,"props":6926,"children":6927},{},[6928,6930,6935,6937,6942],{"type":24,"value":6929},"不再內置支持 ",{"type":19,"tag":37,"props":6931,"children":6933},{"className":6932},[],[6934],{"type":24,"value":6235},{"type":24,"value":6936},"（在 v1.0 需要安裝",{"type":19,"tag":51,"props":6938,"children":6940},{"href":6240,"rel":6939,"target":56},[55,55],[6941],{"type":24,"value":6244},{"type":24,"value":6943},"）",{"type":19,"tag":151,"props":6945,"children":6947},{"id":6946},"開箱即用改進",[6948],{"type":24,"value":6946},{"type":19,"tag":89,"props":6950,"children":6951},{},[6952,6977,6989,6994,6999],{"type":19,"tag":83,"props":6953,"children":6954},{},[6955,6957,6962,6964,6969,6971,6976],{"type":24,"value":6956},"預設不再需要 ",{"type":19,"tag":37,"props":6958,"children":6960},{"className":6959},[],[6961],{"type":24,"value":6265},{"type":24,"value":6963},"，並且不會與 ",{"type":19,"tag":37,"props":6965,"children":6967},{"className":6966},[],[6968],{"type":24,"value":6273},{"type":24,"value":6970}," 衝突（除非明確啟用 ",{"type":19,"tag":37,"props":6972,"children":6974},{"className":6973},[],[6975],{"type":24,"value":6281},{"type":24,"value":6943},{"type":19,"tag":83,"props":6978,"children":6979},{},[6980,6982,6987],{"type":24,"value":6981},"預設總是以 ",{"type":19,"tag":37,"props":6983,"children":6985},{"className":6984},[],[6986],{"type":24,"value":2206},{"type":24,"value":6988}," 包裝 Component Options",{"type":19,"tag":83,"props":6990,"children":6991},{},[6992],{"type":24,"value":6993},"不再以警告色顯示未知 Component Tag",{"type":19,"tag":83,"props":6995,"children":6996},{},[6997],{"type":24,"value":6998},"改進 JS 組件中的 Template TypeScript 支持",{"type":19,"tag":83,"props":7000,"children":7001},{},[7002,7004,7009],{"type":24,"value":7003},"減少對閱讀 README 的依賴，現在會自動檢測常見的項目設置問題（例如錯誤地設置 ",{"type":19,"tag":37,"props":7005,"children":7007},{"className":7006},[],[7008],{"type":24,"value":6330},{"type":24,"value":7010},"），發現問題時會在狀態欄提示",{"type":19,"tag":151,"props":7012,"children":7014},{"id":7013},"ux-dx-改進",[7015],{"type":24,"value":7016},"UX / DX 改進",{"type":19,"tag":89,"props":7018,"children":7019},{},[7020,7025,7030,7035,7040,7045],{"type":19,"tag":83,"props":7021,"children":7022},{},[7023],{"type":24,"value":7024},"啟用 Takeover mode 不再彈出提示",{"type":19,"tag":83,"props":7026,"children":7027},{},[7028],{"type":24,"value":7029},"更快的 \"Reload Project\" 命令代替 \"Restart Vue server\"",{"type":19,"tag":83,"props":7031,"children":7032},{},[7033],{"type":24,"value":7034},"新的 \"Show Virtual Scripts\" 命令代替 \"Write Virtual Files\"",{"type":19,"tag":83,"props":7036,"children":7037},{},[7038],{"type":24,"value":7039},"增量更新過去的診斷結果防止煩人的閃爍問題",{"type":19,"tag":83,"props":7041,"children":7042},{},[7043],{"type":24,"value":7044},"支持在不重啟服務器的情況下添加或切換工作區",{"type":19,"tag":83,"props":7046,"children":7047},{},[7048],{"type":24,"value":7049},"簡化 Name casing tool 在狀態欄的顯示方式，並且現在也支持 Prop name casing 轉換",{"type":19,"tag":151,"props":7051,"children":7053},{"id":7052},"typescript-改進",[7054],{"type":24,"value":7055},"TypeScript 改進",{"type":19,"tag":89,"props":7057,"children":7058},{},[7059,7070,7075,7080,7089,7094],{"type":19,"tag":83,"props":7060,"children":7061},{},[7062,7064],{"type":24,"value":7063},"支持了 ",{"type":19,"tag":37,"props":7065,"children":7067},{"className":7066},[],[7068],{"type":24,"value":7069},"vue-tsc --watch",{"type":19,"tag":83,"props":7071,"children":7072},{},[7073],{"type":24,"value":7074},"支持了 Inlay Hints",{"type":19,"tag":83,"props":7076,"children":7077},{},[7078],{"type":24,"value":7079},"支持 Find File References",{"type":19,"tag":83,"props":7081,"children":7082},{},[7083,7084],{"type":24,"value":7063},{"type":19,"tag":51,"props":7085,"children":7087},{"href":6454,"rel":7086,"target":56},[55,55],[7088],{"type":24,"value":6458},{"type":19,"tag":83,"props":7090,"children":7091},{},[7092],{"type":24,"value":7093},"解決了無法在 Template 引用類型的問題",{"type":19,"tag":83,"props":7095,"children":7096},{},[7097,7098,7103],{"type":24,"value":6912},{"type":19,"tag":37,"props":7099,"children":7101},{"className":7100},[],[7102],{"type":24,"value":6486},{"type":24,"value":7104}," 選項支持更嚴格的 Template type checking，在使用未知的 Component Tag 和 Props 時報告錯誤",{"type":19,"tag":151,"props":7106,"children":7108},{"id":7107},"性能改進",[7109],{"type":24,"value":7107},{"type":19,"tag":89,"props":7111,"children":7112},{},[7113,7118,7123,7128,7133,7138,7143],{"type":19,"tag":83,"props":7114,"children":7115},{},[7116],{"type":24,"value":7117},"大量改善 SourceMap mapping 性能",{"type":19,"tag":83,"props":7119,"children":7120},{},[7121],{"type":24,"value":7122},"實現 SFC AST 和 Template AST 的增量更新",{"type":19,"tag":83,"props":7124,"children":7125},{},[7126],{"type":24,"value":7127},"簡化 Template 生成的代碼以降低了每個 Vue 文件產生的內存佔用",{"type":19,"tag":83,"props":7129,"children":7130},{},[7131],{"type":24,"value":7132},"為 Monorepo 多個 TS project 共用 TS SourceFile 實例",{"type":19,"tag":83,"props":7134,"children":7135},{},[7136],{"type":24,"value":7137},"移植了 tsserver 自動導入的緩存邏輯加快自動完成",{"type":19,"tag":83,"props":7139,"children":7140},{},[7141],{"type":24,"value":7142},"移植了 tsserver 基於 Named Pipe 的 Cancellation Token 實現以解決了 LSP 請求阻塞",{"type":19,"tag":83,"props":7144,"children":7145},{},[7146],{"type":24,"value":7147},"優化 Bundle 降低包大小，並且插件啟動速度更快",{"type":19,"tag":20,"props":7149,"children":7150},{},[7151,7153,7159],{"type":24,"value":7152},"另外一些大型項目的性能問題可能是由於 tsconfig 包含了太多不需要的文件，我們還有一個新的",{"type":19,"tag":51,"props":7154,"children":7156},{"href":6553,"rel":7155,"target":56},[55,55],[7157],{"type":24,"value":7158},"VSCode 插件",{"type":24,"value":7160},"用來檢查你的 tsconfig 包含的文件。",{"type":19,"tag":151,"props":7162,"children":7164},{"id":7163},"通用的-language-server-框架",[7165],{"type":24,"value":7166},"通用的 Language Server 框架",{"type":19,"tag":20,"props":7168,"children":7169},{},[7170],{"type":24,"value":7171},"Volar 的核心代碼現在與框架無關，你可以使用 Volar 為 Vue 以外的語言實現語言服務器。",{"type":19,"tag":20,"props":7173,"children":7174},{},[7175,7177,7183,7185,7191,7193,7198,7199,7204],{"type":24,"value":7176},"在 repo 的 ",{"type":19,"tag":51,"props":7178,"children":7180},{"href":6578,"rel":7179,"target":56},[55,55],[7181],{"type":24,"value":7182},"examples 目錄",{"type":24,"value":7184},"，我們基於 ",{"type":19,"tag":37,"props":7186,"children":7188},{"className":7187},[],[7189],{"type":24,"value":7190},"svelte2tsx",{"type":24,"value":7192}," 分別實現了 ",{"type":19,"tag":37,"props":7194,"children":7196},{"className":7195},[],[7197],{"type":24,"value":6590},{"type":24,"value":474},{"type":19,"tag":37,"props":7200,"children":7202},{"className":7201},[],[7203],{"type":24,"value":6597},{"type":24,"value":7205}," 等等示例。",{"type":19,"tag":20,"props":7207,"children":7208},{},[7209,7211,7216],{"type":24,"value":7210},"目錄中還有一個 ",{"type":19,"tag":37,"props":7212,"children":7214},{"className":7213},[],[7215],{"type":24,"value":6610},{"type":24,"value":7217}," 示例，在單個 Language Server 同時支持 Vue 和 Svelte，避免多個 Language Server 建立分別建立昂貴的 TypeScript LanguageService 實例，對於像 Astro 同時支持多個前端框架的項目可能很有用。",{"type":19,"tag":151,"props":7219,"children":7221},{"id":7220},"vuelanguageplugin-api-1",[7222],{"type":24,"value":6618},{"type":19,"tag":20,"props":7224,"children":7225},{},[7226,7228,7233],{"type":24,"value":7227},"現在支持 ",{"type":19,"tag":37,"props":7229,"children":7231},{"className":7230},[],[7232],{"type":24,"value":6629},{"type":24,"value":7234}," 選項指定額外 plugin 來更改 virtual code 的生成方式。",{"type":19,"tag":20,"props":7236,"children":7237},{},[7238,7240,7245,7247,7252,7254,7259,7261,7266,7268,7273],{"type":24,"value":7239},"VueLanguagePlugin 的 codegen API 使用 ",{"type":19,"tag":37,"props":7241,"children":7243},{"className":7242},[],[7244],{"type":24,"value":6650},{"type":24,"value":7246}," 而不是 ",{"type":19,"tag":37,"props":7248,"children":7250},{"className":7249},[],[7251],{"type":24,"value":6658},{"type":24,"value":7253},"，",{"type":19,"tag":37,"props":7255,"children":7257},{"className":7256},[],[7258],{"type":24,"value":6650},{"type":24,"value":7260}," 仍然是早期版本缺乏主要功能，但是與 Volar 解耦因此可以獨立發展，如果你需要開發 ",{"type":19,"tag":37,"props":7262,"children":7264},{"className":7263},[],[7265],{"type":24,"value":6642},{"type":24,"value":7267}," 請關注 ",{"type":19,"tag":51,"props":7269,"children":7271},{"href":6676,"rel":7270,"target":56},[55,55],[7272],{"type":24,"value":6676},{"type":24,"value":7274}," 更新。",{"type":19,"tag":151,"props":7276,"children":7278},{"id":7277},"languageserviceplugin-api-1",[7279],{"type":24,"value":6687},{"type":19,"tag":20,"props":7281,"children":7282},{},[7283,7285,7290,7292,7297],{"type":24,"value":7284},"你可以在 ",{"type":19,"tag":37,"props":7286,"children":7288},{"className":7287},[],[7289],{"type":24,"value":4682},{"type":24,"value":7291}," 添加 plugin 來更改 language server 的行為，例如將 ",{"type":19,"tag":37,"props":7293,"children":7295},{"className":7294},[],[7296],{"type":24,"value":5677},{"type":24,"value":7298}," 使用的 formatter 改為 Prettier。",{"type":19,"tag":20,"props":7300,"children":7301},{},[7302,7304],{"type":24,"value":7303},"我們有一個單獨的 repo 用來維護常用的 plugins: ",{"type":19,"tag":51,"props":7305,"children":7307},{"href":6714,"rel":7306,"target":56},[55,55],[7308],{"type":24,"value":6714},{"type":19,"tag":151,"props":7310,"children":7312},{"id":7311},"外部工具支持",[7313],{"type":24,"value":7311},{"type":19,"tag":89,"props":7315,"children":7316},{},[7317,7334,7349],{"type":19,"tag":83,"props":7318,"children":7319},{},[7320,7325,7327,7332],{"type":19,"tag":37,"props":7321,"children":7323},{"className":7322},[],[7324],{"type":24,"value":6735},{"type":24,"value":7326}," 為 ",{"type":19,"tag":37,"props":7328,"children":7330},{"className":7329},[],[7331],{"type":24,"value":6743},{"type":24,"value":7333}," 公開了 organizeImports API",{"type":19,"tag":83,"props":7335,"children":7336},{},[7337,7342,7344],{"type":19,"tag":37,"props":7338,"children":7340},{"className":7339},[],[7341],{"type":24,"value":6752},{"type":24,"value":7343}," 為 VSCode 以外的 IDE 公開了 ",{"type":19,"tag":37,"props":7345,"children":7347},{"className":7346},[],[7348],{"type":24,"value":6760},{"type":19,"tag":83,"props":7350,"children":7351},{},[7352,7353,7358],{"type":24,"value":6902},{"type":19,"tag":37,"props":7354,"children":7356},{"className":7355},[],[7357],{"type":24,"value":6772},{"type":24,"value":7359}," 用於 UI Library 文檔生成",{"type":19,"tag":72,"props":7361,"children":7363},{"id":7362},"whats-next-1",[7364],{"type":24,"value":6779},{"type":19,"tag":20,"props":7366,"children":7367},{},[7368],{"type":24,"value":7369},"Volar 至今開發了兩年多時間，對於原本只是一個 VSCode Plugin 來說投入的開發成本是巨大的，同時它的項目 scope 也可能嚇怕一些原本打算為語言實現 Tooling 的人，因此我希望在 v2.0 改進核心框架，讓其他需要實現 Tooling 的語言更容易地利用 Volar 所做的努力。",{"type":19,"tag":20,"props":7371,"children":7372},{},[7373],{"type":24,"value":7374},"此外還有一些計劃做的事情：",{"type":19,"tag":89,"props":7376,"children":7377},{},[7378,7383,7388,7393,7398,7403],{"type":19,"tag":83,"props":7379,"children":7380},{},[7381],{"type":24,"value":7382},"文檔網站",{"type":19,"tag":83,"props":7384,"children":7385},{},[7386],{"type":24,"value":7387},"改進 Bug report 流程",{"type":19,"tag":83,"props":7389,"children":7390},{},[7391],{"type":24,"value":7392},"支持全局安裝 LangaugeServicePlugin",{"type":19,"tag":83,"props":7394,"children":7395},{},[7396],{"type":24,"value":7397},"基於 Bun 的 Language Server",{"type":19,"tag":83,"props":7399,"children":7400},{},[7401],{"type":24,"value":7402},"增量更新 template codegen",{"type":19,"tag":83,"props":7404,"children":7405},{},[7406],{"type":24,"value":7407},"探索 TypeScript 和 LSP 源代碼中的性能改進",{"type":19,"tag":20,"props":7409,"children":7410},{},[7411],{"type":24,"value":7412},"發佈 v1.0 之後我將會回到全職工作和開始一些其他個人項目，同時在業餘時間繼續做這些工作。",{"type":19,"tag":20,"props":7414,"children":7415},{},[7416,7418,7423],{"type":24,"value":7417},"我想為從五月開始成為 Platinum Sponsor 的 ",{"type":19,"tag":51,"props":7419,"children":7421},{"href":6835,"rel":7420,"target":56},[55,55],[7422],{"type":24,"value":4983},{"type":24,"value":7424}," 以及所有贊助者大聲呼喊 🙌，這很大程度地保證了我在完成 1.0 之後仍然能夠繼續維護 Volar 以改善你的 Vue 開發體驗！",{"type":19,"tag":20,"props":7426,"children":7427},{"align":6843},[7428,7429],{"type":24,"value":6846},{"type":19,"tag":51,"props":7430,"children":7431},{"href":6849},[7432,7433,7436],{"type":24,"value":6852},{"type":19,"tag":642,"props":7434,"children":7435},{"src":6849},[],{"type":24,"value":6846},{"type":19,"tag":20,"props":7438,"children":7439},{},[7440],{"type":24,"value":7441},"感謝你閱讀這篇文章！",{"title":8,"searchDepth":292,"depth":292,"links":7443},[7444,7445,7446,7447,7448,7449,7450,7451,7452,7453,7464],{"id":6169,"depth":353,"text":6172},{"id":6248,"depth":353,"text":6251},{"id":6334,"depth":353,"text":6337},{"id":6396,"depth":353,"text":6399},{"id":6491,"depth":353,"text":6494},{"id":6562,"depth":353,"text":6565},{"id":6615,"depth":353,"text":6618},{"id":6684,"depth":353,"text":6687},{"id":6720,"depth":353,"text":6723},{"id":1233,"depth":292,"text":6779,"children":7454},[7455,7456,7457,7458,7459,7460,7461,7462,7463],{"id":6887,"depth":353,"text":6887},{"id":6946,"depth":353,"text":6946},{"id":7013,"depth":353,"text":7016},{"id":7052,"depth":353,"text":7055},{"id":7107,"depth":353,"text":7107},{"id":7163,"depth":353,"text":7166},{"id":7220,"depth":353,"text":6618},{"id":7277,"depth":353,"text":6687},{"id":7311,"depth":353,"text":7311},{"id":7362,"depth":292,"text":6779},"content:blog:volar-1-0.md","blog/volar-1-0.md","blog/volar-1-0",{"loc":6120},{"_path":5190,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":7470,"description":7471,"date":7472,"author":12,"gravatar":13,"twitter":14,"excerpt":7473,"body":7491,"_type":1125,"_id":8486,"_source":1127,"_file":8487,"_stem":8488,"_extension":1130,"sitemap":8489},"Vue 2.7 \"Naruto\" Released","\n  ","2022-07-01",{"type":16,"children":7474},[7475,7486],{"type":19,"tag":20,"props":7476,"children":7477},{"align":6843},[7478,7479],{"type":24,"value":7471},{"type":19,"tag":642,"props":7480,"children":7485},{"width":7481,"height":7482,"src":7483,"alt":7484},300,"128px","https://user-images.githubusercontent.com/499550/176823239-f59d75de-1d24-4b2d-b04b-fcc95db2903e.png","naruto-vue-logo",[],{"type":19,"tag":20,"props":7487,"children":7488},{},[7489],{"type":24,"value":7490},"Today we are happy to announce that Vue 2.7 \"Naruto\" has been released!",{"type":16,"children":7492,"toc":8472},[7493,7500,7504,7507,7512,7518,7557,7562,7663,7669,7751,7757,7762,7876,7888,7959,7965,7971,8184,8189,8211,8224,8230,8249,8342,8348,8353,8359,8370,8382,8388,8410,8415,8468],{"type":19,"tag":20,"props":7494,"children":7495},{"align":6843},[7496,7497],{"type":24,"value":7471},{"type":19,"tag":642,"props":7498,"children":7499},{"width":7481,"height":7482,"src":7483,"alt":7484},[],{"type":19,"tag":20,"props":7501,"children":7502},{},[7503],{"type":24,"value":7490},{"type":19,"tag":63,"props":7505,"children":7506},{},[],{"type":19,"tag":20,"props":7508,"children":7509},{},[7510],{"type":24,"value":7511},"Despite Vue 3 now being the default version, we understand that there are still many users who have to stay on Vue 2 due to dependency compatibility, browser support requirements, or simply not enough bandwidth to upgrade. In Vue 2.7, we have backported some of the most important features from Vue 3 so that Vue 2 users can benefit from them as well.",{"type":19,"tag":72,"props":7513,"children":7515},{"id":7514},"backported-features",[7516],{"type":24,"value":7517},"Backported Features",{"type":19,"tag":89,"props":7519,"children":7520},{},[7521,7531,7546],{"type":19,"tag":83,"props":7522,"children":7523},{},[7524],{"type":19,"tag":51,"props":7525,"children":7528},{"href":7526,"rel":7527,"target":56},"https://vuejs.org/guide/extras/composition-api-faq.html",[55,55],[7529],{"type":24,"value":7530},"Composition API",{"type":19,"tag":83,"props":7532,"children":7533},{},[7534,7536],{"type":24,"value":7535},"SFC ",{"type":19,"tag":51,"props":7537,"children":7540},{"href":7538,"rel":7539,"target":56},"https://vuejs.org/api/sfc-script-setup.html",[55,55],[7541],{"type":19,"tag":37,"props":7542,"children":7544},{"className":7543},[],[7545],{"type":24,"value":544},{"type":19,"tag":83,"props":7547,"children":7548},{},[7549,7550],{"type":24,"value":7535},{"type":19,"tag":51,"props":7551,"children":7554},{"href":7552,"rel":7553,"target":56},"https://vuejs.org/api/sfc-css-features.html#v-bind-in-css",[55,55],[7555],{"type":24,"value":7556},"CSS v-bind",{"type":19,"tag":20,"props":7558,"children":7559},{},[7560],{"type":24,"value":7561},"In addition, the following APIs are also supported:",{"type":19,"tag":89,"props":7563,"children":7564},{},[7565,7581,7611,7636],{"type":19,"tag":83,"props":7566,"children":7567},{},[7568,7573,7575,7580],{"type":19,"tag":37,"props":7569,"children":7571},{"className":7570},[],[7572],{"type":24,"value":2206},{"type":24,"value":7574}," with improved type inference (compared to ",{"type":19,"tag":37,"props":7576,"children":7578},{"className":7577},[],[7579],{"type":24,"value":6300},{"type":24,"value":104},{"type":19,"tag":83,"props":7582,"children":7583},{},[7584,7590,7591,7597,7598,7604,7605],{"type":19,"tag":37,"props":7585,"children":7587},{"className":7586},[],[7588],{"type":24,"value":7589},"h()",{"type":24,"value":474},{"type":19,"tag":37,"props":7592,"children":7594},{"className":7593},[],[7595],{"type":24,"value":7596},"useSlot()",{"type":24,"value":474},{"type":19,"tag":37,"props":7599,"children":7601},{"className":7600},[],[7602],{"type":24,"value":7603},"useAttrs()",{"type":24,"value":474},{"type":19,"tag":37,"props":7606,"children":7608},{"className":7607},[],[7609],{"type":24,"value":7610},"useCssModules()",{"type":19,"tag":83,"props":7612,"children":7613},{},[7614,7620,7621,7627,7628,7634],{"type":19,"tag":37,"props":7615,"children":7617},{"className":7616},[],[7618],{"type":24,"value":7619},"set()",{"type":24,"value":474},{"type":19,"tag":37,"props":7622,"children":7624},{"className":7623},[],[7625],{"type":24,"value":7626},"del()",{"type":24,"value":1384},{"type":19,"tag":37,"props":7629,"children":7631},{"className":7630},[],[7632],{"type":24,"value":7633},"nextTick()",{"type":24,"value":7635}," are also provided as named exports in ESM builds.",{"type":19,"tag":83,"props":7637,"children":7638},{},[7639,7641,7647,7649,7653,7655,7661],{"type":24,"value":7640},"The ",{"type":19,"tag":37,"props":7642,"children":7644},{"className":7643},[],[7645],{"type":24,"value":7646},"emits",{"type":24,"value":7648}," option is also supported, but only for type-checking purposes (does not affect runtime behavior)",{"type":19,"tag":7650,"props":7651,"children":7652},"br",{},[],{"type":24,"value":7654},"2.7 also supports using ESNext syntax in template expressions. When using a build system, the compiled template render function will go through the same loaders / plugins configured for normal JavaScript. This means if you have configured Babel for ",{"type":19,"tag":37,"props":7656,"children":7658},{"className":7657},[],[7659],{"type":24,"value":7660},".js",{"type":24,"value":7662}," files, it will also apply to the expressions in your SFC templates.",{"type":19,"tag":151,"props":7664,"children":7666},{"id":7665},"notes-on-api-exposure",[7667],{"type":24,"value":7668},"Notes on API exposure",{"type":19,"tag":89,"props":7670,"children":7671},{},[7672,7733,7746],{"type":19,"tag":83,"props":7673,"children":7674},{},[7675,7677],{"type":24,"value":7676},"In ESM builds, these APIs are provided as named exports (and named exports only):",{"type":19,"tag":236,"props":7678,"children":7680},{"className":238,"code":7679,"language":240,"meta":8,"style":8},"import Vue, { ref } from 'vue'\n\nVue.ref // undefined, use named export instead\n",[7681],{"type":19,"tag":37,"props":7682,"children":7683},{"__ignoreMap":8},[7684,7713,7720],{"type":19,"tag":246,"props":7685,"children":7686},{"class":248,"line":249},[7687,7692,7697,7701,7705,7709],{"type":19,"tag":246,"props":7688,"children":7689},{"style":253},[7690],{"type":24,"value":7691},"import",{"type":19,"tag":246,"props":7693,"children":7694},{"style":259},[7695],{"type":24,"value":7696}," Vue, { ref } ",{"type":19,"tag":246,"props":7698,"children":7699},{"style":253},[7700],{"type":24,"value":1654},{"type":19,"tag":246,"props":7702,"children":7703},{"style":660},[7704],{"type":24,"value":1659},{"type":19,"tag":246,"props":7706,"children":7707},{"style":1619},[7708],{"type":24,"value":625},{"type":19,"tag":246,"props":7710,"children":7711},{"style":660},[7712],{"type":24,"value":1669},{"type":19,"tag":246,"props":7714,"children":7715},{"class":248,"line":292},[7716],{"type":19,"tag":246,"props":7717,"children":7718},{"emptyLinePlaceholder":357},[7719],{"type":24,"value":360},{"type":19,"tag":246,"props":7721,"children":7722},{"class":248,"line":353},[7723,7728],{"type":19,"tag":246,"props":7724,"children":7725},{"style":259},[7726],{"type":24,"value":7727},"Vue.ref ",{"type":19,"tag":246,"props":7729,"children":7730},{"style":395},[7731],{"type":24,"value":7732},"// undefined, use named export instead\n",{"type":19,"tag":83,"props":7734,"children":7735},{},[7736,7738,7744],{"type":24,"value":7737},"In UMD and CJS builds, these APIs are exposed as properties on the global ",{"type":19,"tag":37,"props":7739,"children":7741},{"className":7740},[],[7742],{"type":24,"value":7743},"Vue",{"type":24,"value":7745}," object.",{"type":19,"tag":83,"props":7747,"children":7748},{},[7749],{"type":24,"value":7750},"When bundling with CJS builds externalized, bundlers should be able to handle ESM interop when externalizing CJS builds.",{"type":19,"tag":151,"props":7752,"children":7754},{"id":7753},"behavior-differences-from-vue-3",[7755],{"type":24,"value":7756},"Behavior Differences from Vue 3",{"type":19,"tag":20,"props":7758,"children":7759},{},[7760],{"type":24,"value":7761},"The Composition API is backported using Vue 2's getter/setter-based reactivity system to ensure browser compatibility. This means there are some important behavior differences from Vue 3's proxy-based system:",{"type":19,"tag":89,"props":7763,"children":7764},{},[7765,7779,7842,7859,7871],{"type":19,"tag":83,"props":7766,"children":7767},{},[7768,7770,7777],{"type":24,"value":7769},"All ",{"type":19,"tag":51,"props":7771,"children":7774},{"href":7772,"rel":7773,"target":56},"https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats",[55,55],[7775],{"type":24,"value":7776},"Vue 2 change detection caveats",{"type":24,"value":7778}," still apply.",{"type":19,"tag":83,"props":7780,"children":7781},{},[7782,7788,7789,7795,7796,7802,7804],{"type":19,"tag":37,"props":7783,"children":7785},{"className":7784},[],[7786],{"type":24,"value":7787},"reactive()",{"type":24,"value":474},{"type":19,"tag":37,"props":7790,"children":7792},{"className":7791},[],[7793],{"type":24,"value":7794},"ref()",{"type":24,"value":5174},{"type":19,"tag":37,"props":7797,"children":7799},{"className":7798},[],[7800],{"type":24,"value":7801},"shallowReactive()",{"type":24,"value":7803}," will directly convert original objects instead of creating proxies. This means:",{"type":19,"tag":236,"props":7805,"children":7807},{"className":238,"code":7806,"language":240,"meta":8,"style":8},"// true in 2.7, false in 3.x\nreactive(foo) === foo\n",[7808],{"type":19,"tag":37,"props":7809,"children":7810},{"__ignoreMap":8},[7811,7819],{"type":19,"tag":246,"props":7812,"children":7813},{"class":248,"line":249},[7814],{"type":19,"tag":246,"props":7815,"children":7816},{"style":395},[7817],{"type":24,"value":7818},"// true in 2.7, false in 3.x\n",{"type":19,"tag":246,"props":7820,"children":7821},{"class":248,"line":292},[7822,7827,7832,7837],{"type":19,"tag":246,"props":7823,"children":7824},{"style":270},[7825],{"type":24,"value":7826},"reactive",{"type":19,"tag":246,"props":7828,"children":7829},{"style":259},[7830],{"type":24,"value":7831},"(foo) ",{"type":19,"tag":246,"props":7833,"children":7834},{"style":253},[7835],{"type":24,"value":7836},"===",{"type":19,"tag":246,"props":7838,"children":7839},{"style":259},[7840],{"type":24,"value":7841}," foo\n",{"type":19,"tag":83,"props":7843,"children":7844},{},[7845,7851,7852,7857],{"type":19,"tag":37,"props":7846,"children":7848},{"className":7847},[],[7849],{"type":24,"value":7850},"readonly()",{"type":24,"value":5714},{"type":19,"tag":98,"props":7853,"children":7854},{},[7855],{"type":24,"value":7856},"does",{"type":24,"value":7858}," create a separate object, but it won't track newly added properties and does not work on arrays.",{"type":19,"tag":83,"props":7860,"children":7861},{},[7862,7864,7869],{"type":24,"value":7863},"Avoid using arrays as root values in ",{"type":19,"tag":37,"props":7865,"children":7867},{"className":7866},[],[7868],{"type":24,"value":7787},{"type":24,"value":7870}," because without property access the array's mutation won't be tracked (this will result in a warning).",{"type":19,"tag":83,"props":7872,"children":7873},{},[7874],{"type":24,"value":7875},"Reactivity APIs ignore properties with symbol keys.",{"type":19,"tag":20,"props":7877,"children":7878},{},[7879,7881,7886],{"type":24,"value":7880},"In addition, the following features are explicitly ",{"type":19,"tag":98,"props":7882,"children":7883},{},[7884],{"type":24,"value":7885},"NOT",{"type":24,"value":7887}," ported:",{"type":19,"tag":89,"props":7889,"children":7890},{},[7891,7904,7923,7928,7933],{"type":19,"tag":83,"props":7892,"children":7893},{},[7894,7896,7902],{"type":24,"value":7895},"❌ ",{"type":19,"tag":37,"props":7897,"children":7899},{"className":7898},[],[7900],{"type":24,"value":7901},"createApp()",{"type":24,"value":7903}," (Vue 2 doesn't have isolated app scope)",{"type":19,"tag":83,"props":7905,"children":7906},{},[7907,7909,7915,7916,7921],{"type":24,"value":7908},"❌ Top-level ",{"type":19,"tag":37,"props":7910,"children":7912},{"className":7911},[],[7913],{"type":24,"value":7914},"await",{"type":24,"value":944},{"type":19,"tag":37,"props":7917,"children":7919},{"className":7918},[],[7920],{"type":24,"value":544},{"type":24,"value":7922}," (Vue 2 does not support async component initialization)",{"type":19,"tag":83,"props":7924,"children":7925},{},[7926],{"type":24,"value":7927},"❌ TypeScript syntax in template expressions (incompatible w/ Vue 2 parser)",{"type":19,"tag":83,"props":7929,"children":7930},{},[7931],{"type":24,"value":7932},"❌ Reactivity transform (still experimental)",{"type":19,"tag":83,"props":7934,"children":7935},{},[7936,7937,7943,7945,7951,7953,7958],{"type":24,"value":7895},{"type":19,"tag":37,"props":7938,"children":7940},{"className":7939},[],[7941],{"type":24,"value":7942},"expose",{"type":24,"value":7944}," option is not supported for options components (but ",{"type":19,"tag":37,"props":7946,"children":7948},{"className":7947},[],[7949],{"type":24,"value":7950},"defineExpose()",{"type":24,"value":7952}," is supported in ",{"type":19,"tag":37,"props":7954,"children":7956},{"className":7955},[],[7957],{"type":24,"value":544},{"type":24,"value":5512},{"type":19,"tag":72,"props":7960,"children":7962},{"id":7961},"upgrade-guide",[7963],{"type":24,"value":7964},"Upgrade Guide",{"type":19,"tag":151,"props":7966,"children":7968},{"id":7967},"vue-cli-webpack",[7969],{"type":24,"value":7970},"Vue CLI / webpack",{"type":19,"tag":79,"props":7972,"children":7973},{},[7974,8012,8059,8120,8153,8172],{"type":19,"tag":83,"props":7975,"children":7976},{},[7977,7979,7985,7987],{"type":24,"value":7978},"Upgrade local ",{"type":19,"tag":37,"props":7980,"children":7982},{"className":7981},[],[7983],{"type":24,"value":7984},"@vue/cli-xxx",{"type":24,"value":7986}," dependencies the latest version in your major version range (if applicable):",{"type":19,"tag":89,"props":7988,"children":7989},{},[7990,8001],{"type":19,"tag":83,"props":7991,"children":7992},{},[7993,7999],{"type":19,"tag":37,"props":7994,"children":7996},{"className":7995},[],[7997],{"type":24,"value":7998},"~4.5.18",{"type":24,"value":8000}," for v4",{"type":19,"tag":83,"props":8002,"children":8003},{},[8004,8010],{"type":19,"tag":37,"props":8005,"children":8007},{"className":8006},[],[8008],{"type":24,"value":8009},"~5.0.6",{"type":24,"value":8011}," for v5",{"type":19,"tag":83,"props":8013,"children":8014},{},[8015,8017,8022,8023,8029,8031,8037,8039,8042,8044,8050,8052,8057],{"type":24,"value":8016},"Upgrade ",{"type":19,"tag":37,"props":8018,"children":8020},{"className":8019},[],[8021],{"type":24,"value":625},{"type":24,"value":936},{"type":19,"tag":37,"props":8024,"children":8026},{"className":8025},[],[8027],{"type":24,"value":8028},"^2.7.0",{"type":24,"value":8030},". You can also remove ",{"type":19,"tag":37,"props":8032,"children":8034},{"className":8033},[],[8035],{"type":24,"value":8036},"vue-template-compiler",{"type":24,"value":8038}," from the dependencies - it is no longer needed in 2.7.",{"type":19,"tag":7650,"props":8040,"children":8041},{},[],{"type":24,"value":8043},"Note: if you are using ",{"type":19,"tag":37,"props":8045,"children":8047},{"className":8046},[],[8048],{"type":24,"value":8049},"@vue/test-utils",{"type":24,"value":8051},", you will need to keep ",{"type":19,"tag":37,"props":8053,"children":8055},{"className":8054},[],[8056],{"type":24,"value":8036},{"type":24,"value":8058}," in the dependencies because test utils rely on some APIs only exposed in this package.",{"type":19,"tag":83,"props":8060,"children":8061},{},[8062,8064,8070,8071,8107,8110,8112,8118],{"type":24,"value":8063},"Check your package manager lockfile to ensure the following dependencies meet the version requirements. They may be transitive dependencies not listed in ",{"type":19,"tag":37,"props":8065,"children":8067},{"className":8066},[],[8068],{"type":24,"value":8069},"package.json",{"type":24,"value":61},{"type":19,"tag":89,"props":8072,"children":8073},{},[8074,8091],{"type":19,"tag":83,"props":8075,"children":8076},{},[8077,8083,8085],{"type":19,"tag":37,"props":8078,"children":8080},{"className":8079},[],[8081],{"type":24,"value":8082},"vue-loader",{"type":24,"value":8084},": ",{"type":19,"tag":37,"props":8086,"children":8088},{"className":8087},[],[8089],{"type":24,"value":8090},"^15.10.0",{"type":19,"tag":83,"props":8092,"children":8093},{},[8094,8100,8101],{"type":19,"tag":37,"props":8095,"children":8097},{"className":8096},[],[8098],{"type":24,"value":8099},"vue-demi",{"type":24,"value":8084},{"type":19,"tag":37,"props":8102,"children":8104},{"className":8103},[],[8105],{"type":24,"value":8106},"^0.13.1",{"type":19,"tag":7650,"props":8108,"children":8109},{},[],{"type":24,"value":8111},"If not, you will need to remove ",{"type":19,"tag":37,"props":8113,"children":8115},{"className":8114},[],[8116],{"type":24,"value":8117},"node_modules",{"type":24,"value":8119}," and the lockfile and perform a fresh install to ensure they are bumped to the latest version.",{"type":19,"tag":83,"props":8121,"children":8122},{},[8123,8125,8136,8138,8143,8145,8151],{"type":24,"value":8124},"If you were previously using ",{"type":19,"tag":51,"props":8126,"children":8129},{"href":8127,"rel":8128,"target":56},"https://github.com/vuejs/composition-api",[55,55],[8130],{"type":19,"tag":37,"props":8131,"children":8133},{"className":8132},[],[8134],{"type":24,"value":8135},"@vue/composition-api",{"type":24,"value":8137},", update imports from it to ",{"type":19,"tag":37,"props":8139,"children":8141},{"className":8140},[],[8142],{"type":24,"value":625},{"type":24,"value":8144}," instead. Note that some APIs exported by the plugin, e.g. ",{"type":19,"tag":37,"props":8146,"children":8148},{"className":8147},[],[8149],{"type":24,"value":8150},"createApp",{"type":24,"value":8152},", are not ported in 2.7.",{"type":19,"tag":83,"props":8154,"children":8155},{},[8156,8158,8164,8166,8171],{"type":24,"value":8157},"Update ",{"type":19,"tag":37,"props":8159,"children":8161},{"className":8160},[],[8162],{"type":24,"value":8163},"eslint-plugin-vue",{"type":24,"value":8165}," to latest version (9+) if you run into unused variable lint errors when using ",{"type":19,"tag":37,"props":8167,"children":8169},{"className":8168},[],[8170],{"type":24,"value":544},{"type":24,"value":61},{"type":19,"tag":83,"props":8173,"children":8174},{},[8175,8177,8182],{"type":24,"value":8176},"The SFC compiler for 2.7 now uses PostCSS 8 (upgraded from 7). PostCSS 8 should be backwards compatible with most plugins, but the upgrade ",{"type":19,"tag":98,"props":8178,"children":8179},{},[8180],{"type":24,"value":8181},"may",{"type":24,"value":8183}," cause issues if you were previously using a custom PostCSS plugin that can only work with PostCSS 7. In such cases, you will need to upgrade the relevant plugins to their PostCSS 8 compatible versions.",{"type":19,"tag":151,"props":8185,"children":8187},{"id":8186},"vite",[8188],{"type":24,"value":4605},{"type":19,"tag":20,"props":8190,"children":8191},{},[8192,8194,8201,8203,8210],{"type":24,"value":8193},"2.7 support for Vite is provided via a new plugin: ",{"type":19,"tag":51,"props":8195,"children":8198},{"href":8196,"rel":8197,"target":56},"https://github.com/vitejs/vite-plugin-vue2",[55,55],[8199],{"type":24,"value":8200},"@vitejs/plugin-vue2",{"type":24,"value":8202},". This new plugin requires Vue 2.7 or above and supersedes the existing ",{"type":19,"tag":51,"props":8204,"children":8207},{"href":8205,"rel":8206,"target":56},"https://github.com/underfin/vite-plugin-vue2",[55,55],[8208],{"type":24,"value":8209},"vite-plugin-vue2",{"type":24,"value":61},{"type":19,"tag":20,"props":8212,"children":8213},{},[8214,8216,8223],{"type":24,"value":8215},"Note that the new plugin does not handle Vue-specific JSX / TSX transform, which is intentional. Vue 2 JSX / TSX transform for Vite is handled in a separate, dedicated plugin: ",{"type":19,"tag":51,"props":8217,"children":8220},{"href":8218,"rel":8219,"target":56},"https://github.com/vitejs/vite-plugin-vue2-jsx",[55,55],[8221],{"type":24,"value":8222},"@vitejs/plugin-vue2-jsx",{"type":24,"value":61},{"type":19,"tag":151,"props":8225,"children":8227},{"id":8226},"volar-compatibility",[8228],{"type":24,"value":8229},"Volar Compatibility",{"type":19,"tag":20,"props":8231,"children":8232},{},[8233,8235,8241,8243,8248],{"type":24,"value":8234},"2.7 ships improved type definitions so it is no longer necessary to install ",{"type":19,"tag":37,"props":8236,"children":8238},{"className":8237},[],[8239],{"type":24,"value":8240},"@vue/runtime-dom",{"type":24,"value":8242}," just for Volar template type inference support. All you need now is the following config in ",{"type":19,"tag":37,"props":8244,"children":8246},{"className":8245},[],[8247],{"type":24,"value":950},{"type":24,"value":1883},{"type":19,"tag":236,"props":8250,"children":8254},{"className":8251,"code":8252,"language":8253,"meta":8,"style":8},"language-json shiki shiki-themes dracula-soft","{\n  // ...\n  \"vueCompilerOptions\": {\n    \"target\": 2.7\n  }\n}\n","json",[8255],{"type":19,"tag":37,"props":8256,"children":8257},{"__ignoreMap":8},[8258,8266,8274,8301,8327,8334],{"type":19,"tag":246,"props":8259,"children":8260},{"class":248,"line":249},[8261],{"type":19,"tag":246,"props":8262,"children":8263},{"style":259},[8264],{"type":24,"value":8265},"{\n",{"type":19,"tag":246,"props":8267,"children":8268},{"class":248,"line":292},[8269],{"type":19,"tag":246,"props":8270,"children":8271},{"style":395},[8272],{"type":24,"value":8273},"  // ...\n",{"type":19,"tag":246,"props":8275,"children":8276},{"class":248,"line":353},[8277,8283,8289,8293,8297],{"type":19,"tag":246,"props":8278,"children":8280},{"style":8279},"--shiki-default:#97E2F2",[8281],{"type":24,"value":8282},"  \"",{"type":19,"tag":246,"props":8284,"children":8286},{"style":8285},"--shiki-default:#97E1F1",[8287],{"type":24,"value":8288},"vueCompilerOptions",{"type":19,"tag":246,"props":8290,"children":8291},{"style":8279},[8292],{"type":24,"value":663},{"type":19,"tag":246,"props":8294,"children":8295},{"style":253},[8296],{"type":24,"value":1883},{"type":19,"tag":246,"props":8298,"children":8299},{"style":259},[8300],{"type":24,"value":3046},{"type":19,"tag":246,"props":8302,"children":8303},{"class":248,"line":363},[8304,8309,8314,8318,8322],{"type":19,"tag":246,"props":8305,"children":8306},{"style":8279},[8307],{"type":24,"value":8308},"    \"",{"type":19,"tag":246,"props":8310,"children":8311},{"style":8285},[8312],{"type":24,"value":8313},"target",{"type":19,"tag":246,"props":8315,"children":8316},{"style":8279},[8317],{"type":24,"value":663},{"type":19,"tag":246,"props":8319,"children":8320},{"style":253},[8321],{"type":24,"value":1883},{"type":19,"tag":246,"props":8323,"children":8324},{"style":281},[8325],{"type":24,"value":8326}," 2.7\n",{"type":19,"tag":246,"props":8328,"children":8329},{"class":248,"line":401},[8330],{"type":19,"tag":246,"props":8331,"children":8332},{"style":259},[8333],{"type":24,"value":3436},{"type":19,"tag":246,"props":8335,"children":8336},{"class":248,"line":409},[8337],{"type":19,"tag":246,"props":8338,"children":8339},{"style":259},[8340],{"type":24,"value":8341},"}\n",{"type":19,"tag":151,"props":8343,"children":8345},{"id":8344},"devtools-support",[8346],{"type":24,"value":8347},"Devtools Support",{"type":19,"tag":20,"props":8349,"children":8350},{},[8351],{"type":24,"value":8352},"Vue Devtools 6.2.0 has added support for inspecting 2.7 Composition API state, but the extensions may still need a few days to go through review on respective publishing platforms.",{"type":19,"tag":72,"props":8354,"children":8356},{"id":8355},"implications-of-the-27-release",[8357],{"type":24,"value":8358},"Implications of the 2.7 Release",{"type":19,"tag":20,"props":8360,"children":8361},{},[8362,8364,8369],{"type":24,"value":8363},"As stated before, 2.7 is the final minor release of Vue 2.x. After this release, Vue 2 has entered LTS (long-term support) which lasts for 18 months from now, and will no longer receive new features. This means ",{"type":19,"tag":98,"props":8365,"children":8366},{},[8367],{"type":24,"value":8368},"Vue 2 will reach End of Life on December 31st, 2023",{"type":24,"value":61},{"type":19,"tag":20,"props":8371,"children":8372},{},[8373,8375,8381],{"type":24,"value":8374},"We believe this should provide plenty of time for most of the ecosystem to migrate over to Vue 3. However, we also understand that there could be teams or projects that cannot upgrade by this timeline while still needing to fulfill security and compliance requirements. We are partnering with industry experts to provide extended support for Vue 2 for teams with such needs - if your team expects to be using Vue 2 beyond the end of 2023, make sure to plan ahead and learn more about ",{"type":19,"tag":51,"props":8376,"children":8378},{"href":5405,"rel":8377,"target":56},[55,55],[8379],{"type":24,"value":8380},"Vue 2 Extended LTS",{"type":24,"value":61},{"type":19,"tag":72,"props":8383,"children":8385},{"id":8384},"extra-details",[8386],{"type":24,"value":8387},"Extra Details",{"type":19,"tag":20,"props":8389,"children":8390},{},[8391,8393,8400,8402,8408],{"type":24,"value":8392},"In preparation of this release, we ported the Vue 2 codebase from Flow to TypeScript, building upon the heroic effort by core team member ",{"type":19,"tag":51,"props":8394,"children":8397},{"href":8395,"rel":8396,"target":56},"https://github.com/pikax",[55,55],[8398],{"type":24,"value":8399},"@pikax",{"type":24,"value":8401},". This made it much easier for us to reuse code from Vue 3, and auto-generate type definitions for the ported APIs. We also moved the unit tests from Karma + Jasmine to ",{"type":19,"tag":51,"props":8403,"children":8406},{"href":8404,"rel":8405,"target":56},"https://vitest.dev/",[55,55],[8407],{"type":24,"value":4369},{"type":24,"value":8409},", resulting in greatly improved maintenance DX and CI stability.",{"type":19,"tag":20,"props":8411,"children":8412},{},[8413],{"type":24,"value":8414},"We would also like to express our appreciation towards prior community efforts that bridged the gap before 2.7 was available:",{"type":19,"tag":89,"props":8416,"children":8417},{},[8418,8435,8452],{"type":19,"tag":83,"props":8419,"children":8420},{},[8421,8426,8428],{"type":19,"tag":37,"props":8422,"children":8424},{"className":8423},[],[8425],{"type":24,"value":8135},{"type":24,"value":8427}," plugin by ",{"type":19,"tag":51,"props":8429,"children":8432},{"href":8430,"rel":8431,"target":56},"https://github.com/liximomo",[55,55],[8433],{"type":24,"value":8434},"@liximomo",{"type":19,"tag":83,"props":8436,"children":8437},{},[8438,8443,8445],{"type":19,"tag":37,"props":8439,"children":8441},{"className":8440},[],[8442],{"type":24,"value":8099},{"type":24,"value":8444}," by ",{"type":19,"tag":51,"props":8446,"children":8449},{"href":8447,"rel":8448,"target":56},"https://github.com/antfu",[55,55],[8450],{"type":24,"value":8451},"@antfu",{"type":19,"tag":83,"props":8453,"children":8454},{},[8455,8460,8461],{"type":19,"tag":37,"props":8456,"children":8458},{"className":8457},[],[8459],{"type":24,"value":8209},{"type":24,"value":8444},{"type":19,"tag":51,"props":8462,"children":8465},{"href":8463,"rel":8464,"target":56},"https://github.com/underfin",[55,55],[8466],{"type":24,"value":8467},"@underfin",{"type":19,"tag":1103,"props":8469,"children":8470},{},[8471],{"type":24,"value":1107},{"title":8,"searchDepth":292,"depth":292,"links":8473},[8474,8478,8484,8485],{"id":7514,"depth":292,"text":7517,"children":8475},[8476,8477],{"id":7665,"depth":353,"text":7668},{"id":7753,"depth":353,"text":7756},{"id":7961,"depth":292,"text":7964,"children":8479},[8480,8481,8482,8483],{"id":7967,"depth":353,"text":7970},{"id":8186,"depth":353,"text":4605},{"id":8226,"depth":353,"text":8229},{"id":8344,"depth":353,"text":8347},{"id":8355,"depth":292,"text":8358},{"id":8384,"depth":292,"text":8387},"content:blog:vue-2-7-naruto.md","blog/vue-2-7-naruto.md","blog/vue-2-7-naruto",{"loc":5190},{"_path":8491,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":8492,"description":8493,"date":8494,"author":12,"gravatar":13,"twitter":14,"excerpt":8495,"body":8501,"_type":1125,"_id":9879,"_source":1127,"_file":9880,"_stem":9881,"_extension":1130,"sitemap":9882},"/blog/vue-2-7-beta","Vue 2.7 is Now in Beta","We are happy to announce that Vue 2.7 is now in beta.","2022-06-20",{"type":16,"children":8496},[8497],{"type":19,"tag":20,"props":8498,"children":8499},{},[8500],{"type":24,"value":8493},{"type":16,"children":8502,"toc":9867},[8503,8507,8510,8514,8518,8551,8555,8640,8644,8716,8720,8724,8818,8827,8886,8892,8897,8903,9711,9715,9731,9736,9740,9756,9836,9840,9845,9863],{"type":19,"tag":20,"props":8504,"children":8505},{},[8506],{"type":24,"value":8493},{"type":19,"tag":63,"props":8508,"children":8509},{},[],{"type":19,"tag":20,"props":8511,"children":8512},{},[8513],{"type":24,"value":7511},{"type":19,"tag":72,"props":8515,"children":8516},{"id":7514},[8517],{"type":24,"value":7517},{"type":19,"tag":89,"props":8519,"children":8520},{},[8521,8529,8542],{"type":19,"tag":83,"props":8522,"children":8523},{},[8524],{"type":19,"tag":51,"props":8525,"children":8527},{"href":7526,"rel":8526,"target":56},[55,55],[8528],{"type":24,"value":7530},{"type":19,"tag":83,"props":8530,"children":8531},{},[8532,8533],{"type":24,"value":7535},{"type":19,"tag":51,"props":8534,"children":8536},{"href":7538,"rel":8535,"target":56},[55,55],[8537],{"type":19,"tag":37,"props":8538,"children":8540},{"className":8539},[],[8541],{"type":24,"value":544},{"type":19,"tag":83,"props":8543,"children":8544},{},[8545,8546],{"type":24,"value":7535},{"type":19,"tag":51,"props":8547,"children":8549},{"href":7552,"rel":8548,"target":56},[55,55],[8550],{"type":24,"value":7556},{"type":19,"tag":20,"props":8552,"children":8553},{},[8554],{"type":24,"value":7561},{"type":19,"tag":89,"props":8556,"children":8557},{},[8558,8573,8599,8620],{"type":19,"tag":83,"props":8559,"children":8560},{},[8561,8566,8567,8572],{"type":19,"tag":37,"props":8562,"children":8564},{"className":8563},[],[8565],{"type":24,"value":2206},{"type":24,"value":7574},{"type":19,"tag":37,"props":8568,"children":8570},{"className":8569},[],[8571],{"type":24,"value":6300},{"type":24,"value":104},{"type":19,"tag":83,"props":8574,"children":8575},{},[8576,8581,8582,8587,8588,8593,8594],{"type":19,"tag":37,"props":8577,"children":8579},{"className":8578},[],[8580],{"type":24,"value":7589},{"type":24,"value":474},{"type":19,"tag":37,"props":8583,"children":8585},{"className":8584},[],[8586],{"type":24,"value":7596},{"type":24,"value":474},{"type":19,"tag":37,"props":8589,"children":8591},{"className":8590},[],[8592],{"type":24,"value":7603},{"type":24,"value":474},{"type":19,"tag":37,"props":8595,"children":8597},{"className":8596},[],[8598],{"type":24,"value":7610},{"type":19,"tag":83,"props":8600,"children":8601},{},[8602,8607,8608,8613,8614,8619],{"type":19,"tag":37,"props":8603,"children":8605},{"className":8604},[],[8606],{"type":24,"value":7619},{"type":24,"value":474},{"type":19,"tag":37,"props":8609,"children":8611},{"className":8610},[],[8612],{"type":24,"value":7626},{"type":24,"value":1384},{"type":19,"tag":37,"props":8615,"children":8617},{"className":8616},[],[8618],{"type":24,"value":7633},{"type":24,"value":7635},{"type":19,"tag":83,"props":8621,"children":8622},{},[8623,8624,8629,8630,8633,8634,8639],{"type":24,"value":7640},{"type":19,"tag":37,"props":8625,"children":8627},{"className":8626},[],[8628],{"type":24,"value":7646},{"type":24,"value":7648},{"type":19,"tag":7650,"props":8631,"children":8632},{},[],{"type":24,"value":7654},{"type":19,"tag":37,"props":8635,"children":8637},{"className":8636},[],[8638],{"type":24,"value":7660},{"type":24,"value":7662},{"type":19,"tag":151,"props":8641,"children":8642},{"id":7665},[8643],{"type":24,"value":7668},{"type":19,"tag":89,"props":8645,"children":8646},{},[8647,8702,8712],{"type":19,"tag":83,"props":8648,"children":8649},{},[8650,8651],{"type":24,"value":7676},{"type":19,"tag":236,"props":8652,"children":8653},{"className":238,"code":7679,"language":240,"meta":8,"style":8},[8654],{"type":19,"tag":37,"props":8655,"children":8656},{"__ignoreMap":8},[8657,8684,8691],{"type":19,"tag":246,"props":8658,"children":8659},{"class":248,"line":249},[8660,8664,8668,8672,8676,8680],{"type":19,"tag":246,"props":8661,"children":8662},{"style":253},[8663],{"type":24,"value":7691},{"type":19,"tag":246,"props":8665,"children":8666},{"style":259},[8667],{"type":24,"value":7696},{"type":19,"tag":246,"props":8669,"children":8670},{"style":253},[8671],{"type":24,"value":1654},{"type":19,"tag":246,"props":8673,"children":8674},{"style":660},[8675],{"type":24,"value":1659},{"type":19,"tag":246,"props":8677,"children":8678},{"style":1619},[8679],{"type":24,"value":625},{"type":19,"tag":246,"props":8681,"children":8682},{"style":660},[8683],{"type":24,"value":1669},{"type":19,"tag":246,"props":8685,"children":8686},{"class":248,"line":292},[8687],{"type":19,"tag":246,"props":8688,"children":8689},{"emptyLinePlaceholder":357},[8690],{"type":24,"value":360},{"type":19,"tag":246,"props":8692,"children":8693},{"class":248,"line":353},[8694,8698],{"type":19,"tag":246,"props":8695,"children":8696},{"style":259},[8697],{"type":24,"value":7727},{"type":19,"tag":246,"props":8699,"children":8700},{"style":395},[8701],{"type":24,"value":7732},{"type":19,"tag":83,"props":8703,"children":8704},{},[8705,8706,8711],{"type":24,"value":7737},{"type":19,"tag":37,"props":8707,"children":8709},{"className":8708},[],[8710],{"type":24,"value":7743},{"type":24,"value":7745},{"type":19,"tag":83,"props":8713,"children":8714},{},[8715],{"type":24,"value":7750},{"type":19,"tag":151,"props":8717,"children":8718},{"id":7753},[8719],{"type":24,"value":7756},{"type":19,"tag":20,"props":8721,"children":8722},{},[8723],{"type":24,"value":7761},{"type":19,"tag":89,"props":8725,"children":8726},{},[8727,8737,8790,8804,8814],{"type":19,"tag":83,"props":8728,"children":8729},{},[8730,8731,8736],{"type":24,"value":7769},{"type":19,"tag":51,"props":8732,"children":8734},{"href":7772,"rel":8733,"target":56},[55,55],[8735],{"type":24,"value":7776},{"type":24,"value":7778},{"type":19,"tag":83,"props":8738,"children":8739},{},[8740,8745,8746,8751,8752,8757,8758],{"type":19,"tag":37,"props":8741,"children":8743},{"className":8742},[],[8744],{"type":24,"value":7787},{"type":24,"value":474},{"type":19,"tag":37,"props":8747,"children":8749},{"className":8748},[],[8750],{"type":24,"value":7794},{"type":24,"value":5174},{"type":19,"tag":37,"props":8753,"children":8755},{"className":8754},[],[8756],{"type":24,"value":7801},{"type":24,"value":7803},{"type":19,"tag":236,"props":8759,"children":8760},{"className":238,"code":7806,"language":240,"meta":8,"style":8},[8761],{"type":19,"tag":37,"props":8762,"children":8763},{"__ignoreMap":8},[8764,8771],{"type":19,"tag":246,"props":8765,"children":8766},{"class":248,"line":249},[8767],{"type":19,"tag":246,"props":8768,"children":8769},{"style":395},[8770],{"type":24,"value":7818},{"type":19,"tag":246,"props":8772,"children":8773},{"class":248,"line":292},[8774,8778,8782,8786],{"type":19,"tag":246,"props":8775,"children":8776},{"style":270},[8777],{"type":24,"value":7826},{"type":19,"tag":246,"props":8779,"children":8780},{"style":259},[8781],{"type":24,"value":7831},{"type":19,"tag":246,"props":8783,"children":8784},{"style":253},[8785],{"type":24,"value":7836},{"type":19,"tag":246,"props":8787,"children":8788},{"style":259},[8789],{"type":24,"value":7841},{"type":19,"tag":83,"props":8791,"children":8792},{},[8793,8798,8799,8803],{"type":19,"tag":37,"props":8794,"children":8796},{"className":8795},[],[8797],{"type":24,"value":7850},{"type":24,"value":5714},{"type":19,"tag":98,"props":8800,"children":8801},{},[8802],{"type":24,"value":7856},{"type":24,"value":7858},{"type":19,"tag":83,"props":8805,"children":8806},{},[8807,8808,8813],{"type":24,"value":7863},{"type":19,"tag":37,"props":8809,"children":8811},{"className":8810},[],[8812],{"type":24,"value":7787},{"type":24,"value":7870},{"type":19,"tag":83,"props":8815,"children":8816},{},[8817],{"type":24,"value":7875},{"type":19,"tag":20,"props":8819,"children":8820},{},[8821,8822,8826],{"type":24,"value":7880},{"type":19,"tag":98,"props":8823,"children":8824},{},[8825],{"type":24,"value":7885},{"type":24,"value":7887},{"type":19,"tag":89,"props":8828,"children":8829},{},[8830,8840,8856,8860,8864],{"type":19,"tag":83,"props":8831,"children":8832},{},[8833,8834,8839],{"type":24,"value":7895},{"type":19,"tag":37,"props":8835,"children":8837},{"className":8836},[],[8838],{"type":24,"value":7901},{"type":24,"value":7903},{"type":19,"tag":83,"props":8841,"children":8842},{},[8843,8844,8849,8850,8855],{"type":24,"value":7908},{"type":19,"tag":37,"props":8845,"children":8847},{"className":8846},[],[8848],{"type":24,"value":7914},{"type":24,"value":944},{"type":19,"tag":37,"props":8851,"children":8853},{"className":8852},[],[8854],{"type":24,"value":544},{"type":24,"value":7922},{"type":19,"tag":83,"props":8857,"children":8858},{},[8859],{"type":24,"value":7927},{"type":19,"tag":83,"props":8861,"children":8862},{},[8863],{"type":24,"value":7932},{"type":19,"tag":83,"props":8865,"children":8866},{},[8867,8868,8873,8874,8879,8880,8885],{"type":24,"value":7895},{"type":19,"tag":37,"props":8869,"children":8871},{"className":8870},[],[8872],{"type":24,"value":7942},{"type":24,"value":7944},{"type":19,"tag":37,"props":8875,"children":8877},{"className":8876},[],[8878],{"type":24,"value":7950},{"type":24,"value":7952},{"type":19,"tag":37,"props":8881,"children":8883},{"className":8882},[],[8884],{"type":24,"value":544},{"type":24,"value":5512},{"type":19,"tag":72,"props":8887,"children":8889},{"id":8888},"beta-adoption-guide",[8890],{"type":24,"value":8891},"Beta Adoption Guide",{"type":19,"tag":20,"props":8893,"children":8894},{},[8895],{"type":24,"value":8896},"2.7 is currently in beta stage and may still have rough edges. Please help us test its stability by opting into the beta. Here's how:",{"type":19,"tag":151,"props":8898,"children":8900},{"id":8899},"vue-cli",[8901],{"type":24,"value":8902},"Vue CLI",{"type":19,"tag":79,"props":8904,"children":8905},{},[8906,8938,8970,8990,9679,9702],{"type":19,"tag":83,"props":8907,"children":8908},{},[8909,8910,8915,8917],{"type":24,"value":7978},{"type":19,"tag":37,"props":8911,"children":8913},{"className":8912},[],[8914],{"type":24,"value":7984},{"type":24,"value":8916}," dependencies the latest version in your major version range:",{"type":19,"tag":89,"props":8918,"children":8919},{},[8920,8929],{"type":19,"tag":83,"props":8921,"children":8922},{},[8923,8928],{"type":19,"tag":37,"props":8924,"children":8926},{"className":8925},[],[8927],{"type":24,"value":7998},{"type":24,"value":8000},{"type":19,"tag":83,"props":8930,"children":8931},{},[8932,8937],{"type":19,"tag":37,"props":8933,"children":8935},{"className":8934},[],[8936],{"type":24,"value":8009},{"type":24,"value":8011},{"type":19,"tag":83,"props":8939,"children":8940},{},[8941,8942,8947,8948,8954,8956,8962,8964,8969],{"type":24,"value":8016},{"type":19,"tag":37,"props":8943,"children":8945},{"className":8944},[],[8946],{"type":24,"value":625},{"type":24,"value":936},{"type":19,"tag":37,"props":8949,"children":8951},{"className":8950},[],[8952],{"type":24,"value":8953},"v2-beta",{"type":24,"value":8955},", or pin to a specific version (latest beta as of this writing is ",{"type":19,"tag":37,"props":8957,"children":8959},{"className":8958},[],[8960],{"type":24,"value":8961},"2.7.0-beta.3",{"type":24,"value":8963},"). You can also remove ",{"type":19,"tag":37,"props":8965,"children":8967},{"className":8966},[],[8968],{"type":24,"value":8036},{"type":24,"value":8038},{"type":19,"tag":83,"props":8971,"children":8972},{},[8973,8974,8983,8984,8989],{"type":24,"value":8124},{"type":19,"tag":51,"props":8975,"children":8977},{"href":8127,"rel":8976,"target":56},[55,55],[8978],{"type":19,"tag":37,"props":8979,"children":8981},{"className":8980},[],[8982],{"type":24,"value":8135},{"type":24,"value":8137},{"type":19,"tag":37,"props":8985,"children":8987},{"className":8986},[],[8988],{"type":24,"value":625},{"type":24,"value":1101},{"type":19,"tag":83,"props":8991,"children":8992},{},[8993,8995,9000,9002,9007,9009,9015,9017],{"type":24,"value":8994},"Opt-in to ",{"type":19,"tag":37,"props":8996,"children":8998},{"className":8997},[],[8999],{"type":24,"value":8082},{"type":24,"value":9001}," v15 beta. Since ",{"type":19,"tag":37,"props":9003,"children":9005},{"className":9004},[],[9006],{"type":24,"value":8082},{"type":24,"value":9008}," is a transitive dependency of ",{"type":19,"tag":37,"props":9010,"children":9012},{"className":9011},[],[9013],{"type":24,"value":9014},"@vue/cli-service",{"type":24,"value":9016},", you will need to force your package manager to explicitly use the beta version. The forced resolution will no longer be necessary when it goes stable.",{"type":19,"tag":89,"props":9018,"children":9019},{},[9020,9227,9425],{"type":19,"tag":83,"props":9021,"children":9022},{},[9023,9025,9031,9033,9040,9042,9047,9048,9051,9053,9138,9141,9143],{"type":24,"value":9024},"For ",{"type":19,"tag":37,"props":9026,"children":9028},{"className":9027},[],[9029],{"type":24,"value":9030},"npm",{"type":24,"value":9032}," (>=8.3.0), use the ",{"type":19,"tag":51,"props":9034,"children":9037},{"href":9035,"rel":9036,"target":56},"https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides",[55,55],[9038],{"type":24,"value":9039},"overrides",{"type":24,"value":9041}," field in ",{"type":19,"tag":37,"props":9043,"children":9045},{"className":9044},[],[9046],{"type":24,"value":8069},{"type":24,"value":61},{"type":19,"tag":7650,"props":9049,"children":9050},{},[],{"type":24,"value":9052},"If using Vue CLI v4:",{"type":19,"tag":236,"props":9054,"children":9056},{"className":8251,"code":9055,"language":8253,"meta":8,"style":8},"{\n  \"overrides\": {\n    \"vue-loader\": \"^15.10.0-beta.6\"\n  }\n}\n",[9057],{"type":19,"tag":37,"props":9058,"children":9059},{"__ignoreMap":8},[9060,9067,9090,9124,9131],{"type":19,"tag":246,"props":9061,"children":9062},{"class":248,"line":249},[9063],{"type":19,"tag":246,"props":9064,"children":9065},{"style":259},[9066],{"type":24,"value":8265},{"type":19,"tag":246,"props":9068,"children":9069},{"class":248,"line":292},[9070,9074,9078,9082,9086],{"type":19,"tag":246,"props":9071,"children":9072},{"style":8279},[9073],{"type":24,"value":8282},{"type":19,"tag":246,"props":9075,"children":9076},{"style":8285},[9077],{"type":24,"value":9039},{"type":19,"tag":246,"props":9079,"children":9080},{"style":8279},[9081],{"type":24,"value":663},{"type":19,"tag":246,"props":9083,"children":9084},{"style":253},[9085],{"type":24,"value":1883},{"type":19,"tag":246,"props":9087,"children":9088},{"style":259},[9089],{"type":24,"value":3046},{"type":19,"tag":246,"props":9091,"children":9092},{"class":248,"line":353},[9093,9097,9101,9105,9109,9114,9119],{"type":19,"tag":246,"props":9094,"children":9095},{"style":8279},[9096],{"type":24,"value":8308},{"type":19,"tag":246,"props":9098,"children":9099},{"style":8285},[9100],{"type":24,"value":8082},{"type":19,"tag":246,"props":9102,"children":9103},{"style":8279},[9104],{"type":24,"value":663},{"type":19,"tag":246,"props":9106,"children":9107},{"style":253},[9108],{"type":24,"value":1883},{"type":19,"tag":246,"props":9110,"children":9111},{"style":660},[9112],{"type":24,"value":9113}," \"",{"type":19,"tag":246,"props":9115,"children":9116},{"style":1619},[9117],{"type":24,"value":9118},"^15.10.0-beta.6",{"type":19,"tag":246,"props":9120,"children":9121},{"style":660},[9122],{"type":24,"value":9123},"\"\n",{"type":19,"tag":246,"props":9125,"children":9126},{"class":248,"line":363},[9127],{"type":19,"tag":246,"props":9128,"children":9129},{"style":259},[9130],{"type":24,"value":3436},{"type":19,"tag":246,"props":9132,"children":9133},{"class":248,"line":401},[9134],{"type":19,"tag":246,"props":9135,"children":9136},{"style":259},[9137],{"type":24,"value":8341},{"type":19,"tag":7650,"props":9139,"children":9140},{},[],{"type":24,"value":9142},"If using Vue CLI v5:",{"type":19,"tag":236,"props":9144,"children":9146},{"className":8251,"code":9145,"language":8253,"meta":8,"style":8},"{\n  \"overrides\": {\n    \"@vue/vue-loader-v15\": \"npm:vue-loader@^15.10.0-beta.6\"\n  }\n}\n",[9147],{"type":19,"tag":37,"props":9148,"children":9149},{"__ignoreMap":8},[9150,9157,9180,9213,9220],{"type":19,"tag":246,"props":9151,"children":9152},{"class":248,"line":249},[9153],{"type":19,"tag":246,"props":9154,"children":9155},{"style":259},[9156],{"type":24,"value":8265},{"type":19,"tag":246,"props":9158,"children":9159},{"class":248,"line":292},[9160,9164,9168,9172,9176],{"type":19,"tag":246,"props":9161,"children":9162},{"style":8279},[9163],{"type":24,"value":8282},{"type":19,"tag":246,"props":9165,"children":9166},{"style":8285},[9167],{"type":24,"value":9039},{"type":19,"tag":246,"props":9169,"children":9170},{"style":8279},[9171],{"type":24,"value":663},{"type":19,"tag":246,"props":9173,"children":9174},{"style":253},[9175],{"type":24,"value":1883},{"type":19,"tag":246,"props":9177,"children":9178},{"style":259},[9179],{"type":24,"value":3046},{"type":19,"tag":246,"props":9181,"children":9182},{"class":248,"line":353},[9183,9187,9192,9196,9200,9204,9209],{"type":19,"tag":246,"props":9184,"children":9185},{"style":8279},[9186],{"type":24,"value":8308},{"type":19,"tag":246,"props":9188,"children":9189},{"style":8285},[9190],{"type":24,"value":9191},"@vue/vue-loader-v15",{"type":19,"tag":246,"props":9193,"children":9194},{"style":8279},[9195],{"type":24,"value":663},{"type":19,"tag":246,"props":9197,"children":9198},{"style":253},[9199],{"type":24,"value":1883},{"type":19,"tag":246,"props":9201,"children":9202},{"style":660},[9203],{"type":24,"value":9113},{"type":19,"tag":246,"props":9205,"children":9206},{"style":1619},[9207],{"type":24,"value":9208},"npm:vue-loader@^15.10.0-beta.6",{"type":19,"tag":246,"props":9210,"children":9211},{"style":660},[9212],{"type":24,"value":9123},{"type":19,"tag":246,"props":9214,"children":9215},{"class":248,"line":363},[9216],{"type":19,"tag":246,"props":9217,"children":9218},{"style":259},[9219],{"type":24,"value":3436},{"type":19,"tag":246,"props":9221,"children":9222},{"class":248,"line":401},[9223],{"type":19,"tag":246,"props":9224,"children":9225},{"style":259},[9226],{"type":24,"value":8341},{"type":19,"tag":83,"props":9228,"children":9229},{},[9230,9231,9237,9239,9246,9247,9252,9253,9256,9257,9339,9342,9343],{"type":24,"value":9024},{"type":19,"tag":37,"props":9232,"children":9234},{"className":9233},[],[9235],{"type":24,"value":9236},"yarn",{"type":24,"value":9238},", use the ",{"type":19,"tag":51,"props":9240,"children":9243},{"href":9241,"rel":9242,"target":56},"https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/",[55,55],[9244],{"type":24,"value":9245},"resolutions",{"type":24,"value":9041},{"type":19,"tag":37,"props":9248,"children":9250},{"className":9249},[],[9251],{"type":24,"value":8069},{"type":24,"value":61},{"type":19,"tag":7650,"props":9254,"children":9255},{},[],{"type":24,"value":9052},{"type":19,"tag":236,"props":9258,"children":9260},{"className":8251,"code":9259,"language":8253,"meta":8,"style":8},"{\n  \"resolutions\": {\n    \"vue-loader\": \"^15.10.0-beta.6\"\n  }\n}\n",[9261],{"type":19,"tag":37,"props":9262,"children":9263},{"__ignoreMap":8},[9264,9271,9294,9325,9332],{"type":19,"tag":246,"props":9265,"children":9266},{"class":248,"line":249},[9267],{"type":19,"tag":246,"props":9268,"children":9269},{"style":259},[9270],{"type":24,"value":8265},{"type":19,"tag":246,"props":9272,"children":9273},{"class":248,"line":292},[9274,9278,9282,9286,9290],{"type":19,"tag":246,"props":9275,"children":9276},{"style":8279},[9277],{"type":24,"value":8282},{"type":19,"tag":246,"props":9279,"children":9280},{"style":8285},[9281],{"type":24,"value":9245},{"type":19,"tag":246,"props":9283,"children":9284},{"style":8279},[9285],{"type":24,"value":663},{"type":19,"tag":246,"props":9287,"children":9288},{"style":253},[9289],{"type":24,"value":1883},{"type":19,"tag":246,"props":9291,"children":9292},{"style":259},[9293],{"type":24,"value":3046},{"type":19,"tag":246,"props":9295,"children":9296},{"class":248,"line":353},[9297,9301,9305,9309,9313,9317,9321],{"type":19,"tag":246,"props":9298,"children":9299},{"style":8279},[9300],{"type":24,"value":8308},{"type":19,"tag":246,"props":9302,"children":9303},{"style":8285},[9304],{"type":24,"value":8082},{"type":19,"tag":246,"props":9306,"children":9307},{"style":8279},[9308],{"type":24,"value":663},{"type":19,"tag":246,"props":9310,"children":9311},{"style":253},[9312],{"type":24,"value":1883},{"type":19,"tag":246,"props":9314,"children":9315},{"style":660},[9316],{"type":24,"value":9113},{"type":19,"tag":246,"props":9318,"children":9319},{"style":1619},[9320],{"type":24,"value":9118},{"type":19,"tag":246,"props":9322,"children":9323},{"style":660},[9324],{"type":24,"value":9123},{"type":19,"tag":246,"props":9326,"children":9327},{"class":248,"line":363},[9328],{"type":19,"tag":246,"props":9329,"children":9330},{"style":259},[9331],{"type":24,"value":3436},{"type":19,"tag":246,"props":9333,"children":9334},{"class":248,"line":401},[9335],{"type":19,"tag":246,"props":9336,"children":9337},{"style":259},[9338],{"type":24,"value":8341},{"type":19,"tag":7650,"props":9340,"children":9341},{},[],{"type":24,"value":9142},{"type":19,"tag":236,"props":9344,"children":9346},{"className":8251,"code":9345,"language":8253,"meta":8,"style":8},"{\n  \"resolutions\": {\n    \"@vue/vue-loader-v15\": \"npm:vue-loader@^15.10.0-beta.6\"\n  }\n}\n",[9347],{"type":19,"tag":37,"props":9348,"children":9349},{"__ignoreMap":8},[9350,9357,9380,9411,9418],{"type":19,"tag":246,"props":9351,"children":9352},{"class":248,"line":249},[9353],{"type":19,"tag":246,"props":9354,"children":9355},{"style":259},[9356],{"type":24,"value":8265},{"type":19,"tag":246,"props":9358,"children":9359},{"class":248,"line":292},[9360,9364,9368,9372,9376],{"type":19,"tag":246,"props":9361,"children":9362},{"style":8279},[9363],{"type":24,"value":8282},{"type":19,"tag":246,"props":9365,"children":9366},{"style":8285},[9367],{"type":24,"value":9245},{"type":19,"tag":246,"props":9369,"children":9370},{"style":8279},[9371],{"type":24,"value":663},{"type":19,"tag":246,"props":9373,"children":9374},{"style":253},[9375],{"type":24,"value":1883},{"type":19,"tag":246,"props":9377,"children":9378},{"style":259},[9379],{"type":24,"value":3046},{"type":19,"tag":246,"props":9381,"children":9382},{"class":248,"line":353},[9383,9387,9391,9395,9399,9403,9407],{"type":19,"tag":246,"props":9384,"children":9385},{"style":8279},[9386],{"type":24,"value":8308},{"type":19,"tag":246,"props":9388,"children":9389},{"style":8285},[9390],{"type":24,"value":9191},{"type":19,"tag":246,"props":9392,"children":9393},{"style":8279},[9394],{"type":24,"value":663},{"type":19,"tag":246,"props":9396,"children":9397},{"style":253},[9398],{"type":24,"value":1883},{"type":19,"tag":246,"props":9400,"children":9401},{"style":660},[9402],{"type":24,"value":9113},{"type":19,"tag":246,"props":9404,"children":9405},{"style":1619},[9406],{"type":24,"value":9208},{"type":19,"tag":246,"props":9408,"children":9409},{"style":660},[9410],{"type":24,"value":9123},{"type":19,"tag":246,"props":9412,"children":9413},{"class":248,"line":363},[9414],{"type":19,"tag":246,"props":9415,"children":9416},{"style":259},[9417],{"type":24,"value":3436},{"type":19,"tag":246,"props":9419,"children":9420},{"class":248,"line":401},[9421],{"type":19,"tag":246,"props":9422,"children":9423},{"style":259},[9424],{"type":24,"value":8341},{"type":19,"tag":83,"props":9426,"children":9427},{},[9428,9429,9435,9437,9444,9445,9448,9449,9563,9566,9567],{"type":24,"value":9024},{"type":19,"tag":37,"props":9430,"children":9432},{"className":9431},[],[9433],{"type":24,"value":9434},"pnpm",{"type":24,"value":9436},", use ",{"type":19,"tag":51,"props":9438,"children":9441},{"href":9439,"rel":9440,"target":56},"https://pnpm.io/package_json#pnpmoverrides",[55,55],[9442],{"type":24,"value":9443},"pnpm.overrides",{"type":24,"value":1883},{"type":19,"tag":7650,"props":9446,"children":9447},{},[],{"type":24,"value":9052},{"type":19,"tag":236,"props":9450,"children":9452},{"className":8251,"code":9451,"language":8253,"meta":8,"style":8},"{\n  \"pnpm\": {\n    \"overrides\": {\n      \"vue-loader\": \"^15.10.0-beta.6\"\n    }\n  }\n}\n",[9453],{"type":19,"tag":37,"props":9454,"children":9455},{"__ignoreMap":8},[9456,9463,9486,9509,9541,9549,9556],{"type":19,"tag":246,"props":9457,"children":9458},{"class":248,"line":249},[9459],{"type":19,"tag":246,"props":9460,"children":9461},{"style":259},[9462],{"type":24,"value":8265},{"type":19,"tag":246,"props":9464,"children":9465},{"class":248,"line":292},[9466,9470,9474,9478,9482],{"type":19,"tag":246,"props":9467,"children":9468},{"style":8279},[9469],{"type":24,"value":8282},{"type":19,"tag":246,"props":9471,"children":9472},{"style":8285},[9473],{"type":24,"value":9434},{"type":19,"tag":246,"props":9475,"children":9476},{"style":8279},[9477],{"type":24,"value":663},{"type":19,"tag":246,"props":9479,"children":9480},{"style":253},[9481],{"type":24,"value":1883},{"type":19,"tag":246,"props":9483,"children":9484},{"style":259},[9485],{"type":24,"value":3046},{"type":19,"tag":246,"props":9487,"children":9488},{"class":248,"line":353},[9489,9493,9497,9501,9505],{"type":19,"tag":246,"props":9490,"children":9491},{"style":8279},[9492],{"type":24,"value":8308},{"type":19,"tag":246,"props":9494,"children":9495},{"style":8285},[9496],{"type":24,"value":9039},{"type":19,"tag":246,"props":9498,"children":9499},{"style":8279},[9500],{"type":24,"value":663},{"type":19,"tag":246,"props":9502,"children":9503},{"style":253},[9504],{"type":24,"value":1883},{"type":19,"tag":246,"props":9506,"children":9507},{"style":259},[9508],{"type":24,"value":3046},{"type":19,"tag":246,"props":9510,"children":9511},{"class":248,"line":363},[9512,9517,9521,9525,9529,9533,9537],{"type":19,"tag":246,"props":9513,"children":9514},{"style":8279},[9515],{"type":24,"value":9516},"      \"",{"type":19,"tag":246,"props":9518,"children":9519},{"style":8285},[9520],{"type":24,"value":8082},{"type":19,"tag":246,"props":9522,"children":9523},{"style":8279},[9524],{"type":24,"value":663},{"type":19,"tag":246,"props":9526,"children":9527},{"style":253},[9528],{"type":24,"value":1883},{"type":19,"tag":246,"props":9530,"children":9531},{"style":660},[9532],{"type":24,"value":9113},{"type":19,"tag":246,"props":9534,"children":9535},{"style":1619},[9536],{"type":24,"value":9118},{"type":19,"tag":246,"props":9538,"children":9539},{"style":660},[9540],{"type":24,"value":9123},{"type":19,"tag":246,"props":9542,"children":9543},{"class":248,"line":401},[9544],{"type":19,"tag":246,"props":9545,"children":9546},{"style":259},[9547],{"type":24,"value":9548},"    }\n",{"type":19,"tag":246,"props":9550,"children":9551},{"class":248,"line":409},[9552],{"type":19,"tag":246,"props":9553,"children":9554},{"style":259},[9555],{"type":24,"value":3436},{"type":19,"tag":246,"props":9557,"children":9558},{"class":248,"line":2155},[9559],{"type":19,"tag":246,"props":9560,"children":9561},{"style":259},[9562],{"type":24,"value":8341},{"type":19,"tag":7650,"props":9564,"children":9565},{},[],{"type":24,"value":9142},{"type":19,"tag":236,"props":9568,"children":9570},{"className":8251,"code":9569,"language":8253,"meta":8,"style":8},"{\n  \"pnpm\": {\n    \"overrides\": {\n      \"@vue/vue-loader-v15\": \"npm:vue-loader@^15.10.0-beta.6\"\n    }\n  }\n}\n",[9571],{"type":19,"tag":37,"props":9572,"children":9573},{"__ignoreMap":8},[9574,9581,9604,9627,9658,9665,9672],{"type":19,"tag":246,"props":9575,"children":9576},{"class":248,"line":249},[9577],{"type":19,"tag":246,"props":9578,"children":9579},{"style":259},[9580],{"type":24,"value":8265},{"type":19,"tag":246,"props":9582,"children":9583},{"class":248,"line":292},[9584,9588,9592,9596,9600],{"type":19,"tag":246,"props":9585,"children":9586},{"style":8279},[9587],{"type":24,"value":8282},{"type":19,"tag":246,"props":9589,"children":9590},{"style":8285},[9591],{"type":24,"value":9434},{"type":19,"tag":246,"props":9593,"children":9594},{"style":8279},[9595],{"type":24,"value":663},{"type":19,"tag":246,"props":9597,"children":9598},{"style":253},[9599],{"type":24,"value":1883},{"type":19,"tag":246,"props":9601,"children":9602},{"style":259},[9603],{"type":24,"value":3046},{"type":19,"tag":246,"props":9605,"children":9606},{"class":248,"line":353},[9607,9611,9615,9619,9623],{"type":19,"tag":246,"props":9608,"children":9609},{"style":8279},[9610],{"type":24,"value":8308},{"type":19,"tag":246,"props":9612,"children":9613},{"style":8285},[9614],{"type":24,"value":9039},{"type":19,"tag":246,"props":9616,"children":9617},{"style":8279},[9618],{"type":24,"value":663},{"type":19,"tag":246,"props":9620,"children":9621},{"style":253},[9622],{"type":24,"value":1883},{"type":19,"tag":246,"props":9624,"children":9625},{"style":259},[9626],{"type":24,"value":3046},{"type":19,"tag":246,"props":9628,"children":9629},{"class":248,"line":363},[9630,9634,9638,9642,9646,9650,9654],{"type":19,"tag":246,"props":9631,"children":9632},{"style":8279},[9633],{"type":24,"value":9516},{"type":19,"tag":246,"props":9635,"children":9636},{"style":8285},[9637],{"type":24,"value":9191},{"type":19,"tag":246,"props":9639,"children":9640},{"style":8279},[9641],{"type":24,"value":663},{"type":19,"tag":246,"props":9643,"children":9644},{"style":253},[9645],{"type":24,"value":1883},{"type":19,"tag":246,"props":9647,"children":9648},{"style":660},[9649],{"type":24,"value":9113},{"type":19,"tag":246,"props":9651,"children":9652},{"style":1619},[9653],{"type":24,"value":9208},{"type":19,"tag":246,"props":9655,"children":9656},{"style":660},[9657],{"type":24,"value":9123},{"type":19,"tag":246,"props":9659,"children":9660},{"class":248,"line":401},[9661],{"type":19,"tag":246,"props":9662,"children":9663},{"style":259},[9664],{"type":24,"value":9548},{"type":19,"tag":246,"props":9666,"children":9667},{"class":248,"line":409},[9668],{"type":19,"tag":246,"props":9669,"children":9670},{"style":259},[9671],{"type":24,"value":3436},{"type":19,"tag":246,"props":9673,"children":9674},{"class":248,"line":2155},[9675],{"type":19,"tag":246,"props":9676,"children":9677},{"style":259},[9678],{"type":24,"value":8341},{"type":19,"tag":83,"props":9680,"children":9681},{},[9682,9684,9694,9696,9701],{"type":24,"value":9683},"If you were previously using any libraries that rely on ",{"type":19,"tag":51,"props":9685,"children":9688},{"href":9686,"rel":9687,"target":56},"https://github.com/vueuse/vue-demi",[55,55],[9689],{"type":19,"tag":37,"props":9690,"children":9692},{"className":9691},[],[9693],{"type":24,"value":8099},{"type":24,"value":9695}," (e.g. VueUse or Pinia), you may need to remove lockfile and do a fresh npm install to upgrade to the latest version of ",{"type":19,"tag":37,"props":9697,"children":9699},{"className":9698},[],[9700],{"type":24,"value":8099},{"type":24,"value":61},{"type":19,"tag":83,"props":9703,"children":9704},{},[9705,9706,9710],{"type":24,"value":8176},{"type":19,"tag":98,"props":9707,"children":9708},{},[9709],{"type":24,"value":8181},{"type":24,"value":8183},{"type":19,"tag":151,"props":9712,"children":9713},{"id":8186},[9714],{"type":24,"value":4605},{"type":19,"tag":20,"props":9716,"children":9717},{},[9718,9719,9724,9725,9730],{"type":24,"value":8193},{"type":19,"tag":51,"props":9720,"children":9722},{"href":8196,"rel":9721,"target":56},[55,55],[9723],{"type":24,"value":8200},{"type":24,"value":8202},{"type":19,"tag":51,"props":9726,"children":9728},{"href":8205,"rel":9727,"target":56},[55,55],[9729],{"type":24,"value":8209},{"type":24,"value":61},{"type":19,"tag":20,"props":9732,"children":9733},{},[9734],{"type":24,"value":9735},"Note that the new plugin does not handle Vue-specific JSX / TSX transform, which is intentional. Vue 2 JSX / TSX transform should be handled in a separate, dedicated plugin.",{"type":19,"tag":151,"props":9737,"children":9738},{"id":8226},[9739],{"type":24,"value":8229},{"type":19,"tag":20,"props":9741,"children":9742},{},[9743,9744,9749,9750,9755],{"type":24,"value":8234},{"type":19,"tag":37,"props":9745,"children":9747},{"className":9746},[],[9748],{"type":24,"value":8240},{"type":24,"value":8242},{"type":19,"tag":37,"props":9751,"children":9753},{"className":9752},[],[9754],{"type":24,"value":950},{"type":24,"value":1883},{"type":19,"tag":236,"props":9757,"children":9758},{"className":8251,"code":8252,"language":8253,"meta":8,"style":8},[9759],{"type":19,"tag":37,"props":9760,"children":9761},{"__ignoreMap":8},[9762,9769,9776,9799,9822,9829],{"type":19,"tag":246,"props":9763,"children":9764},{"class":248,"line":249},[9765],{"type":19,"tag":246,"props":9766,"children":9767},{"style":259},[9768],{"type":24,"value":8265},{"type":19,"tag":246,"props":9770,"children":9771},{"class":248,"line":292},[9772],{"type":19,"tag":246,"props":9773,"children":9774},{"style":395},[9775],{"type":24,"value":8273},{"type":19,"tag":246,"props":9777,"children":9778},{"class":248,"line":353},[9779,9783,9787,9791,9795],{"type":19,"tag":246,"props":9780,"children":9781},{"style":8279},[9782],{"type":24,"value":8282},{"type":19,"tag":246,"props":9784,"children":9785},{"style":8285},[9786],{"type":24,"value":8288},{"type":19,"tag":246,"props":9788,"children":9789},{"style":8279},[9790],{"type":24,"value":663},{"type":19,"tag":246,"props":9792,"children":9793},{"style":253},[9794],{"type":24,"value":1883},{"type":19,"tag":246,"props":9796,"children":9797},{"style":259},[9798],{"type":24,"value":3046},{"type":19,"tag":246,"props":9800,"children":9801},{"class":248,"line":363},[9802,9806,9810,9814,9818],{"type":19,"tag":246,"props":9803,"children":9804},{"style":8279},[9805],{"type":24,"value":8308},{"type":19,"tag":246,"props":9807,"children":9808},{"style":8285},[9809],{"type":24,"value":8313},{"type":19,"tag":246,"props":9811,"children":9812},{"style":8279},[9813],{"type":24,"value":663},{"type":19,"tag":246,"props":9815,"children":9816},{"style":253},[9817],{"type":24,"value":1883},{"type":19,"tag":246,"props":9819,"children":9820},{"style":281},[9821],{"type":24,"value":8326},{"type":19,"tag":246,"props":9823,"children":9824},{"class":248,"line":401},[9825],{"type":19,"tag":246,"props":9826,"children":9827},{"style":259},[9828],{"type":24,"value":3436},{"type":19,"tag":246,"props":9830,"children":9831},{"class":248,"line":409},[9832],{"type":19,"tag":246,"props":9833,"children":9834},{"style":259},[9835],{"type":24,"value":8341},{"type":19,"tag":72,"props":9837,"children":9838},{"id":8355},[9839],{"type":24,"value":8358},{"type":19,"tag":20,"props":9841,"children":9842},{},[9843],{"type":24,"value":9844},"2.7 stable is scheduled to land around end of June 2022. As stated before, it will be the final minor release of Vue 2.x. Once 2.7 is released as stable, Vue 2 will no longer receive new features, and will enter LTS (long-term support) which lasts for 18 months.",{"type":19,"tag":20,"props":9846,"children":9847},{},[9848,9850,9855,9857,9862],{"type":24,"value":9849},"This means ",{"type":19,"tag":98,"props":9851,"children":9852},{},[9853],{"type":24,"value":9854},"Vue 2 will reach End of Life by the end of 2023",{"type":24,"value":9856},". We believe this should provide plenty of time for most of the ecosystem to migrate over to Vue 3. However, we also understand that there could be teams or projects that cannot upgrade by this timeline while still need to fullfil security and compliance requirements. We are planning to provide extended support for Vue 2 for teams with such needs - if your team expects to be using Vue 2 beyond end of 2023, make sure to plan head and register your interest ",{"type":19,"tag":51,"props":9858,"children":9860},{"href":6091,"rel":9859,"target":56},[55,55],[9861],{"type":24,"value":6095},{"type":24,"value":61},{"type":19,"tag":1103,"props":9864,"children":9865},{},[9866],{"type":24,"value":1107},{"title":8,"searchDepth":292,"depth":292,"links":9868},[9869,9873,9878],{"id":7514,"depth":292,"text":7517,"children":9870},[9871,9872],{"id":7665,"depth":353,"text":7668},{"id":7753,"depth":353,"text":7756},{"id":8888,"depth":292,"text":8891,"children":9874},[9875,9876,9877],{"id":8899,"depth":353,"text":8902},{"id":8186,"depth":353,"text":4605},{"id":8226,"depth":353,"text":8229},{"id":8355,"depth":292,"text":8358},"content:blog:vue-2-7-beta.md","blog/vue-2-7-beta.md","blog/vue-2-7-beta",{"loc":8491},{"_path":5062,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":9884,"description":9885,"date":9886,"author":12,"gravatar":13,"twitter":14,"excerpt":9887,"body":9901,"_type":1125,"_id":10750,"_source":1127,"_file":10751,"_stem":10752,"_extension":1130,"sitemap":10753},"Vue 3 as the New Default","TL;DR: Vue 3 is now the new default version as of Monday, February 7, 2022!","2022-01-20",{"type":16,"children":9888},[9889],{"type":19,"tag":20,"props":9890,"children":9891},{},[9892,9894,9899],{"type":24,"value":9893},"TL;DR: Vue 3 is now the new default version as of ",{"type":19,"tag":98,"props":9895,"children":9896},{},[9897],{"type":24,"value":9898},"Monday, February 7, 2022",{"type":24,"value":9900},"!",{"type":16,"children":9902,"toc":10734},[9903,9912,9925,9928,9934,9939,10004,10009,10015,10020,10025,10031,10041,10046,10120,10141,10147,10158,10164,10214,10220,10225,10253,10258,10286,10292,10313,10422,10440,10445,10451,10473,10486,10491,10497,10509,10558,10563,10576,10596,10730],{"type":19,"tag":20,"props":9904,"children":9905},{},[9906,9907,9911],{"type":24,"value":9893},{"type":19,"tag":98,"props":9908,"children":9909},{},[9910],{"type":24,"value":9898},{"type":24,"value":9900},{"type":19,"tag":20,"props":9913,"children":9914},{},[9915,9917,9923],{"type":24,"value":9916},"Make sure to read the ",{"type":19,"tag":51,"props":9918,"children":9920},{"href":9919},"/blog/vue-3-as-the-new-default#potential-required-actions",[9921],{"type":24,"value":9922},"Potential Required Actions",{"type":24,"value":9924}," section to see if you need to make certain changes before the switch to avoid breakage.",{"type":19,"tag":63,"props":9926,"children":9927},{},[],{"type":19,"tag":72,"props":9929,"children":9931},{"id":9930},"from-a-library-to-a-framework",[9932],{"type":24,"value":9933},"From a Library to a Framework",{"type":19,"tag":20,"props":9935,"children":9936},{},[9937],{"type":24,"value":9938},"When Vue first started, it was just a runtime library. Over the years, it has evolved into a framework that encompasses many sub projects:",{"type":19,"tag":89,"props":9940,"children":9941},{},[9942,9954,9959,9964,9969,9974,9979,9984,9989,9994,9999],{"type":19,"tag":83,"props":9943,"children":9944},{},[9945,9947,9952],{"type":24,"value":9946},"The core library, i.e. the ",{"type":19,"tag":37,"props":9948,"children":9950},{"className":9949},[],[9951],{"type":24,"value":625},{"type":24,"value":9953}," npm package",{"type":19,"tag":83,"props":9955,"children":9956},{},[9957],{"type":24,"value":9958},"The documentation, with enough content to be considered a book",{"type":19,"tag":83,"props":9960,"children":9961},{},[9962],{"type":24,"value":9963},"The build toolchain, i.e. Vue CLI, vue-loader and other supporting packages",{"type":19,"tag":83,"props":9965,"children":9966},{},[9967],{"type":24,"value":9968},"Vue Router for building SPA",{"type":19,"tag":83,"props":9970,"children":9971},{},[9972],{"type":24,"value":9973},"Vuex for state management",{"type":19,"tag":83,"props":9975,"children":9976},{},[9977],{"type":24,"value":9978},"Browser devtools extension for debugging and profiling",{"type":19,"tag":83,"props":9980,"children":9981},{},[9982],{"type":24,"value":9983},"Vetur, the VSCode extension for Single-File Component IDE support",{"type":19,"tag":83,"props":9985,"children":9986},{},[9987],{"type":24,"value":9988},"ESLint plugin for static style / error checking",{"type":19,"tag":83,"props":9990,"children":9991},{},[9992],{"type":24,"value":9993},"Vue Test Utils for component testing",{"type":19,"tag":83,"props":9995,"children":9996},{},[9997],{"type":24,"value":9998},"Custom JSX transforms that leverages Vue's runtime features",{"type":19,"tag":83,"props":10000,"children":10001},{},[10002],{"type":24,"value":10003},"VuePress for Vue-based static site generation",{"type":19,"tag":20,"props":10005,"children":10006},{},[10007],{"type":24,"value":10008},"This is only possible because Vue is a community-driven project. Many of these projects were started by community members who later became Vue team members. The rest were originally started by me, but are now almost entirely maintained by the team (with the exception of the core library).",{"type":19,"tag":72,"props":10010,"children":10012},{"id":10011},"soft-launch-of-vue-3",[10013],{"type":24,"value":10014},"Soft Launch of Vue 3",{"type":19,"tag":20,"props":10016,"children":10017},{},[10018],{"type":24,"value":10019},"With the core releasing a new major version, all the other parts of the framework needed to move forward together. We also needed to provide a migration path for Vue 2 users. This was a massive undertaking for a community-drive team like Vue. When Vue 3 core was ready, most other parts of the framework were either in beta or still awaiting update. We decided to go ahead and release the core so that the early adopters, library authors and higher-level frameworks can start building with it while we worked on the rest of the framework.",{"type":19,"tag":20,"props":10021,"children":10022},{},[10023],{"type":24,"value":10024},"At the same time, we kept Vue 2 as the default for documentation and npm installs. This is because we knew that for many users, Vue 2 still provided a more coherent and comprehensive experience until other parts of Vue 3 are refined.",{"type":19,"tag":72,"props":10026,"children":10028},{"id":10027},"the-new-vue",[10029],{"type":24,"value":10030},"The New Vue",{"type":19,"tag":20,"props":10032,"children":10033},{},[10034,10036,10040],{"type":24,"value":10035},"This soft launch process took longer than we hoped, but we are finally here: we are excited to announce that Vue 3 will become the new default version on ",{"type":19,"tag":98,"props":10037,"children":10038},{},[10039],{"type":24,"value":9898},{"type":24,"value":61},{"type":19,"tag":20,"props":10042,"children":10043},{},[10044],{"type":24,"value":10045},"Outside of Vue core, we have improved almost every aspect of the framework:",{"type":19,"tag":89,"props":10047,"children":10048},{},[10049,10061,10071,10083,10094,10106],{"type":19,"tag":83,"props":10050,"children":10051},{},[10052,10054,10059],{"type":24,"value":10053},"Blazing fast, ",{"type":19,"tag":51,"props":10055,"children":10057},{"href":4601,"rel":10056,"target":56},[55,55],[10058],{"type":24,"value":4605},{"type":24,"value":10060},"-powered build toolchain",{"type":19,"tag":83,"props":10062,"children":10063},{},[10064,10066],{"type":24,"value":10065},"More ergonomic Composition API syntax via ",{"type":19,"tag":37,"props":10067,"children":10069},{"className":10068},[],[10070],{"type":24,"value":544},{"type":19,"tag":83,"props":10072,"children":10073},{},[10074,10076],{"type":24,"value":10075},"Improved TypeScript IDE support for Single File Components via ",{"type":19,"tag":51,"props":10077,"children":10080},{"href":10078,"rel":10079,"target":56},"https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar",[55,55],[10081],{"type":24,"value":10082},"Volar",{"type":19,"tag":83,"props":10084,"children":10085},{},[10086,10088],{"type":24,"value":10087},"Command line type checking for SFCs via ",{"type":19,"tag":51,"props":10089,"children":10092},{"href":10090,"rel":10091,"target":56},"https://github.com/johnsoncodehk/volar/tree/master/packages/vue-tsc",[55,55],[10093],{"type":24,"value":2853},{"type":19,"tag":83,"props":10095,"children":10096},{},[10097,10099],{"type":24,"value":10098},"Simpler state management via ",{"type":19,"tag":51,"props":10100,"children":10103},{"href":10101,"rel":10102,"target":56},"https://pinia.vuejs.org/",[55,55],[10104],{"type":24,"value":10105},"Pinia",{"type":19,"tag":83,"props":10107,"children":10108},{},[10109,10111,10118],{"type":24,"value":10110},"New devtools extension with simultaneous Vue 2 / Vue 3 support and a ",{"type":19,"tag":51,"props":10112,"children":10115},{"href":10113,"rel":10114,"target":56},"https://devtools.vuejs.org/plugin/plugins-guide.html",[55,55],[10116],{"type":24,"value":10117},"plugin system",{"type":24,"value":10119}," that allows community libraries to hook into the devtools panels",{"type":19,"tag":20,"props":10121,"children":10122},{},[10123,10125,10132,10134,10139],{"type":24,"value":10124},"We also completely reworked the main documentation. ",{"type":19,"tag":51,"props":10126,"children":10129},{"href":10127,"rel":10128,"target":56},"https://staging.vuejs.org",[55,55],[10130],{"type":24,"value":10131},"The new vuejs.org",{"type":24,"value":10133}," (currently in staging) will provide updated framework overview and recommendations, flexible learning paths for users from different backgrounds, the ability to toggle between Options API and Composition API throughout the guide and examples, and many new deep dive sections. It's also ",{"type":19,"tag":1355,"props":10135,"children":10136},{},[10137],{"type":24,"value":10138},"very",{"type":24,"value":10140}," fast - which we will discuss in more details in a separate blog post soon.",{"type":19,"tag":72,"props":10142,"children":10144},{"id":10143},"version-switch-details",[10145],{"type":24,"value":10146},"Version Switch Details",{"type":19,"tag":20,"props":10148,"children":10149},{},[10150,10152,10157],{"type":24,"value":10151},"Here are the details on what we mean by \"the new default\". In addition, please read the ",{"type":19,"tag":51,"props":10153,"children":10155},{"href":10154},"#potential-required-actions",[10156],{"type":24,"value":9922},{"type":24,"value":9924},{"type":19,"tag":151,"props":10159,"children":10161},{"id":10160},"npm-dist-tags",[10162],{"type":24,"value":10163},"npm dist tags",{"type":19,"tag":89,"props":10165,"children":10166},{},[10167,10178],{"type":19,"tag":83,"props":10168,"children":10169},{},[10170,10176],{"type":19,"tag":37,"props":10171,"children":10173},{"className":10172},[],[10174],{"type":24,"value":10175},"npm install vue",{"type":24,"value":10177}," now installs Vue 3 by default.",{"type":19,"tag":83,"props":10179,"children":10180},{},[10181,10182,10188,10190,10195,10196,10201,10202,10207,10208,10213],{"type":24,"value":7640},{"type":19,"tag":37,"props":10183,"children":10185},{"className":10184},[],[10186],{"type":24,"value":10187},"latest",{"type":24,"value":10189}," dist tag of all other official npm packages now point to Vue 3 compatible versions, including ",{"type":19,"tag":37,"props":10191,"children":10193},{"className":10192},[],[10194],{"type":24,"value":1204},{"type":24,"value":474},{"type":19,"tag":37,"props":10197,"children":10199},{"className":10198},[],[10200],{"type":24,"value":1216},{"type":24,"value":474},{"type":19,"tag":37,"props":10203,"children":10205},{"className":10204},[],[10206],{"type":24,"value":8082},{"type":24,"value":5174},{"type":19,"tag":37,"props":10209,"children":10211},{"className":10210},[],[10212],{"type":24,"value":8049},{"type":24,"value":61},{"type":19,"tag":151,"props":10215,"children":10217},{"id":10216},"official-docs-and-sites",[10218],{"type":24,"value":10219},"Official docs and sites",{"type":19,"tag":20,"props":10221,"children":10222},{},[10223],{"type":24,"value":10224},"All documentation and official sites now default to Vue 3 versions. These include:",{"type":19,"tag":89,"props":10226,"children":10227},{},[10228,10233,10238,10243,10248],{"type":19,"tag":83,"props":10229,"children":10230},{},[10231],{"type":24,"value":10232},"vuejs.org",{"type":19,"tag":83,"props":10234,"children":10235},{},[10236],{"type":24,"value":10237},"router.vuejs.org",{"type":19,"tag":83,"props":10239,"children":10240},{},[10241],{"type":24,"value":10242},"vuex.vuejs.org",{"type":19,"tag":83,"props":10244,"children":10245},{},[10246],{"type":24,"value":10247},"vue-test-utils.vuejs.org (moved to test-utils.vuejs.org)",{"type":19,"tag":83,"props":10249,"children":10250},{},[10251],{"type":24,"value":10252},"template-explorer.vuejs.org",{"type":19,"tag":20,"props":10254,"children":10255},{},[10256],{"type":24,"value":10257},"The current Vue 2 versions of these sites have been moved to new addresses (the version prefixes indicate the libraries' respective versions, not Vue core's):",{"type":19,"tag":89,"props":10259,"children":10260},{},[10261,10266,10271,10276,10281],{"type":19,"tag":83,"props":10262,"children":10263},{},[10264],{"type":24,"value":10265},"vuejs.org -> v2.vuejs.org (old v2 URLs will auto redirect to the new address)",{"type":19,"tag":83,"props":10267,"children":10268},{},[10269],{"type":24,"value":10270},"router.vuejs.org -> v3.router.vuejs.org",{"type":19,"tag":83,"props":10272,"children":10273},{},[10274],{"type":24,"value":10275},"vuex.vuejs.org -> v3.vuex.vuejs.org",{"type":19,"tag":83,"props":10277,"children":10278},{},[10279],{"type":24,"value":10280},"vue-test-utils.vuejs.org -> v1.test-utils.vuejs.org",{"type":19,"tag":83,"props":10282,"children":10283},{},[10284],{"type":24,"value":10285},"template-explorer.vuejs.org -> v2.template-explorer.vuejs.org",{"type":19,"tag":151,"props":10287,"children":10289},{"id":10288},"github-repos",[10290],{"type":24,"value":10291},"GitHub repos",{"type":19,"tag":20,"props":10293,"children":10294},{},[10295,10297,10303,10305,10311],{"type":24,"value":10296},"All GitHub repos under the ",{"type":19,"tag":37,"props":10298,"children":10300},{"className":10299},[],[10301],{"type":24,"value":10302},"vuejs",{"type":24,"value":10304}," organization have switched to Vue 3 versions in the default branch. In addition, we have renamed the following repos to remove ",{"type":19,"tag":37,"props":10306,"children":10308},{"className":10307},[],[10309],{"type":24,"value":10310},"next",{"type":24,"value":10312}," in their names:",{"type":19,"tag":89,"props":10314,"children":10315},{},[10316,10338,10359,10380,10401],{"type":19,"tag":83,"props":10317,"children":10318},{},[10319,10325,10327],{"type":19,"tag":37,"props":10320,"children":10322},{"className":10321},[],[10323],{"type":24,"value":10324},"vuejs/vue-next",{"type":24,"value":10326}," -> ",{"type":19,"tag":51,"props":10328,"children":10331},{"href":10329,"rel":10330,"target":56},"https://github.com/vuejs/core",[55,55],[10332],{"type":19,"tag":37,"props":10333,"children":10335},{"className":10334},[],[10336],{"type":24,"value":10337},"vuejs/core",{"type":19,"tag":83,"props":10339,"children":10340},{},[10341,10347,10348],{"type":19,"tag":37,"props":10342,"children":10344},{"className":10343},[],[10345],{"type":24,"value":10346},"vuejs/vue-router-next",{"type":24,"value":10326},{"type":19,"tag":51,"props":10349,"children":10352},{"href":10350,"rel":10351,"target":56},"https://github.com/vuejs/router",[55,55],[10353],{"type":19,"tag":37,"props":10354,"children":10356},{"className":10355},[],[10357],{"type":24,"value":10358},"vuejs/router",{"type":19,"tag":83,"props":10360,"children":10361},{},[10362,10368,10369],{"type":19,"tag":37,"props":10363,"children":10365},{"className":10364},[],[10366],{"type":24,"value":10367},"vuejs/docs-next",{"type":24,"value":10326},{"type":19,"tag":51,"props":10370,"children":10373},{"href":10371,"rel":10372,"target":56},"https://github.com/vuejs/docs",[55,55],[10374],{"type":19,"tag":37,"props":10375,"children":10377},{"className":10376},[],[10378],{"type":24,"value":10379},"vuejs/docs",{"type":19,"tag":83,"props":10381,"children":10382},{},[10383,10389,10390],{"type":19,"tag":37,"props":10384,"children":10386},{"className":10385},[],[10387],{"type":24,"value":10388},"vuejs/vue-test-utils-next",{"type":24,"value":10326},{"type":19,"tag":51,"props":10391,"children":10394},{"href":10392,"rel":10393,"target":56},"https://github.com/vuejs/test-utils",[55,55],[10395],{"type":19,"tag":37,"props":10396,"children":10398},{"className":10397},[],[10399],{"type":24,"value":10400},"vuejs/test-utils",{"type":19,"tag":83,"props":10402,"children":10403},{},[10404,10410,10411],{"type":19,"tag":37,"props":10405,"children":10407},{"className":10406},[],[10408],{"type":24,"value":10409},"vuejs/jsx-next",{"type":24,"value":10326},{"type":19,"tag":51,"props":10412,"children":10415},{"href":10413,"rel":10414,"target":56},"https://github.com/vuejs/babel-plugin-jsx",[55,55],[10416],{"type":19,"tag":37,"props":10417,"children":10419},{"className":10418},[],[10420],{"type":24,"value":10421},"vuejs/babel-plugin-jsx",{"type":19,"tag":20,"props":10423,"children":10424},{},[10425,10427,10439],{"type":24,"value":10426},"Translation repos for the main documentation are moved to the ",{"type":19,"tag":51,"props":10428,"children":10431},{"href":10429,"rel":10430,"target":56},"https://github.com/vuejs-translations",[55,55],[10432,10438],{"type":19,"tag":37,"props":10433,"children":10435},{"className":10434},[],[10436],{"type":24,"value":10437},"vuejs-translations",{"type":24,"value":4647},{"type":24,"value":61},{"type":19,"tag":20,"props":10441,"children":10442},{},[10443],{"type":24,"value":10444},"GitHub handles repo directs automatically, so previous links to source code and issues should still work.",{"type":19,"tag":151,"props":10446,"children":10448},{"id":10447},"devtools-extension",[10449],{"type":24,"value":10450},"Devtools extension",{"type":19,"tag":20,"props":10452,"children":10453},{},[10454,10456,10463,10465,10472],{"type":24,"value":10455},"Devtools v6, which was previously published under the ",{"type":19,"tag":51,"props":10457,"children":10460},{"href":10458,"rel":10459,"target":56},"https://chrome.google.com/webstore/detail/vuejs-devtools/ljjemllljcmogpfapbkkighbhhppjdbg",[55,55],[10461],{"type":24,"value":10462},"beta channel",{"type":24,"value":10464}," on Chrome Web Store, is now published under the ",{"type":19,"tag":51,"props":10466,"children":10469},{"href":10467,"rel":10468,"target":56},"https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd",[55,55],[10470],{"type":24,"value":10471},"stable channel",{"type":24,"value":61},{"type":19,"tag":20,"props":10474,"children":10475},{},[10476,10478,10485],{"type":24,"value":10477},"The previous version of the devtools extension is still be available and has been moved to the ",{"type":19,"tag":51,"props":10479,"children":10482},{"href":10480,"rel":10481,"target":56},"https://chrome.google.com/webstore/detail/vuejs-devtools/iaajmlceplecbljialhhkmedjlpdblhp",[55,55],[10483],{"type":24,"value":10484},"legacy channel",{"type":24,"value":61},{"type":19,"tag":72,"props":10487,"children":10489},{"id":10488},"potential-required-actions",[10490],{"type":24,"value":9922},{"type":19,"tag":151,"props":10492,"children":10494},{"id":10493},"unversioned-cdn-usage",[10495],{"type":24,"value":10496},"Unversioned CDN Usage",{"type":19,"tag":20,"props":10498,"children":10499},{},[10500,10502,10508],{"type":24,"value":10501},"If you are using Vue 2 via a CDN link without specifying a version, make sure to specify a version range via ",{"type":19,"tag":37,"props":10503,"children":10505},{"className":10504},[],[10506],{"type":24,"value":10507},"@2",{"type":24,"value":1883},{"type":19,"tag":236,"props":10510,"children":10514},{"className":10511,"code":10512,"language":10513,"meta":8,"style":8},"language-diff shiki shiki-themes dracula-soft","- \u003Cscript src=\"https://unpkg.com/vue\">\u003C/script>\n+ \u003Cscript src=\"https://unpkg.com/vue@2\">\u003C/script>\n\n- \u003Cscript src=\"https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js\">\u003C/script>\n+ \u003Cscript src=\"https://cdn.jsdelivr.net/npm/vue@2/dist/vue.min.js\">\u003C/script>\n","diff",[10515],{"type":19,"tag":37,"props":10516,"children":10517},{"__ignoreMap":8},[10518,10527,10535,10542,10550],{"type":19,"tag":246,"props":10519,"children":10520},{"class":248,"line":249},[10521],{"type":19,"tag":246,"props":10522,"children":10524},{"style":10523},"--shiki-default:#EE6666",[10525],{"type":24,"value":10526},"- \u003Cscript src=\"https://unpkg.com/vue\">\u003C/script>\n",{"type":19,"tag":246,"props":10528,"children":10529},{"class":248,"line":292},[10530],{"type":19,"tag":246,"props":10531,"children":10532},{"style":270},[10533],{"type":24,"value":10534},"+ \u003Cscript src=\"https://unpkg.com/vue@2\">\u003C/script>\n",{"type":19,"tag":246,"props":10536,"children":10537},{"class":248,"line":353},[10538],{"type":19,"tag":246,"props":10539,"children":10540},{"emptyLinePlaceholder":357},[10541],{"type":24,"value":360},{"type":19,"tag":246,"props":10543,"children":10544},{"class":248,"line":363},[10545],{"type":19,"tag":246,"props":10546,"children":10547},{"style":10523},[10548],{"type":24,"value":10549},"- \u003Cscript src=\"https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js\">\u003C/script>\n",{"type":19,"tag":246,"props":10551,"children":10552},{"class":248,"line":401},[10553],{"type":19,"tag":246,"props":10554,"children":10555},{"style":270},[10556],{"type":24,"value":10557},"+ \u003Cscript src=\"https://cdn.jsdelivr.net/npm/vue@2/dist/vue.min.js\">\u003C/script>\n",{"type":19,"tag":20,"props":10559,"children":10560},{},[10561],{"type":24,"value":10562},"Note: even if using Vue 3, you should also always specify a version range in production to avoid accidentally loading future major versions.",{"type":19,"tag":151,"props":10564,"children":10566},{"id":10565},"npm-latest-tag",[10567,10569,10574],{"type":24,"value":10568},"NPM ",{"type":19,"tag":37,"props":10570,"children":10572},{"className":10571},[],[10573],{"type":24,"value":10187},{"type":24,"value":10575}," Tag",{"type":19,"tag":20,"props":10577,"children":10578},{},[10579,10581,10586,10588,10594],{"type":24,"value":10580},"If you are installing Vue or other official libraries from npm using the ",{"type":19,"tag":37,"props":10582,"children":10584},{"className":10583},[],[10585],{"type":24,"value":10187},{"type":24,"value":10587}," tag or ",{"type":19,"tag":37,"props":10589,"children":10591},{"className":10590},[],[10592],{"type":24,"value":10593},"*",{"type":24,"value":10595},", please update to explicitly use Vue 2 compatible versions:",{"type":19,"tag":236,"props":10597,"children":10599},{"className":10511,"code":10598,"language":10513,"meta":8,"style":8},"{\n  \"dependencies\": {\n-   \"vue\": \"latest\",\n+   \"vue\": \"^2.6.14\",\n-   \"vue-router\": \"latest\",\n+   \"vue-router\": \"^3.5.3\",\n-   \"vuex\": \"latest\"\n+   \"vuex\": \"^3.6.2\"\n  },\n  \"devDependencies\": {\n-   \"vue-loader\": \"latest\",\n+   \"vue-loader\": \"^15.9.8\",\n-   \"@vue/test-utils\": \"latest\"\n+   \"@vue/test-utils\": \"^1.3.0\"\n  }\n}\n",[10600],{"type":19,"tag":37,"props":10601,"children":10602},{"__ignoreMap":8},[10603,10610,10618,10626,10634,10642,10650,10658,10666,10674,10682,10690,10698,10706,10714,10722],{"type":19,"tag":246,"props":10604,"children":10605},{"class":248,"line":249},[10606],{"type":19,"tag":246,"props":10607,"children":10608},{"style":259},[10609],{"type":24,"value":8265},{"type":19,"tag":246,"props":10611,"children":10612},{"class":248,"line":292},[10613],{"type":19,"tag":246,"props":10614,"children":10615},{"style":259},[10616],{"type":24,"value":10617},"  \"dependencies\": {\n",{"type":19,"tag":246,"props":10619,"children":10620},{"class":248,"line":353},[10621],{"type":19,"tag":246,"props":10622,"children":10623},{"style":10523},[10624],{"type":24,"value":10625},"-   \"vue\": \"latest\",\n",{"type":19,"tag":246,"props":10627,"children":10628},{"class":248,"line":363},[10629],{"type":19,"tag":246,"props":10630,"children":10631},{"style":270},[10632],{"type":24,"value":10633},"+   \"vue\": \"^2.6.14\",\n",{"type":19,"tag":246,"props":10635,"children":10636},{"class":248,"line":401},[10637],{"type":19,"tag":246,"props":10638,"children":10639},{"style":10523},[10640],{"type":24,"value":10641},"-   \"vue-router\": \"latest\",\n",{"type":19,"tag":246,"props":10643,"children":10644},{"class":248,"line":409},[10645],{"type":19,"tag":246,"props":10646,"children":10647},{"style":270},[10648],{"type":24,"value":10649},"+   \"vue-router\": \"^3.5.3\",\n",{"type":19,"tag":246,"props":10651,"children":10652},{"class":248,"line":2155},[10653],{"type":19,"tag":246,"props":10654,"children":10655},{"style":10523},[10656],{"type":24,"value":10657},"-   \"vuex\": \"latest\"\n",{"type":19,"tag":246,"props":10659,"children":10660},{"class":248,"line":3057},[10661],{"type":19,"tag":246,"props":10662,"children":10663},{"style":270},[10664],{"type":24,"value":10665},"+   \"vuex\": \"^3.6.2\"\n",{"type":19,"tag":246,"props":10667,"children":10668},{"class":248,"line":3066},[10669],{"type":19,"tag":246,"props":10670,"children":10671},{"style":259},[10672],{"type":24,"value":10673},"  },\n",{"type":19,"tag":246,"props":10675,"children":10676},{"class":248,"line":3111},[10677],{"type":19,"tag":246,"props":10678,"children":10679},{"style":259},[10680],{"type":24,"value":10681},"  \"devDependencies\": {\n",{"type":19,"tag":246,"props":10683,"children":10684},{"class":248,"line":3120},[10685],{"type":19,"tag":246,"props":10686,"children":10687},{"style":10523},[10688],{"type":24,"value":10689},"-   \"vue-loader\": \"latest\",\n",{"type":19,"tag":246,"props":10691,"children":10692},{"class":248,"line":3136},[10693],{"type":19,"tag":246,"props":10694,"children":10695},{"style":270},[10696],{"type":24,"value":10697},"+   \"vue-loader\": \"^15.9.8\",\n",{"type":19,"tag":246,"props":10699,"children":10700},{"class":248,"line":3144},[10701],{"type":19,"tag":246,"props":10702,"children":10703},{"style":10523},[10704],{"type":24,"value":10705},"-   \"@vue/test-utils\": \"latest\"\n",{"type":19,"tag":246,"props":10707,"children":10708},{"class":248,"line":3544},[10709],{"type":19,"tag":246,"props":10710,"children":10711},{"style":270},[10712],{"type":24,"value":10713},"+   \"@vue/test-utils\": \"^1.3.0\"\n",{"type":19,"tag":246,"props":10715,"children":10717},{"class":248,"line":10716},15,[10718],{"type":19,"tag":246,"props":10719,"children":10720},{"style":259},[10721],{"type":24,"value":3436},{"type":19,"tag":246,"props":10723,"children":10725},{"class":248,"line":10724},16,[10726],{"type":19,"tag":246,"props":10727,"children":10728},{"style":259},[10729],{"type":24,"value":8341},{"type":19,"tag":1103,"props":10731,"children":10732},{},[10733],{"type":24,"value":1107},{"title":8,"searchDepth":292,"depth":292,"links":10735},[10736,10737,10738,10739,10745],{"id":9930,"depth":292,"text":9933},{"id":10011,"depth":292,"text":10014},{"id":10027,"depth":292,"text":10030},{"id":10143,"depth":292,"text":10146,"children":10740},[10741,10742,10743,10744],{"id":10160,"depth":353,"text":10163},{"id":10216,"depth":353,"text":10219},{"id":10288,"depth":353,"text":10291},{"id":10447,"depth":353,"text":10450},{"id":10488,"depth":292,"text":9922,"children":10746},[10747,10748],{"id":10493,"depth":353,"text":10496},{"id":10565,"depth":353,"text":10749},"NPM latest Tag","content:blog:vue-3-as-the-new-default.md","blog/vue-3-as-the-new-default.md","blog/vue-3-as-the-new-default",{"loc":5062},{"_path":10755,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":10756,"description":10757,"date":10758,"author":12,"gravatar":13,"twitter":14,"excerpt":10759,"body":10765,"_type":1125,"_id":11725,"_source":1127,"_file":11726,"_stem":11727,"_extension":1130,"sitemap":11728},"/blog/vue-3-2","Vue 3.2 Released!","We are excited to announce the release of Vue.js 3.2 \"Quintessential Quintuplets\"! This release includes many significant new features and performance improvements, and contains no breaking changes.","2021-08-05",{"type":16,"children":10760},[10761],{"type":19,"tag":20,"props":10762,"children":10763},{},[10764],{"type":24,"value":10757},{"type":16,"children":10766,"toc":11718},[10767,10771,10777,10790,10822,10827,11197,11211,11240,11259,11265,11287,11437,11450,11454,11468,11501,11506,11541,11576,11595,11603,11609,11637,11665,11671,11684,11698,11701,11714],{"type":19,"tag":20,"props":10768,"children":10769},{},[10770],{"type":24,"value":10757},{"type":19,"tag":72,"props":10772,"children":10774},{"id":10773},"new-sfc-features",[10775],{"type":24,"value":10776},"New SFC Features",{"type":19,"tag":20,"props":10778,"children":10779},{},[10780,10782,10788],{"type":24,"value":10781},"Two new features for Single File Components (SFCs, aka ",{"type":19,"tag":37,"props":10783,"children":10785},{"className":10784},[],[10786],{"type":24,"value":10787},".vue",{"type":24,"value":10789}," files) have graduated from experimental status and are now considered stable:",{"type":19,"tag":89,"props":10791,"children":10792},{},[10793,10803],{"type":19,"tag":83,"props":10794,"children":10795},{},[10796,10801],{"type":19,"tag":37,"props":10797,"children":10799},{"className":10798},[],[10800],{"type":24,"value":544},{"type":24,"value":10802}," is a compile-time syntactic sugar that greatly improves the ergonomics when using Composition API inside SFCs.",{"type":19,"tag":83,"props":10804,"children":10805},{},[10806,10812,10814,10820],{"type":19,"tag":37,"props":10807,"children":10809},{"className":10808},[],[10810],{"type":24,"value":10811},"\u003Cstyle> v-bind",{"type":24,"value":10813}," enables component state-driven dynamic CSS values in SFC ",{"type":19,"tag":37,"props":10815,"children":10817},{"className":10816},[],[10818],{"type":24,"value":10819},"\u003Cstyle>",{"type":24,"value":10821}," tags.",{"type":19,"tag":20,"props":10823,"children":10824},{},[10825],{"type":24,"value":10826},"Here is an example component using these two new features together:",{"type":19,"tag":236,"props":10828,"children":10830},{"className":623,"code":10829,"language":625,"meta":8,"style":8},"\u003Cscript setup>\n  import { ref } from 'vue'\n\n  const color = ref('red')\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cbutton @click=\"color = color === 'red' ? 'green' : 'red'\">\n    Color is: {{ color }}\n  \u003C/button>\n\u003C/template>\n\n\u003Cstyle scoped>\n  button {\n    color: v-bind(color);\n  }\n\u003C/style>\n",[10831],{"type":19,"tag":37,"props":10832,"children":10833},{"__ignoreMap":8},[10834,10853,10881,10888,10929,10944,10951,10966,11061,11082,11098,11113,11120,11140,11152,11174,11181],{"type":19,"tag":246,"props":10835,"children":10836},{"class":248,"line":249},[10837,10841,10845,10849],{"type":19,"tag":246,"props":10838,"children":10839},{"style":259},[10840],{"type":24,"value":637},{"type":19,"tag":246,"props":10842,"children":10843},{"style":253},[10844],{"type":24,"value":1598},{"type":19,"tag":246,"props":10846,"children":10847},{"style":650},[10848],{"type":24,"value":1603},{"type":19,"tag":246,"props":10850,"children":10851},{"style":259},[10852],{"type":24,"value":1631},{"type":19,"tag":246,"props":10854,"children":10855},{"class":248,"line":292},[10856,10860,10865,10869,10873,10877],{"type":19,"tag":246,"props":10857,"children":10858},{"style":253},[10859],{"type":24,"value":1639},{"type":19,"tag":246,"props":10861,"children":10862},{"style":259},[10863],{"type":24,"value":10864}," { ref } ",{"type":19,"tag":246,"props":10866,"children":10867},{"style":253},[10868],{"type":24,"value":1654},{"type":19,"tag":246,"props":10870,"children":10871},{"style":660},[10872],{"type":24,"value":1659},{"type":19,"tag":246,"props":10874,"children":10875},{"style":1619},[10876],{"type":24,"value":625},{"type":19,"tag":246,"props":10878,"children":10879},{"style":660},[10880],{"type":24,"value":1669},{"type":19,"tag":246,"props":10882,"children":10883},{"class":248,"line":353},[10884],{"type":19,"tag":246,"props":10885,"children":10886},{"emptyLinePlaceholder":357},[10887],{"type":24,"value":360},{"type":19,"tag":246,"props":10889,"children":10890},{"class":248,"line":363},[10891,10895,10900,10904,10908,10912,10916,10921,10925],{"type":19,"tag":246,"props":10892,"children":10893},{"style":253},[10894],{"type":24,"value":2959},{"type":19,"tag":246,"props":10896,"children":10897},{"style":259},[10898],{"type":24,"value":10899}," color ",{"type":19,"tag":246,"props":10901,"children":10902},{"style":253},[10903],{"type":24,"value":267},{"type":19,"tag":246,"props":10905,"children":10906},{"style":270},[10907],{"type":24,"value":273},{"type":19,"tag":246,"props":10909,"children":10910},{"style":259},[10911],{"type":24,"value":278},{"type":19,"tag":246,"props":10913,"children":10914},{"style":660},[10915],{"type":24,"value":2303},{"type":19,"tag":246,"props":10917,"children":10918},{"style":1619},[10919],{"type":24,"value":10920},"red",{"type":19,"tag":246,"props":10922,"children":10923},{"style":660},[10924],{"type":24,"value":2303},{"type":19,"tag":246,"props":10926,"children":10927},{"style":259},[10928],{"type":24,"value":289},{"type":19,"tag":246,"props":10930,"children":10931},{"class":248,"line":401},[10932,10936,10940],{"type":19,"tag":246,"props":10933,"children":10934},{"style":259},[10935],{"type":24,"value":1736},{"type":19,"tag":246,"props":10937,"children":10938},{"style":253},[10939],{"type":24,"value":1598},{"type":19,"tag":246,"props":10941,"children":10942},{"style":259},[10943],{"type":24,"value":1631},{"type":19,"tag":246,"props":10945,"children":10946},{"class":248,"line":409},[10947],{"type":19,"tag":246,"props":10948,"children":10949},{"emptyLinePlaceholder":357},[10950],{"type":24,"value":360},{"type":19,"tag":246,"props":10952,"children":10953},{"class":248,"line":2155},[10954,10958,10962],{"type":19,"tag":246,"props":10955,"children":10956},{"style":259},[10957],{"type":24,"value":637},{"type":19,"tag":246,"props":10959,"children":10960},{"style":253},[10961],{"type":24,"value":3154},{"type":19,"tag":246,"props":10963,"children":10964},{"style":259},[10965],{"type":24,"value":1631},{"type":19,"tag":246,"props":10967,"children":10968},{"class":248,"line":3057},[10969,10973,10977,10981,10985,10989,10993,10998,11002,11006,11010,11014,11018,11022,11027,11031,11036,11040,11044,11048,11052,11057],{"type":19,"tag":246,"props":10970,"children":10971},{"style":259},[10972],{"type":24,"value":3481},{"type":19,"tag":246,"props":10974,"children":10975},{"style":253},[10976],{"type":24,"value":5894},{"type":19,"tag":246,"props":10978,"children":10979},{"style":259},[10980],{"type":24,"value":3516},{"type":19,"tag":246,"props":10982,"children":10983},{"style":650},[10984],{"type":24,"value":5903},{"type":19,"tag":246,"props":10986,"children":10987},{"style":253},[10988],{"type":24,"value":267},{"type":19,"tag":246,"props":10990,"children":10991},{"style":660},[10992],{"type":24,"value":663},{"type":19,"tag":246,"props":10994,"children":10995},{"style":259},[10996],{"type":24,"value":10997},"color ",{"type":19,"tag":246,"props":10999,"children":11000},{"style":253},[11001],{"type":24,"value":267},{"type":19,"tag":246,"props":11003,"children":11004},{"style":259},[11005],{"type":24,"value":10899},{"type":19,"tag":246,"props":11007,"children":11008},{"style":253},[11009],{"type":24,"value":7836},{"type":19,"tag":246,"props":11011,"children":11012},{"style":660},[11013],{"type":24,"value":1659},{"type":19,"tag":246,"props":11015,"children":11016},{"style":1619},[11017],{"type":24,"value":10920},{"type":19,"tag":246,"props":11019,"children":11020},{"style":660},[11021],{"type":24,"value":2303},{"type":19,"tag":246,"props":11023,"children":11024},{"style":253},[11025],{"type":24,"value":11026}," ?",{"type":19,"tag":246,"props":11028,"children":11029},{"style":660},[11030],{"type":24,"value":1659},{"type":19,"tag":246,"props":11032,"children":11033},{"style":1619},[11034],{"type":24,"value":11035},"green",{"type":19,"tag":246,"props":11037,"children":11038},{"style":660},[11039],{"type":24,"value":2303},{"type":19,"tag":246,"props":11041,"children":11042},{"style":253},[11043],{"type":24,"value":647},{"type":19,"tag":246,"props":11045,"children":11046},{"style":660},[11047],{"type":24,"value":1659},{"type":19,"tag":246,"props":11049,"children":11050},{"style":1619},[11051],{"type":24,"value":10920},{"type":19,"tag":246,"props":11053,"children":11054},{"style":660},[11055],{"type":24,"value":11056},"'\"",{"type":19,"tag":246,"props":11058,"children":11059},{"style":259},[11060],{"type":24,"value":1631},{"type":19,"tag":246,"props":11062,"children":11063},{"class":248,"line":3066},[11064,11069,11073,11077],{"type":19,"tag":246,"props":11065,"children":11066},{"style":259},[11067],{"type":24,"value":11068},"    Color is: ",{"type":19,"tag":246,"props":11070,"children":11071},{"style":253},[11072],{"type":24,"value":3164},{"type":19,"tag":246,"props":11074,"children":11075},{"style":259},[11076],{"type":24,"value":10899},{"type":19,"tag":246,"props":11078,"children":11079},{"style":253},[11080],{"type":24,"value":11081},"}}\n",{"type":19,"tag":246,"props":11083,"children":11084},{"class":248,"line":3111},[11085,11090,11094],{"type":19,"tag":246,"props":11086,"children":11087},{"style":259},[11088],{"type":24,"value":11089},"  \u003C/",{"type":19,"tag":246,"props":11091,"children":11092},{"style":253},[11093],{"type":24,"value":5894},{"type":19,"tag":246,"props":11095,"children":11096},{"style":259},[11097],{"type":24,"value":1631},{"type":19,"tag":246,"props":11099,"children":11100},{"class":248,"line":3120},[11101,11105,11109],{"type":19,"tag":246,"props":11102,"children":11103},{"style":259},[11104],{"type":24,"value":1736},{"type":19,"tag":246,"props":11106,"children":11107},{"style":253},[11108],{"type":24,"value":3154},{"type":19,"tag":246,"props":11110,"children":11111},{"style":259},[11112],{"type":24,"value":1631},{"type":19,"tag":246,"props":11114,"children":11115},{"class":248,"line":3136},[11116],{"type":19,"tag":246,"props":11117,"children":11118},{"emptyLinePlaceholder":357},[11119],{"type":24,"value":360},{"type":19,"tag":246,"props":11121,"children":11122},{"class":248,"line":3144},[11123,11127,11131,11136],{"type":19,"tag":246,"props":11124,"children":11125},{"style":259},[11126],{"type":24,"value":637},{"type":19,"tag":246,"props":11128,"children":11129},{"style":253},[11130],{"type":24,"value":1103},{"type":19,"tag":246,"props":11132,"children":11133},{"style":650},[11134],{"type":24,"value":11135}," scoped",{"type":19,"tag":246,"props":11137,"children":11138},{"style":259},[11139],{"type":24,"value":1631},{"type":19,"tag":246,"props":11141,"children":11142},{"class":248,"line":3544},[11143,11148],{"type":19,"tag":246,"props":11144,"children":11145},{"style":253},[11146],{"type":24,"value":11147},"  button",{"type":19,"tag":246,"props":11149,"children":11150},{"style":259},[11151],{"type":24,"value":3046},{"type":19,"tag":246,"props":11153,"children":11154},{"class":248,"line":10716},[11155,11160,11164,11169],{"type":19,"tag":246,"props":11156,"children":11157},{"style":8285},[11158],{"type":24,"value":11159},"    color",{"type":19,"tag":246,"props":11161,"children":11162},{"style":253},[11163],{"type":24,"value":1883},{"type":19,"tag":246,"props":11165,"children":11166},{"style":270},[11167],{"type":24,"value":11168}," v-bind",{"type":19,"tag":246,"props":11170,"children":11171},{"style":259},[11172],{"type":24,"value":11173},"(color);\n",{"type":19,"tag":246,"props":11175,"children":11176},{"class":248,"line":10724},[11177],{"type":19,"tag":246,"props":11178,"children":11179},{"style":259},[11180],{"type":24,"value":3436},{"type":19,"tag":246,"props":11182,"children":11184},{"class":248,"line":11183},17,[11185,11189,11193],{"type":19,"tag":246,"props":11186,"children":11187},{"style":259},[11188],{"type":24,"value":1736},{"type":19,"tag":246,"props":11190,"children":11191},{"style":253},[11192],{"type":24,"value":1103},{"type":19,"tag":246,"props":11194,"children":11195},{"style":259},[11196],{"type":24,"value":1631},{"type":19,"tag":20,"props":11198,"children":11199},{},[11200,11202,11209],{"type":24,"value":11201},"Try it out in the ",{"type":19,"tag":51,"props":11203,"children":11206},{"href":11204,"rel":11205,"target":56},"https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHJlZiB9IGZyb20gJ3Z1ZSdcblxuY29uc3QgY29sb3IgPSByZWYoJ3JlZCcpXG48L3NjcmlwdD5cblxuPHRlbXBsYXRlPlxuICA8YnV0dG9uIEBjbGljaz1cImNvbG9yID0gY29sb3IgPT09ICdyZWQnID8gJ2dyZWVuJyA6ICdyZWQnXCI+XG4gICAgQ29sb3IgaXM6IHt7IGNvbG9yIH19XG4gIDwvYnV0dG9uPlxuPC90ZW1wbGF0ZT5cblxuPHN0eWxlIHNjb3BlZD5cbmJ1dHRvbiB7XG4gIGNvbG9yOiB2LWJpbmQoY29sb3IpO1xufVxuPC9zdHlsZT4ifQ==",[55,55],[11207],{"type":24,"value":11208},"SFC Playground",{"type":24,"value":11210},", or read their respective documentations:",{"type":19,"tag":89,"props":11212,"children":11213},{},[11214,11227],{"type":19,"tag":83,"props":11215,"children":11216},{},[11217],{"type":19,"tag":51,"props":11218,"children":11221},{"href":11219,"rel":11220,"target":56},"https://v3.vuejs.org/api/sfc-script-setup.html",[55,55],[11222],{"type":19,"tag":37,"props":11223,"children":11225},{"className":11224},[],[11226],{"type":24,"value":544},{"type":19,"tag":83,"props":11228,"children":11229},{},[11230],{"type":19,"tag":51,"props":11231,"children":11234},{"href":11232,"rel":11233,"target":56},"https://v3.vuejs.org/api/sfc-style.html#state-driven-dynamic-css",[55,55],[11235],{"type":19,"tag":37,"props":11236,"children":11238},{"className":11237},[],[11239],{"type":24,"value":10811},{"type":19,"tag":20,"props":11241,"children":11242},{},[11243,11245,11250,11252,11258],{"type":24,"value":11244},"Building on top of ",{"type":19,"tag":37,"props":11246,"children":11248},{"className":11247},[],[11249],{"type":24,"value":544},{"type":24,"value":11251},", we also have a new RFC for improving the ergonomics of ref usage with compiler-enabled sugar - please share your feedback ",{"type":19,"tag":51,"props":11253,"children":11256},{"href":11254,"rel":11255,"target":56},"https://github.com/vuejs/rfcs/discussions/369",[55,55],[11257],{"type":24,"value":6095},{"type":24,"value":61},{"type":19,"tag":72,"props":11260,"children":11262},{"id":11261},"web-components",[11263],{"type":24,"value":11264},"Web Components",{"type":19,"tag":20,"props":11266,"children":11267},{},[11268,11270,11276,11278,11285],{"type":24,"value":11269},"Vue 3.2 introduces a new ",{"type":19,"tag":37,"props":11271,"children":11273},{"className":11272},[],[11274],{"type":24,"value":11275},"defineCustomElement",{"type":24,"value":11277}," method for easily creating native ",{"type":19,"tag":51,"props":11279,"children":11282},{"href":11280,"rel":11281,"target":56},"https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements",[55,55],[11283],{"type":24,"value":11284},"custom elements",{"type":24,"value":11286}," using Vue component APIs:",{"type":19,"tag":236,"props":11288,"children":11290},{"className":238,"code":11289,"language":240,"meta":8,"style":8},"import { defineCustomElement } from 'vue'\n\nconst MyVueElement = defineCustomElement({\n  // normal Vue component options here\n})\n\n// Register the custom element.\n// After registration, all `\u003Cmy-vue-element>` tags\n// on the page will be upgraded.\ncustomElements.define('my-vue-element', MyVueElement)\n",[11291],{"type":19,"tag":37,"props":11292,"children":11293},{"__ignoreMap":8},[11294,11322,11329,11355,11363,11371,11378,11386,11394,11402],{"type":19,"tag":246,"props":11295,"children":11296},{"class":248,"line":249},[11297,11301,11306,11310,11314,11318],{"type":19,"tag":246,"props":11298,"children":11299},{"style":253},[11300],{"type":24,"value":7691},{"type":19,"tag":246,"props":11302,"children":11303},{"style":259},[11304],{"type":24,"value":11305}," { defineCustomElement } ",{"type":19,"tag":246,"props":11307,"children":11308},{"style":253},[11309],{"type":24,"value":1654},{"type":19,"tag":246,"props":11311,"children":11312},{"style":660},[11313],{"type":24,"value":1659},{"type":19,"tag":246,"props":11315,"children":11316},{"style":1619},[11317],{"type":24,"value":625},{"type":19,"tag":246,"props":11319,"children":11320},{"style":660},[11321],{"type":24,"value":1669},{"type":19,"tag":246,"props":11323,"children":11324},{"class":248,"line":292},[11325],{"type":19,"tag":246,"props":11326,"children":11327},{"emptyLinePlaceholder":357},[11328],{"type":24,"value":360},{"type":19,"tag":246,"props":11330,"children":11331},{"class":248,"line":353},[11332,11336,11341,11345,11350],{"type":19,"tag":246,"props":11333,"children":11334},{"style":253},[11335],{"type":24,"value":256},{"type":19,"tag":246,"props":11337,"children":11338},{"style":259},[11339],{"type":24,"value":11340}," MyVueElement ",{"type":19,"tag":246,"props":11342,"children":11343},{"style":253},[11344],{"type":24,"value":267},{"type":19,"tag":246,"props":11346,"children":11347},{"style":270},[11348],{"type":24,"value":11349}," defineCustomElement",{"type":19,"tag":246,"props":11351,"children":11352},{"style":259},[11353],{"type":24,"value":11354},"({\n",{"type":19,"tag":246,"props":11356,"children":11357},{"class":248,"line":363},[11358],{"type":19,"tag":246,"props":11359,"children":11360},{"style":395},[11361],{"type":24,"value":11362},"  // normal Vue component options here\n",{"type":19,"tag":246,"props":11364,"children":11365},{"class":248,"line":401},[11366],{"type":19,"tag":246,"props":11367,"children":11368},{"style":259},[11369],{"type":24,"value":11370},"})\n",{"type":19,"tag":246,"props":11372,"children":11373},{"class":248,"line":409},[11374],{"type":19,"tag":246,"props":11375,"children":11376},{"emptyLinePlaceholder":357},[11377],{"type":24,"value":360},{"type":19,"tag":246,"props":11379,"children":11380},{"class":248,"line":2155},[11381],{"type":19,"tag":246,"props":11382,"children":11383},{"style":395},[11384],{"type":24,"value":11385},"// Register the custom element.\n",{"type":19,"tag":246,"props":11387,"children":11388},{"class":248,"line":3057},[11389],{"type":19,"tag":246,"props":11390,"children":11391},{"style":395},[11392],{"type":24,"value":11393},"// After registration, all `\u003Cmy-vue-element>` tags\n",{"type":19,"tag":246,"props":11395,"children":11396},{"class":248,"line":3066},[11397],{"type":19,"tag":246,"props":11398,"children":11399},{"style":395},[11400],{"type":24,"value":11401},"// on the page will be upgraded.\n",{"type":19,"tag":246,"props":11403,"children":11404},{"class":248,"line":3111},[11405,11410,11415,11419,11423,11428,11432],{"type":19,"tag":246,"props":11406,"children":11407},{"style":259},[11408],{"type":24,"value":11409},"customElements.",{"type":19,"tag":246,"props":11411,"children":11412},{"style":270},[11413],{"type":24,"value":11414},"define",{"type":19,"tag":246,"props":11416,"children":11417},{"style":259},[11418],{"type":24,"value":278},{"type":19,"tag":246,"props":11420,"children":11421},{"style":660},[11422],{"type":24,"value":2303},{"type":19,"tag":246,"props":11424,"children":11425},{"style":1619},[11426],{"type":24,"value":11427},"my-vue-element",{"type":19,"tag":246,"props":11429,"children":11430},{"style":660},[11431],{"type":24,"value":2303},{"type":19,"tag":246,"props":11433,"children":11434},{"style":259},[11435],{"type":24,"value":11436},", MyVueElement)\n",{"type":19,"tag":20,"props":11438,"children":11439},{},[11440,11442,11449],{"type":24,"value":11441},"This API allows developers to create Vue-powered UI component libraries that can be used with any framework, or no framework at all. We have also added a new section in our docs on ",{"type":19,"tag":51,"props":11443,"children":11446},{"href":11444,"rel":11445,"target":56},"https://v3.vuejs.org/guide/web-components.html",[55,55],[11447],{"type":24,"value":11448},"consuming and creating Web Components in Vue",{"type":24,"value":61},{"type":19,"tag":72,"props":11451,"children":11452},{"id":6491},[11453],{"type":24,"value":6494},{"type":19,"tag":20,"props":11455,"children":11456},{},[11457,11459,11466],{"type":24,"value":11458},"3.2 includes some significant performance improvements to Vue's reactivity system, thanks to the great work by ",{"type":19,"tag":51,"props":11460,"children":11463},{"href":11461,"rel":11462,"target":56},"https://github.com/basvanmeurs",[55,55],[11464],{"type":24,"value":11465},"@basvanmeurs",{"type":24,"value":11467},". Specifically:",{"type":19,"tag":89,"props":11469,"children":11470},{},[11471,11481,11491],{"type":19,"tag":83,"props":11472,"children":11473},{},[11474],{"type":19,"tag":51,"props":11475,"children":11478},{"href":11476,"rel":11477,"target":56},"https://github.com/vuejs/vue-next/pull/3995",[55,55],[11479],{"type":24,"value":11480},"More efficient ref implementation (~260% faster read / ~50% faster write)",{"type":19,"tag":83,"props":11482,"children":11483},{},[11484],{"type":19,"tag":51,"props":11485,"children":11488},{"href":11486,"rel":11487,"target":56},"https://github.com/vuejs/vue-next/pull/4017",[55,55],[11489],{"type":24,"value":11490},"~40% faster dependency tracking",{"type":19,"tag":83,"props":11492,"children":11493},{},[11494],{"type":19,"tag":51,"props":11495,"children":11498},{"href":11496,"rel":11497,"target":56},"https://github.com/vuejs/vue-next/pull/4001",[55,55],[11499],{"type":24,"value":11500},"~17% less memory usage",{"type":19,"tag":20,"props":11502,"children":11503},{},[11504],{"type":24,"value":11505},"The template compiler also received a number of improvements:",{"type":19,"tag":89,"props":11507,"children":11508},{},[11509,11519],{"type":19,"tag":83,"props":11510,"children":11511},{},[11512],{"type":19,"tag":51,"props":11513,"children":11516},{"href":11514,"rel":11515,"target":56},"https://github.com/vuejs/vue-next/pull/3334",[55,55],[11517],{"type":24,"value":11518},"~200% faster creation of plain element VNodes",{"type":19,"tag":83,"props":11520,"children":11521},{},[11522,11524,11530,11532,11539],{"type":24,"value":11523},"More aggressive constant hoisting [",{"type":19,"tag":51,"props":11525,"children":11528},{"href":11526,"rel":11527,"target":56},"https://github.com/vuejs/vue-next/commit/b7ea7c148552874e8bce399eec9fbe565efa2f4d",[55,55],[11529],{"type":24,"value":3919},{"type":24,"value":11531},"] [",{"type":19,"tag":51,"props":11533,"children":11536},{"href":11534,"rel":11535,"target":56},"https://github.com/vuejs/vue-next/commit/02339b67d8c6fab6ee701a7c4f2773139ed007f5",[55,55],[11537],{"type":24,"value":11538},"2",{"type":24,"value":11540},"]",{"type":19,"tag":20,"props":11542,"children":11543},{},[11544,11546,11559,11561,11566,11568,11574],{"type":24,"value":11545},"Finally, there is a new ",{"type":19,"tag":51,"props":11547,"children":11550},{"href":11548,"rel":11549,"target":56},"https://v3.vuejs.org/api/directives.html#v-memo",[55,55],[11551,11557],{"type":19,"tag":37,"props":11552,"children":11554},{"className":11553},[],[11555],{"type":24,"value":11556},"v-memo",{"type":24,"value":11558}," directive",{"type":24,"value":11560}," that provides the ability to memoize part of the template tree. A ",{"type":19,"tag":37,"props":11562,"children":11564},{"className":11563},[],[11565],{"type":24,"value":11556},{"type":24,"value":11567}," hit allows Vue to skip not only the Virtual DOM diffing, but the creation of new VNodes altogether. Although rarely needed, it provides an escape hatch to squeeze out maximum performance in certain scenarios, for example large ",{"type":19,"tag":37,"props":11569,"children":11571},{"className":11570},[],[11572],{"type":24,"value":11573},"v-for",{"type":24,"value":11575}," lists.",{"type":19,"tag":20,"props":11577,"children":11578},{},[11579,11581,11586,11588,11594],{"type":24,"value":11580},"The usage of ",{"type":19,"tag":37,"props":11582,"children":11584},{"className":11583},[],[11585],{"type":24,"value":11556},{"type":24,"value":11587},", which is a one-line addition, places Vue among the fastest mainstream frameworks in ",{"type":19,"tag":51,"props":11589,"children":11592},{"href":11590,"rel":11591,"target":56},"https://github.com/krausest/js-framework-benchmark",[55,55],[11593],{"type":24,"value":5991},{"type":24,"value":1883},{"type":19,"tag":20,"props":11596,"children":11597},{},[11598],{"type":19,"tag":642,"props":11599,"children":11602},{"alt":11600,"src":11601},"benchmark","/bench.png",[],{"type":19,"tag":72,"props":11604,"children":11606},{"id":11605},"server-side-rendering",[11607],{"type":24,"value":11608},"Server-side Rendering",{"type":19,"tag":20,"props":11610,"children":11611},{},[11612,11613,11619,11621,11626,11628,11635],{"type":24,"value":7640},{"type":19,"tag":37,"props":11614,"children":11616},{"className":11615},[],[11617],{"type":24,"value":11618},"@vue/server-renderer",{"type":24,"value":11620}," package in 3.2 now ships an ES module build which is also decoupled from Node.js built-ins. This makes it possible to bundle and leverage ",{"type":19,"tag":37,"props":11622,"children":11624},{"className":11623},[],[11625],{"type":24,"value":11618},{"type":24,"value":11627}," for use inside non-Node.js runtimes such as ",{"type":19,"tag":51,"props":11629,"children":11632},{"href":11630,"rel":11631,"target":56},"https://developers.cloudflare.com/workers/",[55,55],[11633],{"type":24,"value":11634},"CloudFlare Workers",{"type":24,"value":11636}," or Service Workers.",{"type":19,"tag":20,"props":11638,"children":11639},{},[11640,11642,11649,11651,11663],{"type":24,"value":11641},"We also improved the streaming render APIs, with new methods for rendering to the ",{"type":19,"tag":51,"props":11643,"children":11646},{"href":11644,"rel":11645,"target":56},"https://developer.mozilla.org/en-US/docs/Web/API/Streams_API",[55,55],[11647],{"type":24,"value":11648},"Web Streams API",{"type":24,"value":11650},". Check out the ",{"type":19,"tag":51,"props":11652,"children":11655},{"href":11653,"rel":11654,"target":56},"https://github.com/vuejs/vue-next/tree/master/packages/server-renderer#streaming-api",[55,55],[11656,11658],{"type":24,"value":11657},"documentation of ",{"type":19,"tag":37,"props":11659,"children":11661},{"className":11660},[],[11662],{"type":24,"value":11618},{"type":24,"value":11664}," for more details.",{"type":19,"tag":72,"props":11666,"children":11668},{"id":11667},"effect-scope-api",[11669],{"type":24,"value":11670},"Effect Scope API",{"type":19,"tag":20,"props":11672,"children":11673},{},[11674,11676,11682],{"type":24,"value":11675},"3.2 introduces a new ",{"type":19,"tag":51,"props":11677,"children":11680},{"href":11678,"rel":11679,"target":56},"https://v3.vuejs.org/api/effect-scope.html",[55,55],[11681],{"type":24,"value":11670},{"type":24,"value":11683}," for directly controlling the disposal timing of reactive effects (computed and watchers). It makes it easier to leverage Vue's reactivity API out of a component context, and also unlocks some advanced use cases inside components.",{"type":19,"tag":20,"props":11685,"children":11686},{},[11687,11689,11696],{"type":24,"value":11688},"This is low-level API largely intended for library authors, so it's recommended to read the feature's ",{"type":19,"tag":51,"props":11690,"children":11693},{"href":11691,"rel":11692,"target":56},"https://github.com/vuejs/rfcs/blob/master/active-rfcs/0041-reactivity-effect-scope.md",[55,55],[11694],{"type":24,"value":11695},"RFC",{"type":24,"value":11697}," for the motivation and use cases of this feature.",{"type":19,"tag":63,"props":11699,"children":11700},{},[],{"type":19,"tag":20,"props":11702,"children":11703},{},[11704,11706,11713],{"type":24,"value":11705},"For a detailed list of all changes in 3.2, please refer to the ",{"type":19,"tag":51,"props":11707,"children":11710},{"href":11708,"rel":11709,"target":56},"https://github.com/vuejs/vue-next/blob/master/CHANGELOG.md",[55,55],[11711],{"type":24,"value":11712},"full changelog",{"type":24,"value":61},{"type":19,"tag":1103,"props":11715,"children":11716},{},[11717],{"type":24,"value":1107},{"title":8,"searchDepth":292,"depth":292,"links":11719},[11720,11721,11722,11723,11724],{"id":10773,"depth":292,"text":10776},{"id":11261,"depth":292,"text":11264},{"id":6491,"depth":292,"text":6494},{"id":11605,"depth":292,"text":11608},{"id":11667,"depth":292,"text":11670},"content:blog:vue-3-2.md","blog/vue-3-2.md","blog/vue-3-2",{"loc":10755},{"_path":11730,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":11731,"description":11732,"date":11733,"author":12,"gravatar":13,"twitter":14,"excerpt":11734,"body":11740,"_type":1125,"_id":12000,"_source":1127,"_file":12001,"_stem":12002,"_extension":1130,"sitemap":12003},"/blog/hello-2021","Reflections for 2020-2021","With a new year upon us, we also have a new blog! In this post, we would like to take a look back at some of the highlights from 2020, as well as some ideas we have for 2021.","2021-01-11",{"type":16,"children":11735},[11736],{"type":19,"tag":20,"props":11737,"children":11738},{},[11739],{"type":24,"value":11732},{"type":16,"children":11741,"toc":11996},[11742,11746,11749,11755,11777,11782,11844,11849,11923,11928,11934,11939,11991],{"type":19,"tag":20,"props":11743,"children":11744},{},[11745],{"type":24,"value":11732},{"type":19,"tag":63,"props":11747,"children":11748},{},[],{"type":19,"tag":72,"props":11750,"children":11752},{"id":11751},"looking-back-at-2020",[11753],{"type":24,"value":11754},"Looking Back at 2020",{"type":19,"tag":20,"props":11756,"children":11757},{},[11758,11760,11767,11768,11775],{"type":24,"value":11759},"2020 has been a challenging year, to say the least. Nonetheless, the team has made the best of a difficult situation. Despite an already massive user base, Vue's ",{"type":19,"tag":51,"props":11761,"children":11764},{"href":11762,"rel":11763,"target":56},"https://npm-stat.com/charts.html?package=vue&from=2020-01-01&to=2020-12-31",[55,55],[11765],{"type":24,"value":11766},"NPM downloads",{"type":24,"value":1384},{"type":19,"tag":51,"props":11769,"children":11772},{"href":11770,"rel":11771,"target":56},"https://chrome-stats.com/d/nhdogjmejiglipccpnnnanhbledajbpd",[55,55],[11773],{"type":24,"value":11774},"Devtools weekly active users",{"type":24,"value":11776}," both grew close to 50% throughout 2020. As time of this writing, Vue is being downloaded ~8M times per month on NPM and the devtools extension has ~1.5M weekly active users.",{"type":19,"tag":20,"props":11778,"children":11779},{},[11780],{"type":24,"value":11781},"Aside from routine maintenance, there are some incredible things that we accomplished as a team:",{"type":19,"tag":89,"props":11783,"children":11784},{},[11785,11795,11805,11815,11825,11834],{"type":19,"tag":83,"props":11786,"children":11787},{},[11788],{"type":19,"tag":51,"props":11789,"children":11792},{"href":11790,"rel":11791,"target":56},"https://github.com/vuejs/vue-next/releases/tag/v3.0.0",[55,55],[11793],{"type":24,"value":11794},"Shipped Vue 3 core",{"type":19,"tag":83,"props":11796,"children":11797},{},[11798],{"type":19,"tag":51,"props":11799,"children":11802},{"href":11800,"rel":11801,"target":56},"https://v3.vuejs.org/",[55,55],[11803],{"type":24,"value":11804},"Brand new docs site for Vue 3",{"type":19,"tag":83,"props":11806,"children":11807},{},[11808],{"type":19,"tag":51,"props":11809,"children":11812},{"href":11810,"rel":11811,"target":56},"https://github.com/vuejs/vue-router-next/releases/tag/v4.0.0",[55,55],[11813],{"type":24,"value":11814},"Vue Router 4",{"type":19,"tag":83,"props":11816,"children":11817},{},[11818],{"type":19,"tag":51,"props":11819,"children":11822},{"href":11820,"rel":11821,"target":56},"https://next.vuex.vuejs.org/",[55,55],[11823],{"type":24,"value":11824},"Vuex 4 (RC)",{"type":19,"tag":83,"props":11826,"children":11827},{},[11828],{"type":19,"tag":51,"props":11829,"children":11831},{"href":10458,"rel":11830,"target":56},[55,55],[11832],{"type":24,"value":11833},"Vue DevTools 6.0 with Vue 3 support (Beta)",{"type":19,"tag":83,"props":11835,"children":11836},{},[11837],{"type":19,"tag":51,"props":11838,"children":11841},{"href":11839,"rel":11840,"target":56},"https://vue-test-utils.vuejs.org/v2/guide/introduction.html",[55,55],[11842],{"type":24,"value":11843},"Vue Test Utils 2 (Beta)",{"type":19,"tag":20,"props":11845,"children":11846},{},[11847],{"type":24,"value":11848},"In addition to iterating on the existing ecosystem, we also invested in exploring improvements on new frontiers:",{"type":19,"tag":89,"props":11850,"children":11851},{},[11852,11888,11900,11911],{"type":19,"tag":83,"props":11853,"children":11854},{},[11855,11857],{"type":24,"value":11856},"New Single File Component (SFC) feature proposals with the goal of leveraging the SFC compiler for more DX and performance wins:\n",{"type":19,"tag":89,"props":11858,"children":11859},{},[11860,11873],{"type":19,"tag":83,"props":11861,"children":11862},{},[11863],{"type":19,"tag":51,"props":11864,"children":11867},{"href":11865,"rel":11866,"target":56},"https://github.com/vuejs/rfcs/pull/227",[55,55],[11868],{"type":19,"tag":37,"props":11869,"children":11871},{"className":11870},[],[11872],{"type":24,"value":544},{"type":19,"tag":83,"props":11874,"children":11875},{},[11876],{"type":19,"tag":51,"props":11877,"children":11880},{"href":11878,"rel":11879,"target":56},"https://github.com/vuejs/rfcs/pull/231",[55,55],[11881,11883],{"type":24,"value":11882},"CSS variables injection in ",{"type":19,"tag":37,"props":11884,"children":11886},{"className":11885},[],[11887],{"type":24,"value":10819},{"type":19,"tag":83,"props":11889,"children":11890},{},[11891,11898],{"type":19,"tag":51,"props":11892,"children":11895},{"href":11893,"rel":11894,"target":56},"https://github.com/znck/vue-developer-experience",[55,55],[11896],{"type":24,"value":11897},"VueDX",{"type":24,"value":11899}," for providing better IDE integrations and development workflow",{"type":19,"tag":83,"props":11901,"children":11902},{},[11903,11909],{"type":19,"tag":51,"props":11904,"children":11907},{"href":11905,"rel":11906,"target":56},"http://vitejs.dev/",[55,55],[11908],{"type":24,"value":4605},{"type":24,"value":11910},", a new build tool built on top of modern standards",{"type":19,"tag":83,"props":11912,"children":11913},{},[11914,11921],{"type":19,"tag":51,"props":11915,"children":11918},{"href":11916,"rel":11917,"target":56},"https://vitepress.vuejs.org/",[55,55],[11919],{"type":24,"value":11920},"VitePress",{"type":24,"value":11922},", a new static site generator built on Vue 3 and Vite",{"type":19,"tag":20,"props":11924,"children":11925},{},[11926],{"type":24,"value":11927},"In addition to all of these exciting projects, it’s also been incredible to see the community continue to grow despite the challenges 2020 set forth in terms of being unable to facilitate in-person events. With initiatives such as remote conferences, meetups and other events, it’s been a joy to see the community interacting in new ways that might not have been possible otherwise.",{"type":19,"tag":72,"props":11929,"children":11931},{"id":11930},"looking-forward-to-2021",[11932],{"type":24,"value":11933},"Looking Forward to 2021",{"type":19,"tag":20,"props":11935,"children":11936},{},[11937],{"type":24,"value":11938},"While Vue 3 brings many fundamental improvements and opens up avenues for future iterations, we are still in a transition period - both in terms of the library ecosystem and best practices involving new APIs. For early 2021, our focus will be further stabilizing the Vue 3 ecosystem, and continuing to help the community through this transition period. Here is a non-exhaustive list of things we’re looking forward to:",{"type":19,"tag":89,"props":11940,"children":11941},{},[11942,11947,11952,11957,11962,11967,11976,11981,11986],{"type":19,"tag":83,"props":11943,"children":11944},{},[11945],{"type":24,"value":11946},"Stablize current RC/Beta sub projects",{"type":19,"tag":83,"props":11948,"children":11949},{},[11950],{"type":24,"value":11951},"Finalize SFC proposals and further polish IDE support",{"type":19,"tag":83,"props":11953,"children":11954},{},[11955],{"type":24,"value":11956},"Vue 3.1 (Q1, more details as we finalize the release plan)",{"type":19,"tag":83,"props":11958,"children":11959},{},[11960],{"type":24,"value":11961},"Vue 2 → 3 Migration Tools (estimated end of Q1)",{"type":19,"tag":83,"props":11963,"children":11964},{},[11965],{"type":24,"value":11966},"Vue CLI 5 w/ webpack 5 support (estimated Q1)",{"type":19,"tag":83,"props":11968,"children":11969},{},[11970],{"type":19,"tag":11971,"props":11972,"children":11973},"del",{},[11974],{"type":24,"value":11975},"Vue 3 IE 11 Compatibility Build (estimated Q2)",{"type":19,"tag":83,"props":11977,"children":11978},{},[11979],{"type":24,"value":11980},"Vue 2.7 (estimated Q2/3)",{"type":19,"tag":83,"props":11982,"children":11983},{},[11984],{"type":24,"value":11985},"SSR support in Vite",{"type":19,"tag":83,"props":11987,"children":11988},{},[11989],{"type":24,"value":11990},"Vuex 5 (TBD)",{"type":19,"tag":20,"props":11992,"children":11993},{},[11994],{"type":24,"value":11995},"In addition, we are excited about other frameworks and libraries in the ecosystem making progress towards Vue 3 support. And of course, we can’t wait to see what new ideas and tools you all have as we embark on a new chapter in the Vue.js roadmap.",{"title":8,"searchDepth":292,"depth":292,"links":11997},[11998,11999],{"id":11751,"depth":292,"text":11754},{"id":11930,"depth":292,"text":11933},"content:blog:hello-2021.md","blog/hello-2021.md","blog/hello-2021",{"loc":11730},{"_path":12005,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":12006,"description":7471,"date":12007,"author":12,"gravatar":13,"twitter":14,"excerpt":12008,"body":12026,"_type":1125,"_id":12561,"_source":1127,"_file":12562,"_stem":12563,"_extension":1130,"sitemap":12564},"/blog/vue-3-one-piece","Announcing Vue 3.0 \"One Piece\"","2020-09-18",{"type":16,"children":12009},[12010,12021],{"type":19,"tag":20,"props":12011,"children":12012},{"align":6843},[12013,12014],{"type":24,"value":7471},{"type":19,"tag":642,"props":12015,"children":12020},{"width":12016,"height":12017,"src":12018,"alt":12019},200,"177px","https://user-images.githubusercontent.com/499550/93624428-53932780-f9ae-11ea-8d16-af949e16a09f.png","one-piece-logo",[],{"type":19,"tag":20,"props":12022,"children":12023},{},[12024],{"type":24,"value":12025},"Today we are proud to announce the official release of Vue.js 3.0 \"One Piece\". This new major version of the framework provides improved performance, smaller bundle sizes, better TypeScript integration, new APIs for tackling large scale use cases, and a solid foundation for long-term future iterations of the framework.",{"type":16,"children":12027,"toc":12547},[12028,12035,12039,12042,12083,12089,12094,12106,12112,12133,12138,12212,12218,12231,12259,12263,12277,12282,12288,12302,12306,12327,12361,12366,12396,12402,12407,12421,12427,12432,12436,12441,12464,12496,12501,12507,12528,12531],{"type":19,"tag":20,"props":12029,"children":12030},{"align":6843},[12031,12032],{"type":24,"value":7471},{"type":19,"tag":642,"props":12033,"children":12034},{"width":12016,"height":12017,"src":12018,"alt":12019},[],{"type":19,"tag":20,"props":12036,"children":12037},{},[12038],{"type":24,"value":12025},{"type":19,"tag":63,"props":12040,"children":12041},{},[],{"type":19,"tag":20,"props":12043,"children":12044},{},[12045,12047,12054,12056,12063,12065,12072,12074,12081],{"type":24,"value":12046},"The 3.0 release represents over 2 years of development efforts, featuring ",{"type":19,"tag":51,"props":12048,"children":12051},{"href":12049,"rel":12050,"target":56},"https://github.com/vuejs/rfcs/tree/master/active-rfcs",[55,55],[12052],{"type":24,"value":12053},"30+ RFCs",{"type":24,"value":12055},", 2,600+ commits, ",{"type":19,"tag":51,"props":12057,"children":12060},{"href":12058,"rel":12059,"target":56},"https://github.com/vuejs/vue-next/pulls?q=is%3Apr+is%3Amerged+-author%3Aapp%2Fdependabot-preview+",[55,55],[12061],{"type":24,"value":12062},"628 pull requests",{"type":24,"value":12064}," from ",{"type":19,"tag":51,"props":12066,"children":12069},{"href":12067,"rel":12068,"target":56},"https://github.com/vuejs/vue-next/graphs/contributors",[55,55],[12070],{"type":24,"value":12071},"99 contributors",{"type":24,"value":12073},", plus tremendous amount of development and documentation work outside of the core repo. We would like to express our deepest gratitude towards our team members for taking on this challenge, our contributors for the pull requests, our ",{"type":19,"tag":51,"props":12075,"children":12078},{"href":12076,"rel":12077,"target":56},"https://github.com/vuejs/vue/blob/dev/BACKERS.md",[55,55],[12079],{"type":24,"value":12080},"sponsors and backers",{"type":24,"value":12082}," for the financial support, and the wider community for participating in our design discussions and providing feedback for the pre-release versions. Vue is an independent project created for the community and sustained by the community, and Vue 3.0 wouldn't have been possible without your consistent support.",{"type":19,"tag":72,"props":12084,"children":12086},{"id":12085},"taking-the-progressive-framework-concept-further",[12087],{"type":24,"value":12088},"Taking the \"Progressive Framework\" Concept Further",{"type":19,"tag":20,"props":12090,"children":12091},{},[12092],{"type":24,"value":12093},"Vue had a simple mission from its humble beginning: to be an approachable framework that anyone can quickly learn. As our user base grew, the framework also grew in scope to adapt to the increasing demands. Over time, it evolved into what we call a \"Progressive Framework\": a framework that can be learned and adopted incrementally, while providing continued support as the user tackles more and more demanding scenarios.",{"type":19,"tag":20,"props":12095,"children":12096},{},[12097,12099,12104],{"type":24,"value":12098},"Today, with over 1.3 million users worldwide",{"type":19,"tag":12100,"props":12101,"children":12102},"sup",{},[12103],{"type":24,"value":10593},{"type":24,"value":12105},", we are seeing Vue being used in a wildly diverse range of scenarios, from sprinkling interactivity on traditional server-rendered pages, to full-blown single page applications with hundreds of components. Vue 3 takes this flexibility even further.",{"type":19,"tag":151,"props":12107,"children":12109},{"id":12108},"layered-internal-modules",[12110],{"type":24,"value":12111},"Layered internal modules",{"type":19,"tag":20,"props":12113,"children":12114},{},[12115,12117,12122,12124,12131],{"type":24,"value":12116},"Vue 3.0 core can still be used via a simple ",{"type":19,"tag":37,"props":12118,"children":12120},{"className":12119},[],[12121],{"type":24,"value":3789},{"type":24,"value":12123}," tag, but its internals has been re-written from the ground up into ",{"type":19,"tag":51,"props":12125,"children":12128},{"href":12126,"rel":12127,"target":56},"https://github.com/vuejs/vue-next/tree/master/packages",[55,55],[12129],{"type":24,"value":12130},"a collection of decoupled modules",{"type":24,"value":12132},". The new architecture provides better maintainability, and allows end users to shave off up to half of the runtime size via tree-shaking.",{"type":19,"tag":20,"props":12134,"children":12135},{},[12136],{"type":24,"value":12137},"These modules also exposes lower-level APIs that unlocks many advanced use cases:",{"type":19,"tag":89,"props":12139,"children":12140},{},[12141,12154,12184],{"type":19,"tag":83,"props":12142,"children":12143},{},[12144,12146,12153],{"type":24,"value":12145},"The compiler supports custom AST transforms for build-time customizations (e.g. ",{"type":19,"tag":51,"props":12147,"children":12150},{"href":12148,"rel":12149,"target":56},"https://github.com/intlify/vue-i18n-extensions",[55,55],[12151],{"type":24,"value":12152},"build-time i18n",{"type":24,"value":104},{"type":19,"tag":83,"props":12155,"children":12156},{},[12157,12159,12166,12167,12174,12175,12182],{"type":24,"value":12158},"The core runtime provides first-class API for creating custom renderers targeting different render targets (e.g. ",{"type":19,"tag":51,"props":12160,"children":12163},{"href":12161,"rel":12162,"target":56},"https://github.com/rigor789/nativescript-vue-next",[55,55],[12164],{"type":24,"value":12165},"native mobile",{"type":24,"value":474},{"type":19,"tag":51,"props":12168,"children":12171},{"href":12169,"rel":12170,"target":56},"https://github.com/Planning-nl/vugel",[55,55],[12172],{"type":24,"value":12173},"WebGL",{"type":24,"value":6294},{"type":19,"tag":51,"props":12176,"children":12179},{"href":12177,"rel":12178,"target":56},"https://github.com/ycmjason/vuminal",[55,55],[12180],{"type":24,"value":12181},"terminals",{"type":24,"value":12183},"). The default DOM renderer is built using the same API.",{"type":19,"tag":83,"props":12185,"children":12186},{},[12187,12188,12201,12203,12210],{"type":24,"value":7640},{"type":19,"tag":51,"props":12189,"children":12192},{"href":12190,"rel":12191,"target":56},"https://github.com/vuejs/vue-next/tree/master/packages/reactivity",[55,55],[12193,12199],{"type":19,"tag":37,"props":12194,"children":12196},{"className":12195},[],[12197],{"type":24,"value":12198},"@vue/reactivity",{"type":24,"value":12200}," module",{"type":24,"value":12202}," exports functions that provide direct access to Vue's reactivity system, and can be used as a standalone package. It can be used to pair with other templating solutions (e.g. ",{"type":19,"tag":51,"props":12204,"children":12207},{"href":12205,"rel":12206,"target":56},"https://github.com/yyx990803/vue-lit",[55,55],[12208],{"type":24,"value":12209},"lit-html",{"type":24,"value":12211},") or even in non-UI scenarios.",{"type":19,"tag":151,"props":12213,"children":12215},{"id":12214},"new-apis-for-tackling-scale",[12216],{"type":24,"value":12217},"New APIs for tackling scale",{"type":19,"tag":20,"props":12219,"children":12220},{},[12221,12223,12229],{"type":24,"value":12222},"The 2.x Object-based API is largely intact in Vue 3. However, 3.0 also introduces the ",{"type":19,"tag":51,"props":12224,"children":12227},{"href":12225,"rel":12226,"target":56},"https://v3.vuejs.org/guide/composition-api-introduction.html",[55,55],[12228],{"type":24,"value":7530},{"type":24,"value":12230}," - a new set of APIs aimed at addressing the pain points of Vue usage in large scale applications. The Composition API builds on top of the reactivity API and enables logic composition and reuse similar to React hooks, more flexible code organization patterns, and more reliable type inference than the 2.x Object-based API.",{"type":19,"tag":20,"props":12232,"children":12233},{},[12234,12236,12241,12243,12250,12251,12258],{"type":24,"value":12235},"Composition API can also be used with Vue 2.x via the ",{"type":19,"tag":51,"props":12237,"children":12239},{"href":8127,"rel":12238,"target":56},[55,55],[12240],{"type":24,"value":8135},{"type":24,"value":12242}," plugin, and there are already Composition API utility libraries that work for both Vue 2 and 3 (e.g. ",{"type":19,"tag":51,"props":12244,"children":12247},{"href":12245,"rel":12246,"target":56},"https://github.com/antfu/vueuse",[55,55],[12248],{"type":24,"value":12249},"vueuse",{"type":24,"value":474},{"type":19,"tag":51,"props":12252,"children":12255},{"href":12253,"rel":12254,"target":56},"https://github.com/pikax/vue-composable",[55,55],[12256],{"type":24,"value":12257},"vue-composable",{"type":24,"value":5512},{"type":19,"tag":151,"props":12260,"children":12261},{"id":6491},[12262],{"type":24,"value":6494},{"type":19,"tag":20,"props":12264,"children":12265},{},[12266,12268,12275],{"type":24,"value":12267},"Vue 3 has demonstrated ",{"type":19,"tag":51,"props":12269,"children":12272},{"href":12270,"rel":12271,"target":56},"https://docs.google.com/spreadsheets/d/1VJFx-kQ4KjJmnpDXIEaig-cVAAJtpIGLZNbv3Lr4CR0/edit?usp=sharing",[55,55],[12273],{"type":24,"value":12274},"significant performance improvements",{"type":24,"value":12276}," over Vue 2 in terms of bundle size (up to 41% lighter with tree-shaking), initial render (up to 55% faster), updates (up to 133% faster), and memory usage (up to 54% less).",{"type":19,"tag":20,"props":12278,"children":12279},{},[12280],{"type":24,"value":12281},"In Vue 3, we have taken the approach of \"compiler-informed Virtual DOM\": the template compiler performs aggressive optimizations and generates render function code that hoists static content, leaves runtime hints for binding types, and most importantly, flattens the dynamic nodes inside a template to reduce the cost of runtime traversal. The user therefore gets the best of both worlds: compiler-optimized performance from templates, or direct control via manual render functions when the use case demands.",{"type":19,"tag":151,"props":12283,"children":12285},{"id":12284},"improved-typescript-integration",[12286],{"type":24,"value":12287},"Improved TypeScript integration",{"type":19,"tag":20,"props":12289,"children":12290},{},[12291,12293,12300],{"type":24,"value":12292},"Vue 3's codebase is written in TypeScript, with automatically generated, tested, and bundled type definitions so they are always up-to-date. Composition API works great with type inference. Vetur, our official VSCode extension, now supports template expression and props type checking leveraging Vue 3's improved internal typing. Oh, and Vue 3's typing ",{"type":19,"tag":51,"props":12294,"children":12297},{"href":12295,"rel":12296,"target":56},"https://github.com/vuejs/vue-next/blob/master/test-dts/defineComponent.test-d.tsx",[55,55],[12298],{"type":24,"value":12299},"fully supports TSX",{"type":24,"value":12301}," if that's your preference.",{"type":19,"tag":151,"props":12303,"children":12304},{"id":2871},[12305],{"type":24,"value":2874},{"type":19,"tag":20,"props":12307,"children":12308},{},[12309,12311,12318,12320,12325],{"type":24,"value":12310},"We have proposed ",{"type":19,"tag":51,"props":12312,"children":12315},{"href":12313,"rel":12314,"target":56},"https://github.com/vuejs/rfcs/pull/182",[55,55],[12316],{"type":24,"value":12317},"two new features",{"type":24,"value":12319}," for Singe-File Components (SFC, aka ",{"type":19,"tag":37,"props":12321,"children":12323},{"className":12322},[],[12324],{"type":24,"value":10787},{"type":24,"value":12326}," files):",{"type":19,"tag":89,"props":12328,"children":12329},{},[12330,12345],{"type":19,"tag":83,"props":12331,"children":12332},{},[12333],{"type":19,"tag":51,"props":12334,"children":12337},{"href":12335,"rel":12336,"target":56},"https://github.com/vuejs/rfcs/blob/sfc-improvements/active-rfcs/0000-sfc-script-setup.md",[55,55],[12338,12343],{"type":19,"tag":37,"props":12339,"children":12341},{"className":12340},[],[12342],{"type":24,"value":544},{"type":24,"value":12344},": syntactic sugar for using Composition API inside SFCs",{"type":19,"tag":83,"props":12346,"children":12347},{},[12348],{"type":19,"tag":51,"props":12349,"children":12352},{"href":12350,"rel":12351,"target":56},"https://github.com/vuejs/rfcs/blob/sfc-improvements/active-rfcs/0000-sfc-style-variables.md",[55,55],[12353,12359],{"type":19,"tag":37,"props":12354,"children":12356},{"className":12355},[],[12357],{"type":24,"value":12358},"\u003Cstyle vars>",{"type":24,"value":12360},": state-driven CSS variables inside SFCs",{"type":19,"tag":20,"props":12362,"children":12363},{},[12364],{"type":24,"value":12365},"These features are already implemented and available in Vue 3.0, but are provided only for the purpose of gathering feedback. They will remain experimental until the RFCs are merged.",{"type":19,"tag":20,"props":12367,"children":12368},{},[12369,12371,12377,12379,12385,12387,12394],{"type":24,"value":12370},"We have also implemented a currently undocumented ",{"type":19,"tag":37,"props":12372,"children":12374},{"className":12373},[],[12375],{"type":24,"value":12376},"\u003CSuspense>",{"type":24,"value":12378}," component, which allows waiting on nested async dependencies (async components or component with ",{"type":19,"tag":37,"props":12380,"children":12382},{"className":12381},[],[12383],{"type":24,"value":12384},"async setup()",{"type":24,"value":12386},") on initial render or branch switch. We are testing and iterating on this feature with the Nuxt.js team (",{"type":19,"tag":51,"props":12388,"children":12391},{"href":12389,"rel":12390,"target":56},"https://nuxtjs.slides.com/atinux/state-of-nuxt-2020",[55,55],[12392],{"type":24,"value":12393},"Nuxt 3 is on the way",{"type":24,"value":12395},") and will likely solidify it in 3.1.",{"type":19,"tag":72,"props":12397,"children":12399},{"id":12398},"phased-release-process",[12400],{"type":24,"value":12401},"Phased Release Process",{"type":19,"tag":20,"props":12403,"children":12404},{},[12405],{"type":24,"value":12406},"The release of Vue 3.0 marks the general readiness of the framework. While some of the frameworks sub projects may still need further work to reach stable status (specifically router and Vuex integration in the devtools), we believe it's suitable to start new, green-field projects with Vue 3 today. We also encourage library authors to start upgrading your projects to support Vue 3.",{"type":19,"tag":20,"props":12408,"children":12409},{},[12410,12412,12419],{"type":24,"value":12411},"Check out the ",{"type":19,"tag":51,"props":12413,"children":12416},{"href":12414,"rel":12415,"target":56},"https://v3.vuejs.org/guide/migration/introduction.html#supporting-libraries",[55,55],[12417],{"type":24,"value":12418},"Vue 3 Libraries Guide",{"type":24,"value":12420}," for details on all framework sub projects.",{"type":19,"tag":151,"props":12422,"children":12424},{"id":12423},"migration-and-ie11-support",[12425],{"type":24,"value":12426},"Migration and IE11 Support",{"type":19,"tag":20,"props":12428,"children":12429},{},[12430],{"type":24,"value":12431},"We have pushed back the migration build (v3 build with v2 compatible behavior + migration warnings) and the IE11 build due to time constraints, and are aiming to focus on them in Q4 2020. Therefore, users planning to migrate an existing v2 app or require IE11 support should be aware of these limitations at this time.",{"type":19,"tag":151,"props":12433,"children":12434},{"id":4782},[12435],{"type":24,"value":4785},{"type":19,"tag":20,"props":12437,"children":12438},{},[12439],{"type":24,"value":12440},"For the near term after release, we will focus on:",{"type":19,"tag":89,"props":12442,"children":12443},{},[12444,12449,12454,12459],{"type":19,"tag":83,"props":12445,"children":12446},{},[12447],{"type":24,"value":12448},"Migration build",{"type":19,"tag":83,"props":12450,"children":12451},{},[12452],{"type":24,"value":12453},"IE11 support",{"type":19,"tag":83,"props":12455,"children":12456},{},[12457],{"type":24,"value":12458},"Router and Vuex integration in new devtools",{"type":19,"tag":83,"props":12460,"children":12461},{},[12462],{"type":24,"value":12463},"Further improvements to template type inference in Vetur",{"type":19,"tag":20,"props":12465,"children":12466},{},[12467,12469,12474,12476,12481,12483,12489,12491],{"type":24,"value":12468},"For the time being, the documentation websites, GitHub branches, and npm dist tags for Vue 3 and v3-targeting projects will remain under ",{"type":19,"tag":37,"props":12470,"children":12472},{"className":12471},[],[12473],{"type":24,"value":10310},{"type":24,"value":12475},"-denoted status. This means ",{"type":19,"tag":37,"props":12477,"children":12479},{"className":12478},[],[12480],{"type":24,"value":10175},{"type":24,"value":12482}," will still install Vue 2.x and ",{"type":19,"tag":37,"props":12484,"children":12486},{"className":12485},[],[12487],{"type":24,"value":12488},"npm install vue@next",{"type":24,"value":12490}," will install Vue 3. ",{"type":19,"tag":98,"props":12492,"children":12493},{},[12494],{"type":24,"value":12495},"We are planning to switch all doc links, branches and dist tags to default to 3.0 in early 2021.",{"type":19,"tag":20,"props":12497,"children":12498},{},[12499],{"type":24,"value":12500},"At the same time, we have started planning for 2.7, which will be the last planned minor release of the 2.x release line. 2.7 will be backporting compatible improvements from v3, and emit warnings on usage of APIs that are removed/changed in v3 to help with potential migration. We are planning to work on 2.7 in Q1 2021, which will directly become LTS upon release with an 18 months maintenance lifespan.",{"type":19,"tag":72,"props":12502,"children":12504},{"id":12503},"trying-it-out",[12505],{"type":24,"value":12506},"Trying It Out",{"type":19,"tag":20,"props":12508,"children":12509},{},[12510,12512,12518,12520,12527],{"type":24,"value":12511},"To learn more about Vue 3.0, check out our ",{"type":19,"tag":51,"props":12513,"children":12515},{"href":11800,"rel":12514,"target":56},[55,55],[12516],{"type":24,"value":12517},"new documentation website",{"type":24,"value":12519},". If you are an existing Vue 2.x user, go directly to the ",{"type":19,"tag":51,"props":12521,"children":12524},{"href":12522,"rel":12523,"target":56},"https://v3.vuejs.org/guide/migration/introduction.html",[55,55],[12525],{"type":24,"value":12526},"Migration Guide",{"type":24,"value":61},{"type":19,"tag":63,"props":12529,"children":12530},{},[],{"type":19,"tag":89,"props":12532,"children":12533},{},[12534],{"type":19,"tag":83,"props":12535,"children":12536},{},[12537,12539,12545],{"type":24,"value":12538},"*based on ",{"type":19,"tag":51,"props":12540,"children":12542},{"href":10467,"rel":12541,"target":56},[55,55],[12543],{"type":24,"value":12544},"Vue Devtools Chrome extension",{"type":24,"value":12546}," weekly active users as reported by Google.",{"title":8,"searchDepth":292,"depth":292,"links":12548},[12549,12556,12560],{"id":12085,"depth":292,"text":12088,"children":12550},[12551,12552,12553,12554,12555],{"id":12108,"depth":353,"text":12111},{"id":12214,"depth":353,"text":12217},{"id":6491,"depth":353,"text":6494},{"id":12284,"depth":353,"text":12287},{"id":2871,"depth":353,"text":2874},{"id":12398,"depth":292,"text":12401,"children":12557},[12558,12559],{"id":12423,"depth":353,"text":12426},{"id":4782,"depth":353,"text":4785},{"id":12503,"depth":292,"text":12506},"content:blog:vue-3-one-piece.md","blog/vue-3-one-piece.md","blog/vue-3-one-piece",{"loc":12005},1788519848122]