@vue/language-service 2.1.5 → 2.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -992,7 +992,7 @@
992
992
  "name": "v-bind",
993
993
  "description": {
994
994
  "kind": "markdown",
995
- "value": "\nDynamicky váže jeden nebo více atributů nebo vlastností (props) komponenty na výraz.\n\n- **Zkratka:** \n - `:` nebo `.` (pokud se používá modifikátor `.prop`)\n - Vynechání hodnoty (pokud mají atribut a vázaná hodnota stejný název) <sup class=\"vt-badge\">3.4+</sup>\n\n- **Očekává:** `libovolný (s parametrem) | Objekt (bez parametru)`\n\n- **Parametr:** `attrOrProp (volitelné)`\n\n- **Modifikátory**\n\n - `.camel` - převede název atributu z kebab-case na camelCase.\n - `.prop` - vynutí binding jako vlastnost (prop) DOM. <sup class=\"vt-badge\">3.2+</sup>\n - `.attr` - vynutí binding jako atribut DOM. <sup class=\"vt-badge\">3.2+</sup>\n\n- **Použití**\n\n Pokud se používá pro binding atributu `class` nebo `style`, `v-bind` podporuje další typy hodnot, jako jsou pole nebo objekty. Podrobnosti naleznete v příslušné části průvodce níže.\n\n Při nastavování bindingu na element Vue ve výchozím nastavení kontroluje, zda má element klíč definovaný jako vlastnost pomocí operátoru `in`. Pokud je vlastnost definována, Vue nastaví hodnotu jako vlastnost DOM místo atributu. To by mělo fungovat ve většině případů, ale toto chování můžete přepsat explicitním použitím modifikátorů `.prop` nebo `.attr`. To je někdy nutné, zejména při [práci s custom elementy](https://cs.vuejs.org/guide/extras/web-components.html#passing-dom-properties).\n\n Při použití pro binding vlastností (props) komponenty musí být vlastnost v&nbsp;komponentě potomka správně deklarována.\n\n Pokud se používá bez parametru, může být použito pro binding objektu obsahujícího páry název-hodnota atributu.\n\n- **Příklad**\n\n ```html\n <!-- binding atributu -->\n <img v-bind:src=\"imageSrc\" />\n\n <!-- dynamický název atributu -->\n <button v-bind:[key]=\"value\"></button>\n\n <!-- zkratka -->\n <img :src=\"imageSrc\" />\n\n <!-- zkratka stejného názvu (3.4+), bude rozšířeno na :src=\"src\" -->\n <img :src />\n\n <!-- zkratka s dynamickým názvem atributu -->\n <button :[key]=\"value\"></button>\n\n <!-- se spojením řetězců -->\n <img :src=\"'/path/to/images/' + fileName\" />\n\n <!-- binding třídy -->\n <div :class=\"{ red: isRed }\"></div>\n <div :class=\"[classA, classB]\"></div>\n <div :class=\"[classA, { classB: isB, classC: isC }]\"></div>\n\n <!-- binding stylů -->\n <div :style=\"{ fontSize: size + 'px' }\"></div>\n <div :style=\"[styleObjectA, styleObjectB]\"></div>\n\n <!-- binding objektu attributů -->\n <div v-bind=\"{ id: someProp, 'other-attr': otherProp }\"></div>\n\n <!-- binding vlastnosti, `prop` musí být deklarována v komponentě potomka -->\n <MyComponent :prop=\"someThing\" />\n\n <!-- předání props z rodiče, které jsou společné s komponentnou potomka -->\n <MyComponent v-bind=\"$props\" />\n\n <!-- XLink -->\n <svg><a :xlink:special=\"foo\"></a></svg>\n ```\n\nModifikátor `.prop` má také zkrácenou formu, `.`:\n\n```html\n<div :someProperty.prop=\"someObject\"></div>\n\n<!-- ekvivalentní zápis -->\n<div .someProperty=\"someObject\"></div>\n```\n\nModifikátor `.camel` umožňuje převést jméno atributu `v-bind` na camelCase, například atribut `viewBox` ve SVG:\n\n```html\n<svg :view-box.camel=\"viewBox\"></svg>\n```\n\n`.camel` není potřeba, pokud používáte řetězcové šablony nebo předkompilujete šablonu pomocí build fáze.\n\n- **Viz také:**\n - [Binding tříd a stylů](https://cs.vuejs.org/guide/essentials/class-and-style.html)\n - [Vlastnosti (Props) - Detaily předávání vlastností](https://cs.vuejs.org/guide/components/props.html#prop-passing-details)\n"
995
+ "value": "\nDynamicky váže jeden nebo více atributů nebo vlastností (props) komponenty na výraz.\n\n- **Zkratka:** \n - `:` nebo `.` (pokud se používá modifikátor `.prop`)\n - Vynechání hodnoty (pokud mají atribut a vázaná hodnota stejný název), podporováno až od verze 3.4+\n\n- **Očekává:** `libovolný (s parametrem) | Objekt (bez parametru)`\n\n- **Parametr:** `attrOrProp (volitelné)`\n\n- **Modifikátory**\n\n - `.camel` - převede název atributu z kebab-case na camelCase.\n - `.prop` - vynutí binding jako vlastnost (prop) DOM (3.2+).\n - `.attr` - vynutí binding jako atribut DOM (3.2+).\n\n- **Použití**\n\n Pokud se používá pro binding atributu `class` nebo `style`, `v-bind` podporuje další typy hodnot, jako jsou pole nebo objekty. Podrobnosti naleznete v příslušné části průvodce níže.\n\n Při nastavování bindingu na element Vue ve výchozím nastavení kontroluje, zda má element klíč definovaný jako vlastnost pomocí operátoru `in`. Pokud je vlastnost definována, Vue nastaví hodnotu jako vlastnost DOM místo atributu. To by mělo fungovat ve většině případů, ale toto chování můžete přepsat explicitním použitím modifikátorů `.prop` nebo `.attr`. To je někdy nutné, zejména při [práci s custom elementy](https://cs.vuejs.org/guide/extras/web-components.html#passing-dom-properties).\n\n Při použití pro binding vlastností (props) komponenty musí být vlastnost v&nbsp;komponentě potomka správně deklarována.\n\n Pokud se používá bez parametru, může být použito pro binding objektu obsahujícího páry název-hodnota atributu.\n\n- **Příklad**\n\n ```html\n <!-- binding atributu -->\n <img v-bind:src=\"imageSrc\" />\n\n <!-- dynamický název atributu -->\n <button v-bind:[key]=\"value\"></button>\n\n <!-- zkratka -->\n <img :src=\"imageSrc\" />\n\n <!-- zkratka stejného názvu (3.4+), bude rozšířeno na :src=\"src\" -->\n <img :src />\n\n <!-- zkratka s dynamickým názvem atributu -->\n <button :[key]=\"value\"></button>\n\n <!-- se spojením řetězců -->\n <img :src=\"'/path/to/images/' + fileName\" />\n\n <!-- binding třídy -->\n <div :class=\"{ red: isRed }\"></div>\n <div :class=\"[classA, classB]\"></div>\n <div :class=\"[classA, { classB: isB, classC: isC }]\"></div>\n\n <!-- binding stylů -->\n <div :style=\"{ fontSize: size + 'px' }\"></div>\n <div :style=\"[styleObjectA, styleObjectB]\"></div>\n\n <!-- binding objektu attributů -->\n <div v-bind=\"{ id: someProp, 'other-attr': otherProp }\"></div>\n\n <!-- binding vlastnosti, `prop` musí být deklarována v komponentě potomka -->\n <MyComponent :prop=\"someThing\" />\n\n <!-- předání props z rodiče, které jsou společné s komponentnou potomka -->\n <MyComponent v-bind=\"$props\" />\n\n <!-- XLink -->\n <svg><a :xlink:special=\"foo\"></a></svg>\n ```\n\nModifikátor `.prop` má také zkrácenou formu, `.`:\n\n```html\n<div :someProperty.prop=\"someObject\"></div>\n\n<!-- ekvivalentní zápis -->\n<div .someProperty=\"someObject\"></div>\n```\n\nModifikátor `.camel` umožňuje převést jméno atributu `v-bind` na camelCase, například atribut `viewBox` ve SVG:\n\n```html\n<svg :view-box.camel=\"viewBox\"></svg>\n```\n\n`.camel` není potřeba, pokud používáte řetězcové šablony nebo předkompilujete šablonu pomocí build fáze.\n\n- **Viz také:**\n - [Binding tříd a stylů](https://cs.vuejs.org/guide/essentials/class-and-style.html)\n - [Vlastnosti (Props) - Detaily předávání vlastností](https://cs.vuejs.org/guide/components/props.html#prop-passing-details)\n"
996
996
  },
997
997
  "references": [
998
998
  {
@@ -1299,7 +1299,7 @@
1299
1299
  "name": "v-memo",
1300
1300
  "description": {
1301
1301
  "kind": "markdown",
1302
- "value": "\n- **Očekává:** `any[]`\n\n- **Podrobnosti**\n\n Uloží si (memoize) podstrom šablony. Může být použito jak na elementech, tak na komponentách. Direktiva očekává pole hodnot závislostí pevné délky, které se porovnávají pro zapamatování. Pokud každá hodnota v poli byla stejná jako při posledním vykreslení, aktualizace pro celý podstrom bude přeskočena. Například:\n\n ```html\n <div v-memo=\"[hodnotaA, hodnotaB]\">\n ...\n </div>\n ```\n\n Pokud při opětovném vykreslení komponenty zůstanou jak `hodnotaA`, tak `hodnotaB` stejné, všechny aktualizace pro tento `<div>` a jeho potomky budou přeskočeny. Ve skutečnosti bude přeskočeno i vytváření Virtual DOM VNode, protože memoizovaná kopie podstromu může být znovu použita.\n\n Je důležité správně specifikovat pole pro zapamatování, jinak můžeme přeskočit aktualizace, které by aplikovány být měly. `v-memo` s prázdným polem závislostí (`v-memo=\"[]\"`) by bylo funkčně ekvivalentní `v-once`.\n\n **Použití s `v-for`**\n\n `v-memo` je poskytováno výhradně pro mikrooptimalizace výkonu a je potřeba jen zřídka. Nejběžnější případ, kdy se to může hodit, je při vykreslování velkých seznamů `v-for` (kde `length > 1000`):\n\n ```html\n <div v-for=\"prvek in seznam\" :key=\"prvek.id\" v-memo=\"[prvek.id === vybrano]\">\n <p>ID: {{ prvek.id }} - vybráno: {{ prvek.id === vybrano }}</p>\n <p>...další potomci</p>\n </div>\n ```\n\n Při změně stavu `vybrano` komponenty bude vytvořeno velké množství VNodes, i když většina položek zůstala přesně stejná. Použití `v-memo` zde znamená _„aktualizujte tuto položku pouze tehdy, pokud se změnila z nevybrané na vybranou nebo naopak“_. To&nbsp;umožňuje každé neovlivněné položce znovu použít její předchozí VNode a úplně přeskočit porovnávání rozdílů. Poznamenejme, že zde do pole závislostí pro zapamatování nemusíme zahrnout `prvek.id`, protože Vue ji automaticky odvodí z&nbsp;`:key` položky.\n\n :::warning Varování\n Při použití `v-memo` s `v-for` se ujistěte, že jsou použity na stejném elementu. **`v-memo` nefunguje uvnitř `v-for`.**\n :::\n\n `v-memo` lze také použít na komponentách k manuálnímu zabránění nechtěným aktualizacím v určitých okrajových případech, kdy byla kontrola aktualizace potomka de-optimalizována. Ale opět je zodpovědností vývojáře specifikovat správné pole závislostí, aby se zabránilo vynechání nutných aktualizací.\n\n- **Viz také:**\n - [v-once](#v-once)\n"
1302
+ "value": "\n- Podporováno až od verze 3.2+\n\n- **Očekává:** `any[]`\n\n- **Podrobnosti**\n\n Uloží si (memoize) podstrom šablony. Může být použito jak na elementech, tak na komponentách. Direktiva očekává pole hodnot závislostí pevné délky, které se porovnávají pro zapamatování. Pokud každá hodnota v poli byla stejná jako při posledním vykreslení, aktualizace pro celý podstrom bude přeskočena. Například:\n\n ```html\n <div v-memo=\"[hodnotaA, hodnotaB]\">\n ...\n </div>\n ```\n\n Pokud při opětovném vykreslení komponenty zůstanou jak `hodnotaA`, tak `hodnotaB` stejné, všechny aktualizace pro tento `<div>` a jeho potomky budou přeskočeny. Ve skutečnosti bude přeskočeno i vytváření Virtual DOM VNode, protože memoizovaná kopie podstromu může být znovu použita.\n\n Je důležité správně specifikovat pole pro zapamatování, jinak můžeme přeskočit aktualizace, které by aplikovány být měly. `v-memo` s prázdným polem závislostí (`v-memo=\"[]\"`) by bylo funkčně ekvivalentní `v-once`.\n\n **Použití s `v-for`**\n\n `v-memo` je poskytováno výhradně pro mikrooptimalizace výkonu a je potřeba jen zřídka. Nejběžnější případ, kdy se to může hodit, je při vykreslování velkých seznamů `v-for` (kde `length > 1000`):\n\n ```html\n <div v-for=\"prvek in seznam\" :key=\"prvek.id\" v-memo=\"[prvek.id === vybrano]\">\n <p>ID: {{ prvek.id }} - vybráno: {{ prvek.id === vybrano }}</p>\n <p>...další potomci</p>\n </div>\n ```\n\n Při změně stavu `vybrano` komponenty bude vytvořeno velké množství VNodes, i když většina položek zůstala přesně stejná. Použití `v-memo` zde znamená _„aktualizujte tuto položku pouze tehdy, pokud se změnila z nevybrané na vybranou nebo naopak“_. To&nbsp;umožňuje každé neovlivněné položce znovu použít její předchozí VNode a úplně přeskočit porovnávání rozdílů. Poznamenejme, že zde do pole závislostí pro zapamatování nemusíme zahrnout `prvek.id`, protože Vue ji automaticky odvodí z&nbsp;`:key` položky.\n\n :::warning Varování\n Při použití `v-memo` s `v-for` se ujistěte, že jsou použity na stejném elementu. **`v-memo` nefunguje uvnitř `v-for`.**\n :::\n\n `v-memo` lze také použít na komponentách k manuálnímu zabránění nechtěným aktualizacím v určitých okrajových případech, kdy byla kontrola aktualizace potomka de-optimalizována. Ale opět je zodpovědností vývojáře specifikovat správné pole závislostí, aby se zabránilo vynechání nutných aktualizací.\n\n- **Viz také:**\n - [v-once](#v-once)\n"
1303
1303
  },
1304
1304
  "references": [
1305
1305
  {
@@ -1544,7 +1544,7 @@
1544
1544
  "name": "is",
1545
1545
  "description": {
1546
1546
  "kind": "markdown",
1547
- "value": "\nPoužívá se pro binding [dynamických komponent](https://cs.vuejs.org/guide/essentials/component-basics.html#dynamic-components).\n\n- **Očekává:** `string | Komponenta`\n\n- **Použití na nativních elementech** <sup class=\"vt-badge\">3.1+</sup>\n\n Když je atribut `is` použit na nativním HTML elementu, bude interpretován jako [custom vestavěný element](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-customized-builtin-example), což je nativní funkce webové platformy.\n\n Existuje však případ použití, kdy můžete potřebovat, aby Vue nahradilo nativní element Vue komponentou, jak je vysvětleno v [upozornění na omezení při parsování in-DOM šablon](https://cs.vuejs.org/guide/essentials/component-basics.html#in-dom-template-parsing-caveats). Můžete atributu `is` přidat předponu `vue:`, aby Vue vykreslilo element jako Vue komponentu:\n\n ```html\n <table>\n <tr is=\"vue:my-row-component\"></tr>\n </table>\n ```\n\n- **Viz také:**\n\n - [Vestavěné speciální elementy - `<component>`](https://cs.vuejs.org/api/built-in-special-elements.html#component)\n - [Dynamické komponenty](https://cs.vuejs.org/guide/essentials/component-basics.html#dynamic-components)\n"
1547
+ "value": "\nPoužívá se pro binding [dynamických komponent](https://cs.vuejs.org/guide/essentials/component-basics.html#dynamic-components).\n\n- **Očekává:** `string | Komponenta`\n\n- **Použití na nativních elementech**\n\n - Podporováno až od verze 3.1+\n\n Když je atribut `is` použit na nativním HTML elementu, bude interpretován jako [custom vestavěný element](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-customized-builtin-example), což je nativní funkce webové platformy.\n\n Existuje však případ použití, kdy můžete potřebovat, aby Vue nahradilo nativní element Vue komponentou, jak je vysvětleno v [upozornění na omezení při parsování in-DOM šablon](https://cs.vuejs.org/guide/essentials/component-basics.html#in-dom-template-parsing-caveats). Můžete atributu `is` přidat předponu `vue:`, aby Vue vykreslilo element jako Vue komponentu:\n\n ```html\n <table>\n <tr is=\"vue:my-row-component\"></tr>\n </table>\n ```\n\n- **Viz také:**\n\n - [Vestavěné speciální elementy - `<component>`](https://cs.vuejs.org/api/built-in-special-elements.html#component)\n - [Dynamické komponenty](https://cs.vuejs.org/guide/essentials/component-basics.html#dynamic-components)\n"
1548
1548
  },
1549
1549
  "references": [
1550
1550
  {
@@ -191,7 +191,7 @@
191
191
  "name": "Teleport",
192
192
  "description": {
193
193
  "kind": "markdown",
194
- "value": "\nRenders its slot content to another part of the DOM.\n\n- **Props**\n\n ```ts\n interface TeleportProps {\n /**\n * Required. Specify target container.\n * Can either be a selector or an actual element.\n */\n to: string | HTMLElement\n /**\n * When `true`, the content will remain in its original\n * location instead of moved into the target container.\n * Can be changed dynamically.\n */\n disabled?: boolean\n }\n ```\n\n- **Example**\n\n Specifying target container:\n\n ```html\n <Teleport to=\"#some-id\" />\n <Teleport to=\".some-class\" />\n <Teleport to=\"[data-teleport]\" />\n ```\n\n Conditionally disabling:\n\n ```html\n <Teleport to=\"#popup\" :disabled=\"displayVideoInline\">\n <video src=\"./my-movie.mp4\">\n </Teleport>\n ```\n\n- **See also** [Guide - Teleport](https://vuejs.org/guide/built-ins/teleport.html)\n"
194
+ "value": "\nRenders its slot content to another part of the DOM.\n\n- **Props**\n\n ```ts\n interface TeleportProps {\n /**\n * Required. Specify target container.\n * Can either be a selector or an actual element.\n */\n to: string | HTMLElement\n /**\n * When `true`, the content will remain in its original\n * location instead of moved into the target container.\n * Can be changed dynamically.\n */\n disabled?: boolean\n /**\n * When `true`, the Teleport will defer until other\n * parts of the application have been mounted before\n * resolving its target. (3.5+)\n */\n defer?: boolean\n }\n ```\n\n- **Example**\n\n Specifying target container:\n\n ```html\n <Teleport to=\"#some-id\" />\n <Teleport to=\".some-class\" />\n <Teleport to=\"[data-teleport]\" />\n ```\n\n Conditionally disabling:\n\n ```html\n <Teleport to=\"#popup\" :disabled=\"displayVideoInline\">\n <video src=\"./my-movie.mp4\">\n </Teleport>\n ```\n\n Defer target resolution <sup class=\"vt-badge\" data-text=\"3.5+\" />:\n\n ```html\n <Teleport defer to=\"#late-div\">...</Teleport>\n\n <!-- somewhere later in the template -->\n <div id=\"late-div\"></div>\n ```\n\n- **See also** [Guide - Teleport](https://vuejs.org/guide/built-ins/teleport.html)\n"
195
195
  },
196
196
  "attributes": [],
197
197
  "references": [
@@ -992,7 +992,7 @@
992
992
  "name": "v-bind",
993
993
  "description": {
994
994
  "kind": "markdown",
995
- "value": "\nDynamically bind one or more attributes, or a component prop to an expression.\n\n- **Shorthand:**\n - `:` or `.` (when using `.prop` modifier)\n - Omitting value (when attribute and bound value has the same name) <sup class=\"vt-badge\">3.4+</sup>\n\n- **Expects:** `any (with argument) | Object (without argument)`\n\n- **Argument:** `attrOrProp (optional)`\n\n- **Modifiers**\n\n - `.camel` - transform the kebab-case attribute name into camelCase.\n - `.prop` - force a binding to be set as a DOM property. <sup class=\"vt-badge\">3.2+</sup>\n - `.attr` - force a binding to be set as a DOM attribute. <sup class=\"vt-badge\">3.2+</sup>\n\n- **Usage**\n\n When used to bind the `class` or `style` attribute, `v-bind` supports additional value types such as Array or Objects. See linked guide section below for more details.\n\n When setting a binding on an element, Vue by default checks whether the element has the key defined as a property using an `in` operator check. If the property is defined, Vue will set the value as a DOM property instead of an attribute. This should work in most cases, but you can override this behavior by explicitly using `.prop` or `.attr` modifiers. This is sometimes necessary, especially when [working with custom elements](https://vuejs.org/guide/extras/web-components.html#passing-dom-properties).\n\n When used for component prop binding, the prop must be properly declared in the child component.\n\n When used without an argument, can be used to bind an object containing attribute name-value pairs.\n\n- **Example**\n\n ```html\n <!-- bind an attribute -->\n <img v-bind:src=\"imageSrc\" />\n\n <!-- dynamic attribute name -->\n <button v-bind:[key]=\"value\"></button>\n\n <!-- shorthand -->\n <img :src=\"imageSrc\" />\n\n <!-- same-name shorthand (3.4+), expands to :src=\"src\" -->\n <img :src />\n\n <!-- shorthand dynamic attribute name -->\n <button :[key]=\"value\"></button>\n\n <!-- with inline string concatenation -->\n <img :src=\"'/path/to/images/' + fileName\" />\n\n <!-- class binding -->\n <div :class=\"{ red: isRed }\"></div>\n <div :class=\"[classA, classB]\"></div>\n <div :class=\"[classA, { classB: isB, classC: isC }]\"></div>\n\n <!-- style binding -->\n <div :style=\"{ fontSize: size + 'px' }\"></div>\n <div :style=\"[styleObjectA, styleObjectB]\"></div>\n\n <!-- binding an object of attributes -->\n <div v-bind=\"{ id: someProp, 'other-attr': otherProp }\"></div>\n\n <!-- prop binding. \"prop\" must be declared in the child component. -->\n <MyComponent :prop=\"someThing\" />\n\n <!-- pass down parent props in common with a child component -->\n <MyComponent v-bind=\"$props\" />\n\n <!-- XLink -->\n <svg><a :xlink:special=\"foo\"></a></svg>\n ```\n\n The `.prop` modifier also has a dedicated shorthand, `.`:\n\n ```html\n <div :someProperty.prop=\"someObject\"></div>\n\n <!-- equivalent to -->\n <div .someProperty=\"someObject\"></div>\n ```\n\n The `.camel` modifier allows camelizing a `v-bind` attribute name when using in-DOM templates, e.g. the SVG `viewBox` attribute:\n\n ```html\n <svg :view-box.camel=\"viewBox\"></svg>\n ```\n\n `.camel` is not needed if you are using string templates, or pre-compiling the template with a build step.\n\n- **See also**\n - [Class and Style Bindings](https://vuejs.org/guide/essentials/class-and-style.html)\n - [Components - Prop Passing Details](https://vuejs.org/guide/components/props.html#prop-passing-details)\n"
995
+ "value": "\nDynamically bind one or more attributes, or a component prop to an expression.\n\n- **Shorthand:**\n - `:` or `.` (when using `.prop` modifier)\n - Omitting value (when attribute and bound value has the same name, requires 3.4+)\n\n- **Expects:** `any (with argument) | Object (without argument)`\n\n- **Argument:** `attrOrProp (optional)`\n\n- **Modifiers**\n\n - `.camel` - transform the kebab-case attribute name into camelCase.\n - `.prop` - force a binding to be set as a DOM property (3.2+).\n - `.attr` - force a binding to be set as a DOM attribute (3.2+).\n\n- **Usage**\n\n When used to bind the `class` or `style` attribute, `v-bind` supports additional value types such as Array or Objects. See linked guide section below for more details.\n\n When setting a binding on an element, Vue by default checks whether the element has the key defined as a property using an `in` operator check. If the property is defined, Vue will set the value as a DOM property instead of an attribute. This should work in most cases, but you can override this behavior by explicitly using `.prop` or `.attr` modifiers. This is sometimes necessary, especially when [working with custom elements](https://vuejs.org/guide/extras/web-components.html#passing-dom-properties).\n\n When used for component prop binding, the prop must be properly declared in the child component.\n\n When used without an argument, can be used to bind an object containing attribute name-value pairs.\n\n- **Example**\n\n ```html\n <!-- bind an attribute -->\n <img v-bind:src=\"imageSrc\" />\n\n <!-- dynamic attribute name -->\n <button v-bind:[key]=\"value\"></button>\n\n <!-- shorthand -->\n <img :src=\"imageSrc\" />\n\n <!-- same-name shorthand (3.4+), expands to :src=\"src\" -->\n <img :src />\n\n <!-- shorthand dynamic attribute name -->\n <button :[key]=\"value\"></button>\n\n <!-- with inline string concatenation -->\n <img :src=\"'/path/to/images/' + fileName\" />\n\n <!-- class binding -->\n <div :class=\"{ red: isRed }\"></div>\n <div :class=\"[classA, classB]\"></div>\n <div :class=\"[classA, { classB: isB, classC: isC }]\"></div>\n\n <!-- style binding -->\n <div :style=\"{ fontSize: size + 'px' }\"></div>\n <div :style=\"[styleObjectA, styleObjectB]\"></div>\n\n <!-- binding an object of attributes -->\n <div v-bind=\"{ id: someProp, 'other-attr': otherProp }\"></div>\n\n <!-- prop binding. \"prop\" must be declared in the child component. -->\n <MyComponent :prop=\"someThing\" />\n\n <!-- pass down parent props in common with a child component -->\n <MyComponent v-bind=\"$props\" />\n\n <!-- XLink -->\n <svg><a :xlink:special=\"foo\"></a></svg>\n ```\n\n The `.prop` modifier also has a dedicated shorthand, `.`:\n\n ```html\n <div :someProperty.prop=\"someObject\"></div>\n\n <!-- equivalent to -->\n <div .someProperty=\"someObject\"></div>\n ```\n\n The `.camel` modifier allows camelizing a `v-bind` attribute name when using in-DOM templates, e.g. the SVG `viewBox` attribute:\n\n ```html\n <svg :view-box.camel=\"viewBox\"></svg>\n ```\n\n `.camel` is not needed if you are using string templates, or pre-compiling the template with a build step.\n\n- **See also**\n - [Class and Style Bindings](https://vuejs.org/guide/essentials/class-and-style.html)\n - [Components - Prop Passing Details](https://vuejs.org/guide/components/props.html#prop-passing-details)\n"
996
996
  },
997
997
  "references": [
998
998
  {
@@ -1299,7 +1299,7 @@
1299
1299
  "name": "v-memo",
1300
1300
  "description": {
1301
1301
  "kind": "markdown",
1302
- "value": "\n- **Expects:** `any[]`\n\n- **Details**\n\n Memoize a sub-tree of the template. Can be used on both elements and components. The directive expects a fixed-length array of dependency values to compare for the memoization. If every value in the array was the same as last render, then updates for the entire sub-tree will be skipped. For example:\n\n ```html\n <div v-memo=\"[valueA, valueB]\">\n ...\n </div>\n ```\n\n When the component re-renders, if both `valueA` and `valueB` remain the same, all updates for this `<div>` and its children will be skipped. In fact, even the Virtual DOM VNode creation will also be skipped since the memoized copy of the sub-tree can be reused.\n\n It is important to specify the memoization array correctly, otherwise we may skip updates that should indeed be applied. `v-memo` with an empty dependency array (`v-memo=\"[]\"`) would be functionally equivalent to `v-once`.\n\n **Usage with `v-for`**\n\n `v-memo` is provided solely for micro optimizations in performance-critical scenarios and should be rarely needed. The most common case where this may prove helpful is when rendering large `v-for` lists (where `length > 1000`):\n\n ```html\n <div v-for=\"item in list\" :key=\"item.id\" v-memo=\"[item.id === selected]\">\n <p>ID: {{ item.id }} - selected: {{ item.id === selected }}</p>\n <p>...more child nodes</p>\n </div>\n ```\n\n When the component's `selected` state changes, a large amount of VNodes will be created even though most of the items remained exactly the same. The `v-memo` usage here is essentially saying \"only update this item if it went from non-selected to selected, or the other way around\". This allows every unaffected item to reuse its previous VNode and skip diffing entirely. Note we don't need to include `item.id` in the memo dependency array here since Vue automatically infers it from the item's `:key`.\n\n :::warning\n When using `v-memo` with `v-for`, make sure they are used on the same element. **`v-memo` does not work inside `v-for`.**\n :::\n\n `v-memo` can also be used on components to manually prevent unwanted updates in certain edge cases where the child component update check has been de-optimized. But again, it is the developer's responsibility to specify correct dependency arrays to avoid skipping necessary updates.\n\n- **See also**\n - [v-once](#v-once)\n"
1302
+ "value": "\n- Only supported in 3.2+\n\n- **Expects:** `any[]`\n\n- **Details**\n\n Memoize a sub-tree of the template. Can be used on both elements and components. The directive expects a fixed-length array of dependency values to compare for the memoization. If every value in the array was the same as last render, then updates for the entire sub-tree will be skipped. For example:\n\n ```html\n <div v-memo=\"[valueA, valueB]\">\n ...\n </div>\n ```\n\n When the component re-renders, if both `valueA` and `valueB` remain the same, all updates for this `<div>` and its children will be skipped. In fact, even the Virtual DOM VNode creation will also be skipped since the memoized copy of the sub-tree can be reused.\n\n It is important to specify the memoization array correctly, otherwise we may skip updates that should indeed be applied. `v-memo` with an empty dependency array (`v-memo=\"[]\"`) would be functionally equivalent to `v-once`.\n\n **Usage with `v-for`**\n\n `v-memo` is provided solely for micro optimizations in performance-critical scenarios and should be rarely needed. The most common case where this may prove helpful is when rendering large `v-for` lists (where `length > 1000`):\n\n ```html\n <div v-for=\"item in list\" :key=\"item.id\" v-memo=\"[item.id === selected]\">\n <p>ID: {{ item.id }} - selected: {{ item.id === selected }}</p>\n <p>...more child nodes</p>\n </div>\n ```\n\n When the component's `selected` state changes, a large amount of VNodes will be created even though most of the items remained exactly the same. The `v-memo` usage here is essentially saying \"only update this item if it went from non-selected to selected, or the other way around\". This allows every unaffected item to reuse its previous VNode and skip diffing entirely. Note we don't need to include `item.id` in the memo dependency array here since Vue automatically infers it from the item's `:key`.\n\n :::warning\n When using `v-memo` with `v-for`, make sure they are used on the same element. **`v-memo` does not work inside `v-for`.**\n :::\n\n `v-memo` can also be used on components to manually prevent unwanted updates in certain edge cases where the child component update check has been de-optimized. But again, it is the developer's responsibility to specify correct dependency arrays to avoid skipping necessary updates.\n\n- **See also**\n - [v-once](#v-once)\n"
1303
1303
  },
1304
1304
  "references": [
1305
1305
  {
@@ -1544,7 +1544,7 @@
1544
1544
  "name": "is",
1545
1545
  "description": {
1546
1546
  "kind": "markdown",
1547
- "value": "\nUsed for binding [dynamic components](https://vuejs.org/guide/essentials/component-basics.html#dynamic-components).\n\n- **Expects:** `string | Component`\n\n- **Usage on native elements** <sup class=\"vt-badge\">3.1+</sup>\n\n When the `is` attribute is used on a native HTML element, it will be interpreted as a [Customized built-in element](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-customized-builtin-example), which is a native web platform feature.\n\n There is, however, a use case where you may need Vue to replace a native element with a Vue component, as explained in [in-DOM Template Parsing Caveats](https://vuejs.org/guide/essentials/component-basics.html#in-dom-template-parsing-caveats). You can prefix the value of the `is` attribute with `vue:` so that Vue will render the element as a Vue component instead:\n\n ```html\n <table>\n <tr is=\"vue:my-row-component\"></tr>\n </table>\n ```\n\n- **See also**\n\n - [Built-in Special Element - `<component>`](https://vuejs.org/api/built-in-special-elements.html#component)\n - [Dynamic Components](https://vuejs.org/guide/essentials/component-basics.html#dynamic-components)\n"
1547
+ "value": "\nUsed for binding [dynamic components](https://vuejs.org/guide/essentials/component-basics.html#dynamic-components).\n\n- **Expects:** `string | Component`\n\n- **Usage on native elements**\n \n - Only supported in 3.1+\n\n When the `is` attribute is used on a native HTML element, it will be interpreted as a [Customized built-in element](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-customized-builtin-example), which is a native web platform feature.\n\n There is, however, a use case where you may need Vue to replace a native element with a Vue component, as explained in [in-DOM Template Parsing Caveats](https://vuejs.org/guide/essentials/component-basics.html#in-dom-template-parsing-caveats). You can prefix the value of the `is` attribute with `vue:` so that Vue will render the element as a Vue component instead:\n\n ```html\n <table>\n <tr is=\"vue:my-row-component\"></tr>\n </table>\n ```\n\n- **See also**\n\n - [Built-in Special Element - `<component>`](https://vuejs.org/api/built-in-special-elements.html#component)\n - [Dynamic Components](https://vuejs.org/guide/essentials/component-basics.html#dynamic-components)\n"
1548
1548
  },
1549
1549
  "references": [
1550
1550
  {
@@ -191,7 +191,7 @@
191
191
  "name": "Teleport",
192
192
  "description": {
193
193
  "kind": "markdown",
194
- "value": "\nПеремещает содержимое своего слота в другую часть DOM.\n\n- **Входные параметры**\n\n ```ts\n interface TeleportProps {\n /**\n * Обязательный. Задаёт целевой контейнер.\n * Может быть селектором или непосредственно элементом.\n */\n to: string | HTMLElement\n /**\n * Если `true`, содержимое останется на своем первоначальном\n * месте, вместо перемещения в целевой контейнер.\n * Может изменяться динамически.\n */\n disabled?: boolean\n }\n ```\n\n- **Пример**\n\n Указание целевого контейнера:\n\n ```html\n <Teleport to=\"#some-id\" />\n <Teleport to=\".some-class\" />\n <Teleport to=\"[data-teleport]\" />\n ```\n\n Перемещение по условию:\n\n ```html\n <Teleport to=\"#popup\" :disabled=\"displayVideoInline\">\n <video src=\"./my-movie.mp4\">\n </Teleport>\n ```\n\n- **См. также** [Руководство — Teleport](https://ru.vuejs.org/guide/built-ins/teleport.html)\n"
194
+ "value": "\nПеремещает содержимое своего слота в другую часть DOM.\n\n- **Входные параметры**\n\n ```ts\n interface TeleportProps {\n /**\n * Обязательный. Задаёт целевой контейнер.\n * Может быть селектором или непосредственно элементом.\n */\n to: string | HTMLElement\n /**\n * Если `true`, содержимое останется на своем первоначальном\n * месте, вместо перемещения в целевой контейнер.\n * Может изменяться динамически.\n */\n disabled?: boolean\n /**\n * When `true`, the Teleport will defer until other\n * parts of the application have been mounted before\n * resolving its target. (3.5+)\n */\n defer?: boolean\n }\n ```\n\n- **Пример**\n\n Указание целевого контейнера:\n\n ```html\n <Teleport to=\"#some-id\" />\n <Teleport to=\".some-class\" />\n <Teleport to=\"[data-teleport]\" />\n ```\n\n Перемещение по условию:\n\n ```html\n <Teleport to=\"#popup\" :disabled=\"displayVideoInline\">\n <video src=\"./my-movie.mp4\">\n </Teleport>\n ```\n\n Defer target resolution <sup class=\"vt-badge\" data-text=\"3.5+\" />:\n\n ```html\n <Teleport defer to=\"#late-div\">...</Teleport>\n\n <!-- somewhere later in the template -->\n <div id=\"late-div\"></div>\n ```\n\n- **См. также** [Руководство — Teleport](https://ru.vuejs.org/guide/built-ins/teleport.html)\n"
195
195
  },
196
196
  "attributes": [],
197
197
  "references": [
@@ -992,7 +992,7 @@
992
992
  "name": "v-bind",
993
993
  "description": {
994
994
  "kind": "markdown",
995
- "value": "\nДинамически привязывает один или несколько атрибутов или входных параметров компонента к выражению.\n\n- **Сокращённая запись**\n - `:` или `.` (при использовании модификатора `.prop`)\n - Пропуск значения (когда атрибут и связанное значение имеют одинаковое имя) <sup class=\"vt-badge\">3.4+</sup>\n\n- **Ожидает:** `any (если указан аргумент) | Object (без аргумента)`\n\n- **Аргумент:** `attrOrProp (опционально)`\n\n- **Модификаторы**\n\n - `.camel` - преобразование имён атрибутов из kebab-case в camelCase.\n - `.prop` - принудительная установить привязку в качестве свойства DOM. <sup class=\"vt-badge\">3.2+</sup>\n - `.attr` - принудительно установить привязку в качестве атрибута DOM. <sup class=\"vt-badge\">3.2+</sup>\n\n- **Применение**\n\n При использовании для привязки атрибутов `class` или `style`, `v-bind` поддерживает дополнительные типы значений, такие как Array или Objects. Более подробная информация приведена в разделе руководства по ссылкам ниже.\n\n Устанавливая привязку к элементу, Vue по умолчанию проверяет, имеет ли элемент ключ, определенный как свойство, используя проверку оператора `in`. Если свойство определено, то Vue установит значение как свойство DOM, а не как атрибут. В большинстве случаев это должно работать, но вы можете переопределить это поведение, явно используя модификаторы `.prop` или `.attr`. Иногда это необходимо, особенно при [работе с пользовательскими элементами](https://ru.vuejs.org/guide/extras/web-components.html#passing-dom-properties).\n\n При привязке входных параметров к дочернему компоненту необходимо также объявлять их внутри него.\n\n При использовании без аргумента можно привязать объект из пар имя-значение.\n\n- **Пример**\n\n ```html\n <!-- привязка атрибута -->\n <img v-bind:src=\"imageSrc\" />\n\n <!-- динамическое название атрибута -->\n <button v-bind:[key]=\"value\"></button>\n\n <!-- сокращённая запись -->\n <img :src=\"imageSrc\" />\n\n <!-- сокращение при одинаковом названии (3.4+), расширяется до :src=\"src\" -->\n <img :src />\n\n <!-- сокращённая запись при динамическом названии атрибута -->\n <button :[key]=\"value\"></button>\n\n <!-- инлайн-выражение с конкатенацией строк -->\n <img :src=\"'/path/to/images/' + fileName\" />\n\n <!-- привязка классов -->\n <div :class=\"{ red: isRed }\"></div>\n <div :class=\"[classA, classB]\"></div>\n <div :class=\"[classA, { classB: isB, classC: isC }]\"></div>\n\n <!-- привязка стилей -->\n <div :style=\"{ fontSize: size + 'px' }\"></div>\n <div :style=\"[styleObjectA, styleObjectB]\"></div>\n\n <!-- привязка объекта с атрибутами -->\n <div v-bind=\"{ id: someProp, 'other-attr': otherProp }\"></div>\n\n <!-- привязка входного параметра. \"prop\" должен быть объявлен в my-component. -->\n <MyComponent :prop=\"someThing\" />\n\n <!-- передача всех входных параметров родительского компонента в дочерний -->\n <MyComponent v-bind=\"$props\" />\n\n <!-- XLink -->\n <svg><a :xlink:special=\"foo\"></a></svg>\n ```\n\n Модификатор `.prop` также имеет сокращённую запись `.`:\n\n ```html\n <div :someProperty.prop=\"someObject\"></div>\n\n <!-- эквивалент -->\n <div .someProperty=\"someObject\"></div>\n ```\n\n Модификатор `.camel` позволяет приводить имя атрибута `v-bind` в camelCase при использовании DOM-шаблонов, например для атрибута SVG `viewBox`:\n\n ```html\n <svg :view-box.camel=\"viewBox\"></svg>\n ```\n\n Модификатор `.camel` не нужен, если вы используете строковые шаблоны или предварительно компилируете шаблон на этапе сборки.\n\n- **См. также**\n - [Работа с классами и стилями](https://ru.vuejs.org/guide/essentials/class-and-style.html)\n - [Компоненты - Детали передачи входных параметров](https://ru.vuejs.org/guide/components/props.html#prop-passing-details)\n"
995
+ "value": "\nДинамически привязывает один или несколько атрибутов или входных параметров компонента к выражению.\n\n- **Сокращённая запись**\n - `:` или `.` (при использовании модификатора `.prop`)\n - Пропуск значения (когда атрибут и связанное значение имеют одинаковое имя) requires 3.4+\n\n- **Ожидает:** `any (если указан аргумент) | Object (без аргумента)`\n\n- **Аргумент:** `attrOrProp (опционально)`\n\n- **Модификаторы**\n\n - `.camel` - преобразование имён атрибутов из kebab-case в camelCase.\n - `.prop` - принудительная установить привязку в качестве свойства DOM (3.2+).\n - `.attr` - принудительно установить привязку в качестве атрибута DOM (3.2+).\n\n- **Применение**\n\n При использовании для привязки атрибутов `class` или `style`, `v-bind` поддерживает дополнительные типы значений, такие как Array или Objects. Более подробная информация приведена в разделе руководства по ссылкам ниже.\n\n Устанавливая привязку к элементу, Vue по умолчанию проверяет, имеет ли элемент ключ, определенный как свойство, используя проверку оператора `in`. Если свойство определено, то Vue установит значение как свойство DOM, а не как атрибут. В большинстве случаев это должно работать, но вы можете переопределить это поведение, явно используя модификаторы `.prop` или `.attr`. Иногда это необходимо, особенно при [работе с пользовательскими элементами](https://ru.vuejs.org/guide/extras/web-components.html#passing-dom-properties).\n\n При привязке входных параметров к дочернему компоненту необходимо также объявлять их внутри него.\n\n При использовании без аргумента можно привязать объект из пар имя-значение.\n\n- **Пример**\n\n ```html\n <!-- привязка атрибута -->\n <img v-bind:src=\"imageSrc\" />\n\n <!-- динамическое название атрибута -->\n <button v-bind:[key]=\"value\"></button>\n\n <!-- сокращённая запись -->\n <img :src=\"imageSrc\" />\n\n <!-- сокращение при одинаковом названии (3.4+), расширяется до :src=\"src\" -->\n <img :src />\n\n <!-- сокращённая запись при динамическом названии атрибута -->\n <button :[key]=\"value\"></button>\n\n <!-- инлайн-выражение с конкатенацией строк -->\n <img :src=\"'/path/to/images/' + fileName\" />\n\n <!-- привязка классов -->\n <div :class=\"{ red: isRed }\"></div>\n <div :class=\"[classA, classB]\"></div>\n <div :class=\"[classA, { classB: isB, classC: isC }]\"></div>\n\n <!-- привязка стилей -->\n <div :style=\"{ fontSize: size + 'px' }\"></div>\n <div :style=\"[styleObjectA, styleObjectB]\"></div>\n\n <!-- привязка объекта с атрибутами -->\n <div v-bind=\"{ id: someProp, 'other-attr': otherProp }\"></div>\n\n <!-- привязка входного параметра. \"prop\" должен быть объявлен в my-component. -->\n <MyComponent :prop=\"someThing\" />\n\n <!-- передача всех входных параметров родительского компонента в дочерний -->\n <MyComponent v-bind=\"$props\" />\n\n <!-- XLink -->\n <svg><a :xlink:special=\"foo\"></a></svg>\n ```\n\n Модификатор `.prop` также имеет сокращённую запись `.`:\n\n ```html\n <div :someProperty.prop=\"someObject\"></div>\n\n <!-- эквивалент -->\n <div .someProperty=\"someObject\"></div>\n ```\n\n Модификатор `.camel` позволяет приводить имя атрибута `v-bind` в camelCase при использовании DOM-шаблонов, например для атрибута SVG `viewBox`:\n\n ```html\n <svg :view-box.camel=\"viewBox\"></svg>\n ```\n\n Модификатор `.camel` не нужен, если вы используете строковые шаблоны или предварительно компилируете шаблон на этапе сборки.\n\n- **См. также**\n - [Работа с классами и стилями](https://ru.vuejs.org/guide/essentials/class-and-style.html)\n - [Компоненты - Детали передачи входных параметров](https://ru.vuejs.org/guide/components/props.html#prop-passing-details)\n"
996
996
  },
997
997
  "references": [
998
998
  {
@@ -1299,7 +1299,7 @@
1299
1299
  "name": "v-memo",
1300
1300
  "description": {
1301
1301
  "kind": "markdown",
1302
- "value": "\n- **Ожидает:** `any[]`\n\n- **Подробности**\n\n Мемоизация части поддерева шаблона. Может использоваться как для элементов, так и для компонентов. Директива ожидает массив фиксированной длины зависимых значений, которые станут использоваться для сравнения при мемоизации. Если каждое значение массива осталось таким же, как при последней отрисовке, то обновление всего поддерева будет пропущено. Например:\n\n ```html\n <div v-memo=\"[valueA, valueB]\">\n ...\n </div>\n ```\n\n При повторном рендеринге компонента, если `valueA` и `valueB` остались прежними, все обновления для этого `<div>` и его дочерних элементов будут пропущены. Фактически, будет пропущено даже создание VNode виртуального DOM, поскольку мемоизированная копия поддерева может быть использована повторно.\n\n Важно правильно указать массив мемоизации, иначе мы можем пропустить обновления, которые действительно должны быть применены. `v-memo` с пустым массивом зависимостей (`v-memo=\"[]\"`) будет функционально эквивалентен `v-once`.\n\n **Использование вместе с `v-for`**\n\n `v-memo` предоставляется исключительно для микрооптимизации в критичных к производительности сценариях и может понадобиться крайне редко. Наиболее распространённым случаем, когда это может оказаться полезным, является отрисовка больших списков `v-for` (когда `length > 1000`):\n\n ```html\n <div v-for=\"item in list\" :key=\"item.id\" v-memo=\"[item.id === selected]\">\n <p>ID: {{ item.id }} - выбран: {{ item.id === selected }}</p>\n <p>...больше дочерних элементов</p>\n </div>\n ```\n\n При изменении состояния компонента `selected` будет создано большое количество VNodes, даже если большинство элементов остались прежними. Использование `v-memo` здесь, по сути, говорит: \"обновляйте этот элемент только в том случае, если он перешел из состояния `не выбран` в состояние `выбран`, или наоборот\". Это позволяет каждому незатронутому элементу повторно использовать свой предыдущий VNode и полностью пропустить операцию сравнения. Обратите внимание, что нам не нужно включать `item.id` в массив зависимостей memo, поскольку Vue автоматически определяет его из `:key` элемента.\n\n :::warning Предупреждение\n При использовании `v-memo` с `v-for` убедитесь, что они используются на одном и том же элементе. **`v-memo` не работает внутри `v-for`.**.\n :::\n\n `v-memo` также может быть использовано для компонентов, чтобы вручную предотвратить нежелательные обновления в некоторых крайних случаях, когда проверка обновлений дочерних компонентов была де-оптимизирована. Но, повторимся, ответственность за корректное указание массивов зависимостей во избежание пропуска необходимых обновлений лежит на разработчике.\n\n- **См. также**\n - [v-once](#v-once)\n"
1302
+ "value": "\n- Only supported in 3.2+\n\n- **Ожидает:** `any[]`\n\n- **Подробности**\n\n Мемоизация части поддерева шаблона. Может использоваться как для элементов, так и для компонентов. Директива ожидает массив фиксированной длины зависимых значений, которые станут использоваться для сравнения при мемоизации. Если каждое значение массива осталось таким же, как при последней отрисовке, то обновление всего поддерева будет пропущено. Например:\n\n ```html\n <div v-memo=\"[valueA, valueB]\">\n ...\n </div>\n ```\n\n При повторном рендеринге компонента, если `valueA` и `valueB` остались прежними, все обновления для этого `<div>` и его дочерних элементов будут пропущены. Фактически, будет пропущено даже создание VNode виртуального DOM, поскольку мемоизированная копия поддерева может быть использована повторно.\n\n Важно правильно указать массив мемоизации, иначе мы можем пропустить обновления, которые действительно должны быть применены. `v-memo` с пустым массивом зависимостей (`v-memo=\"[]\"`) будет функционально эквивалентен `v-once`.\n\n **Использование вместе с `v-for`**\n\n `v-memo` предоставляется исключительно для микрооптимизации в критичных к производительности сценариях и может понадобиться крайне редко. Наиболее распространённым случаем, когда это может оказаться полезным, является отрисовка больших списков `v-for` (когда `length > 1000`):\n\n ```html\n <div v-for=\"item in list\" :key=\"item.id\" v-memo=\"[item.id === selected]\">\n <p>ID: {{ item.id }} - выбран: {{ item.id === selected }}</p>\n <p>...больше дочерних элементов</p>\n </div>\n ```\n\n При изменении состояния компонента `selected` будет создано большое количество VNodes, даже если большинство элементов остались прежними. Использование `v-memo` здесь, по сути, говорит: \"обновляйте этот элемент только в том случае, если он перешел из состояния `не выбран` в состояние `выбран`, или наоборот\". Это позволяет каждому незатронутому элементу повторно использовать свой предыдущий VNode и полностью пропустить операцию сравнения. Обратите внимание, что нам не нужно включать `item.id` в массив зависимостей memo, поскольку Vue автоматически определяет его из `:key` элемента.\n\n :::warning Предупреждение\n При использовании `v-memo` с `v-for` убедитесь, что они используются на одном и том же элементе. **`v-memo` не работает внутри `v-for`.**.\n :::\n\n `v-memo` также может быть использовано для компонентов, чтобы вручную предотвратить нежелательные обновления в некоторых крайних случаях, когда проверка обновлений дочерних компонентов была де-оптимизирована. Но, повторимся, ответственность за корректное указание массивов зависимостей во избежание пропуска необходимых обновлений лежит на разработчике.\n\n- **См. также**\n - [v-once](#v-once)\n"
1303
1303
  },
1304
1304
  "references": [
1305
1305
  {
@@ -1544,7 +1544,7 @@
1544
1544
  "name": "is",
1545
1545
  "description": {
1546
1546
  "kind": "markdown",
1547
- "value": "\nИспользуется для [динамических компонентов](https://ru.vuejs.org/guide/essentials/component-basics.html#dynamic-components).\n\n- **Ожидает** `string | Component`\n\n- **Использование на нативных элементах** <sup class=\"vt-badge\">3.1+</sup>\n\n Когда атрибут `is` используется на нативном HTML-элементе, то он интерпретируется как [пользовательский встроенный элемент](https://html.spec.whatwg.org/multipage/custom-elements#custom-elements-customized-builtin-example). Это нативная возможность веб-платформы.\n\n Однако есть случай использования, когда может понадобиться, чтобы Vue заменил нативный элемент на компонент Vue, как это разъясняется в [Особенности парсинга DOM-шаблона](https://ru.vuejs.org/guide/essentials/component-basics.html#dom-template-parsing-caveats). В таком случае можно добавить значению атрибута `is` префикс `vue:`, чтобы Vue вместо элемента отрисовал компонент Vue:\n\n ```html\n <table>\n <tr is=\"vue:my-row-component\"></tr>\n </table>\n ```\n\n- **См. также**\n\n - [Специальные встроенные элементы - `<component>`](https://ru.vuejs.org/api/built-in-special-elements.html#component)\n - [Динамические компоненты](https://ru.vuejs.org/guide/essentials/component-basics.html#dynamic-components)\n"
1547
+ "value": "\nИспользуется для [динамических компонентов](https://ru.vuejs.org/guide/essentials/component-basics.html#dynamic-components).\n\n- **Ожидает** `string | Component`\n\n- **Использование на нативных элементах**\n \n - Поддерживается только в 3.1+\n\n Когда атрибут `is` используется на нативном HTML-элементе, то он интерпретируется как [пользовательский встроенный элемент](https://html.spec.whatwg.org/multipage/custom-elements#custom-elements-customized-builtin-example). Это нативная возможность веб-платформы.\n\n Однако есть случай использования, когда может понадобиться, чтобы Vue заменил нативный элемент на компонент Vue, как это разъясняется в [Особенности парсинга DOM-шаблона](https://ru.vuejs.org/guide/essentials/component-basics.html#dom-template-parsing-caveats). В таком случае можно добавить значению атрибута `is` префикс `vue:`, чтобы Vue вместо элемента отрисовал компонент Vue:\n\n ```html\n <table>\n <tr is=\"vue:my-row-component\"></tr>\n </table>\n ```\n\n- **См. также**\n\n - [Специальные встроенные элементы - `<component>`](https://ru.vuejs.org/api/built-in-special-elements.html#component)\n - [Динамические компоненты](https://ru.vuejs.org/guide/essentials/component-basics.html#dynamic-components)\n"
1548
1548
  },
1549
1549
  "references": [
1550
1550
  {
@@ -6,7 +6,7 @@ exports.getNameCasing = getNameCasing;
6
6
  exports.detect = detect;
7
7
  const vue = require("@vue/language-core");
8
8
  const language_core_1 = require("@vue/language-core");
9
- const computeds_1 = require("computeds");
9
+ const alien_signals_1 = require("alien-signals");
10
10
  const types_1 = require("../types");
11
11
  async function convertTagName(context, uri, casing, tsPluginClient) {
12
12
  const sourceFile = context.language.scripts.get(uri);
@@ -17,7 +17,7 @@ async function convertTagName(context, uri, casing, tsPluginClient) {
17
17
  if (!(rootCode instanceof language_core_1.VueVirtualCode)) {
18
18
  return;
19
19
  }
20
- const desc = rootCode.sfc;
20
+ const desc = rootCode._sfc;
21
21
  if (!desc.template) {
22
22
  return;
23
23
  }
@@ -53,7 +53,7 @@ async function convertAttrName(context, uri, casing, tsPluginClient) {
53
53
  if (!(rootCode instanceof language_core_1.VueVirtualCode)) {
54
54
  return;
55
55
  }
56
- const desc = rootCode.sfc;
56
+ const desc = rootCode._sfc;
57
57
  if (!desc.template) {
58
58
  return;
59
59
  }
@@ -65,7 +65,7 @@ async function convertAttrName(context, uri, casing, tsPluginClient) {
65
65
  for (const [tagName, { attrs }] of tags) {
66
66
  const componentName = components.find(component => component === tagName || (0, language_core_1.hyphenateTag)(component) === tagName);
67
67
  if (componentName) {
68
- const props = await tsPluginClient?.getComponentProps(rootCode.fileName, componentName) ?? [];
68
+ const props = (await tsPluginClient?.getComponentProps(rootCode.fileName, componentName) ?? []).map(prop => prop.name);
69
69
  for (const [attrName, { offsets }] of attrs) {
70
70
  const propName = props.find(prop => prop === attrName || (0, language_core_1.hyphenateAttr)(prop) === attrName);
71
71
  if (propName) {
@@ -134,8 +134,8 @@ async function detect(context, uri) {
134
134
  }
135
135
  function getTagNameCase(file) {
136
136
  const result = new Set();
137
- if (file.sfc.template?.ast) {
138
- for (const element of vue.forEachElementNode(file.sfc.template.ast)) {
137
+ if (file._sfc.template?.ast) {
138
+ for (const element of vue.forEachElementNode(file._sfc.template.ast)) {
139
139
  if (element.tagType === 1) {
140
140
  if (element.tag !== (0, language_core_1.hyphenateTag)(element.tag)) {
141
141
  // TagName
@@ -155,11 +155,11 @@ async function detect(context, uri) {
155
155
  const map = new WeakMap();
156
156
  function getTemplateTagsAndAttrs(sourceFile) {
157
157
  if (!map.has(sourceFile)) {
158
- const getter = (0, computeds_1.computed)(() => {
158
+ const getter = (0, alien_signals_1.computed)(() => {
159
159
  if (!(sourceFile instanceof vue.VueVirtualCode)) {
160
160
  return;
161
161
  }
162
- const ast = sourceFile.sfc.template?.ast;
162
+ const ast = sourceFile._sfc.template?.ast;
163
163
  const tags = new Map();
164
164
  if (ast) {
165
165
  for (const node of vue.forEachElementNode(ast)) {
@@ -199,6 +199,6 @@ function getTemplateTagsAndAttrs(sourceFile) {
199
199
  });
200
200
  map.set(sourceFile, getter);
201
201
  }
202
- return map.get(sourceFile)() ?? new Map();
202
+ return map.get(sourceFile).get() ?? new Map();
203
203
  }
204
204
  //# sourceMappingURL=nameCasing.js.map
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.create = create;
4
4
  const language_core_1 = require("@vue/language-core");
5
5
  const shared_1 = require("@vue/shared");
6
- const path = require("path-browserify");
6
+ const path_browserify_1 = require("path-browserify");
7
7
  const getUserPreferences_1 = require("volar-service-typescript/lib/configs/getUserPreferences");
8
8
  const vscode_uri_1 = require("vscode-uri");
9
9
  const vue_extract_file_1 = require("../plugins/vue-extract-file");
@@ -45,7 +45,7 @@ function create(ts, getTsPluginClient) {
45
45
  let baseName = importUri.substring(importUri.lastIndexOf('/') + 1);
46
46
  baseName = baseName.substring(0, baseName.lastIndexOf('.'));
47
47
  const newName = (0, shared_1.capitalize)((0, shared_1.camelize)(baseName));
48
- const { sfc } = vueVirtualCode;
48
+ const { _sfc: sfc } = vueVirtualCode;
49
49
  const script = sfc.scriptSetup ?? sfc.script;
50
50
  if (!script) {
51
51
  return;
@@ -67,7 +67,7 @@ function create(ts, getTsPluginClient) {
67
67
  }
68
68
  }
69
69
  if (!importPath) {
70
- importPath = path.relative(path.dirname(vueVirtualCode.fileName), incomingFileName)
70
+ importPath = path_browserify_1.posix.relative(path_browserify_1.posix.dirname(vueVirtualCode.fileName), incomingFileName)
71
71
  || importUri.substring(importUri.lastIndexOf('/') + 1);
72
72
  if (!importPath.startsWith('./') && !importPath.startsWith('../')) {
73
73
  importPath = './' + importPath;
@@ -17,12 +17,12 @@ function create() {
17
17
  const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
18
18
  if (sourceScript?.generated?.root instanceof language_core_1.VueVirtualCode && virtualCode?.id === 'template') {
19
19
  const result = [];
20
- const codegen = language_core_1.tsCodegen.get(sourceScript.generated.root.sfc);
21
- const scopedClasses = codegen?.generatedTemplate()?.scopedClasses ?? [];
20
+ const codegen = language_core_1.tsCodegen.get(sourceScript.generated.root._sfc);
21
+ const scopedClasses = codegen?.generatedTemplate.get()?.scopedClasses ?? [];
22
22
  const styleClasses = new Map();
23
23
  const option = sourceScript.generated.root.vueCompilerOptions.experimentalResolveStyleCssClasses;
24
- for (let i = 0; i < sourceScript.generated.root.sfc.styles.length; i++) {
25
- const style = sourceScript.generated.root.sfc.styles[i];
24
+ for (let i = 0; i < sourceScript.generated.root._sfc.styles.length; i++) {
25
+ const style = sourceScript.generated.root._sfc.styles[i];
26
26
  if (option === 'always' || (option === 'scoped' && style.scoped)) {
27
27
  for (const className of style.classNames) {
28
28
  if (!styleClasses.has(className.text.substring(1))) {
@@ -29,7 +29,7 @@ function create(ts, getTsPluginClient) {
29
29
  if (!(sourceScript?.generated?.root instanceof language_core_1.VueVirtualCode) || virtualCode?.id !== 'template') {
30
30
  return;
31
31
  }
32
- const { sfc } = sourceScript.generated.root;
32
+ const { _sfc: sfc } = sourceScript.generated.root;
33
33
  const script = sfc.scriptSetup ?? sfc.script;
34
34
  if (!sfc.template || !script) {
35
35
  return;
@@ -62,7 +62,7 @@ function create(ts, getTsPluginClient) {
62
62
  }
63
63
  const document = context.documents.get(parsedUri, virtualCode.languageId, virtualCode.snapshot);
64
64
  const sfcDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
65
- const { sfc } = sourceScript.generated.root;
65
+ const { _sfc: sfc } = sourceScript.generated.root;
66
66
  const script = sfc.scriptSetup ?? sfc.script;
67
67
  if (!sfc.template || !script) {
68
68
  return codeAction;
@@ -4,4 +4,4 @@ export declare function create(ts: typeof import('typescript')): LanguageService
4
4
  /**
5
5
  * Refactored from https://github.com/vuejs/core/blob/main/packages/compiler-sfc/src/script/definePropsDestructure.ts
6
6
  */
7
- export declare function findDestructuredProps(ts: typeof import('typescript'), ast: ts.SourceFile, props: string[]): [ts.Identifier, boolean][];
7
+ export declare function findDestructuredProps(ts: typeof import('typescript'), ast: ts.SourceFile, props: Set<string>): [ts.Identifier, boolean][];
@@ -20,30 +20,34 @@ function create(ts) {
20
20
  const sourceScript = decoded && context.language.scripts.get(decoded[0]);
21
21
  const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
22
22
  if (virtualCode instanceof language_core_1.VueVirtualCode) {
23
- const codegen = language_core_1.tsCodegen.get(virtualCode.sfc);
23
+ const codegen = language_core_1.tsCodegen.get(virtualCode._sfc);
24
24
  const inlayHints = [
25
- ...codegen?.generatedTemplate()?.inlayHints ?? [],
26
- ...codegen?.generatedScript()?.inlayHints ?? [],
25
+ ...codegen?.generatedTemplate.get()?.inlayHints ?? [],
26
+ ...codegen?.generatedScript.get()?.inlayHints ?? [],
27
27
  ];
28
- const scriptSetupRanges = codegen?.scriptSetupRanges();
29
- if (scriptSetupRanges?.props.destructured && virtualCode.sfc.scriptSetup?.ast) {
30
- for (const [prop, isShorthand] of findDestructuredProps(ts, virtualCode.sfc.scriptSetup.ast, scriptSetupRanges.props.destructured)) {
31
- const name = prop.text;
32
- const end = prop.getEnd();
33
- const pos = isShorthand ? end : end - name.length;
34
- const label = isShorthand ? `: props.${name}` : 'props.';
35
- inlayHints.push({
36
- blockName: 'scriptSetup',
37
- offset: pos,
38
- setting: 'vue.inlayHints.destructuredProps',
39
- label,
40
- });
28
+ const scriptSetupRanges = codegen?.scriptSetupRanges.get();
29
+ if (scriptSetupRanges?.props.destructured && virtualCode._sfc.scriptSetup?.ast) {
30
+ const setting = 'vue.inlayHints.destructuredProps';
31
+ settings[setting] ??= await context.env.getConfiguration?.(setting) ?? false;
32
+ if (settings[setting]) {
33
+ for (const [prop, isShorthand] of findDestructuredProps(ts, virtualCode._sfc.scriptSetup.ast, scriptSetupRanges.props.destructured)) {
34
+ const name = prop.text;
35
+ const end = prop.getEnd();
36
+ const pos = isShorthand ? end : end - name.length;
37
+ const label = isShorthand ? `: props.${name}` : 'props.';
38
+ inlayHints.push({
39
+ blockName: 'scriptSetup',
40
+ offset: pos,
41
+ setting,
42
+ label,
43
+ });
44
+ }
41
45
  }
42
46
  }
43
47
  const blocks = [
44
- virtualCode.sfc.template,
45
- virtualCode.sfc.script,
46
- virtualCode.sfc.scriptSetup,
48
+ virtualCode._sfc.template,
49
+ virtualCode._sfc.script,
50
+ virtualCode._sfc.scriptSetup,
47
51
  ];
48
52
  const start = document.offsetAt(range.start);
49
53
  const end = document.offsetAt(range.end);
@@ -79,7 +83,7 @@ function create(ts) {
79
83
  * Refactored from https://github.com/vuejs/core/blob/main/packages/compiler-sfc/src/script/definePropsDestructure.ts
80
84
  */
81
85
  function findDestructuredProps(ts, ast, props) {
82
- const rootScope = {};
86
+ const rootScope = Object.create(null);
83
87
  const scopeStack = [rootScope];
84
88
  let currentScope = rootScope;
85
89
  const excludedIds = new WeakSet();
@@ -135,7 +139,7 @@ function findDestructuredProps(ts, ast, props) {
135
139
  && initializer
136
140
  && ts.isCallExpression(initializer)
137
141
  && initializer.expression.getText(ast) === 'defineProps';
138
- for (const id of (0, common_1.collectIdentifiers)(ts, name)) {
142
+ for (const [id] of (0, common_1.collectIdentifiers)(ts, name)) {
139
143
  if (isDefineProps) {
140
144
  excludedIds.add(id);
141
145
  }
@@ -150,7 +154,7 @@ function findDestructuredProps(ts, ast, props) {
150
154
  registerLocalBinding(name);
151
155
  }
152
156
  for (const p of parameters) {
153
- for (const id of (0, common_1.collectIdentifiers)(ts, p)) {
157
+ for (const [id] of (0, common_1.collectIdentifiers)(ts, p)) {
154
158
  registerLocalBinding(id);
155
159
  }
156
160
  }
@@ -19,7 +19,7 @@ function create() {
19
19
  return await worker(document, context, async (vueCode) => {
20
20
  const formatSettings = await context.env.getConfiguration?.('html.format') ?? {};
21
21
  const blockTypes = ['template', 'script', 'style'];
22
- for (const customBlock of vueCode.sfc.customBlocks) {
22
+ for (const customBlock of vueCode._sfc.customBlocks) {
23
23
  blockTypes.push(customBlock.type);
24
24
  }
25
25
  return {
@@ -66,7 +66,7 @@ function create() {
66
66
  provideDocumentSymbols(document) {
67
67
  return worker(document, context, vueSourceFile => {
68
68
  const result = [];
69
- const descriptor = vueSourceFile.sfc;
69
+ const descriptor = vueSourceFile._sfc;
70
70
  if (descriptor.template) {
71
71
  result.push({
72
72
  name: 'template',
@@ -19,6 +19,7 @@ function create(mode, ts, getTsPluginClient) {
19
19
  let customData = [];
20
20
  let extraCustomData = [];
21
21
  let lastCompletionComponentNames = new Set();
22
+ const tsDocumentations = new Map();
22
23
  const onDidChangeCustomDataListeners = new Set();
23
24
  const onDidChangeCustomData = (listener) => {
24
25
  onDidChangeCustomDataListeners.add(listener);
@@ -182,7 +183,7 @@ function create(mode, ts, getTsPluginClient) {
182
183
  ? tagName
183
184
  : components.find(component => component === tagName || (0, language_core_1.hyphenateTag)(component) === tagName);
184
185
  if (checkTag) {
185
- componentProps[checkTag] ??= await tsPluginClient?.getComponentProps(code.fileName, checkTag, true) ?? [];
186
+ componentProps[checkTag] ??= (await tsPluginClient?.getComponentProps(code.fileName, checkTag, true) ?? []).map(prop => prop.name);
186
187
  current = {
187
188
  unburnedRequiredProps: [...componentProps[checkTag]],
188
189
  labelOffset: scanner.getTokenOffset() + scanner.getTokenLength(),
@@ -279,7 +280,7 @@ function create(mode, ts, getTsPluginClient) {
279
280
  return;
280
281
  }
281
282
  const templateErrors = [];
282
- const { template } = code.sfc;
283
+ const { template } = code._sfc;
283
284
  if (template) {
284
285
  for (const error of template.errors) {
285
286
  onCompilerError(error, 1);
@@ -326,10 +327,10 @@ function create(mode, ts, getTsPluginClient) {
326
327
  const sourceScript = decoded && context.language.scripts.get(decoded[0]);
327
328
  if (!sourceScript
328
329
  || !(sourceScript.generated?.root instanceof language_core_1.VueVirtualCode)
329
- || !sourceScript.generated.root.sfc.template) {
330
+ || !sourceScript.generated.root._sfc.template) {
330
331
  return [];
331
332
  }
332
- const { template } = sourceScript.generated.root.sfc;
333
+ const { template } = sourceScript.generated.root._sfc;
333
334
  const spans = common_1.getComponentSpans.call({
334
335
  files: context.language.scripts,
335
336
  languageService,
@@ -357,11 +358,11 @@ function create(mode, ts, getTsPluginClient) {
357
358
  const casing = await (0, nameCasing_1.getNameCasing)(context, sourceDocumentUri);
358
359
  if (builtInData.tags) {
359
360
  for (const tag of builtInData.tags) {
360
- if (isInternalItemId(tag.name)) {
361
+ if (isItemKey(tag.name)) {
361
362
  continue;
362
363
  }
363
364
  if (specialTags.has(tag.name)) {
364
- tag.name = createInternalItemId('specialTag', [tag.name]);
365
+ tag.name = parseItemKey('specialTag', tag.name, '');
365
366
  }
366
367
  else if (casing.tag === types_1.TagNameCasing.Kebab) {
367
368
  tag.name = (0, language_core_1.hyphenateTag)(tag.name);
@@ -376,6 +377,7 @@ function create(mode, ts, getTsPluginClient) {
376
377
  let version = 0;
377
378
  let components;
378
379
  let templateContextProps;
380
+ tsDocumentations.clear();
379
381
  updateExtraCustomData([
380
382
  html.newHTMLDataProvider('vue-template-built-in', builtInData),
381
383
  {
@@ -395,8 +397,8 @@ function create(mode, ts, getTsPluginClient) {
395
397
  })());
396
398
  return [];
397
399
  }
398
- const scriptSetupRanges = vueCode.sfc.scriptSetup
399
- ? (0, language_core_1.parseScriptSetupRanges)(ts, vueCode.sfc.scriptSetup.ast, vueCompilerOptions)
400
+ const scriptSetupRanges = vueCode._sfc.scriptSetup
401
+ ? (0, language_core_1.parseScriptSetupRanges)(ts, vueCode._sfc.scriptSetup.ast, vueCompilerOptions)
400
402
  : undefined;
401
403
  const names = new Set();
402
404
  const tags = [];
@@ -409,7 +411,7 @@ function create(mode, ts, getTsPluginClient) {
409
411
  }
410
412
  }
411
413
  for (const binding of scriptSetupRanges?.bindings ?? []) {
412
- const name = vueCode.sfc.scriptSetup.content.substring(binding.start, binding.end);
414
+ const name = vueCode._sfc.scriptSetup.content.substring(binding.start, binding.end);
413
415
  if (casing.tag === types_1.TagNameCasing.Kebab) {
414
416
  names.add((0, language_core_1.hyphenateTag)(name));
415
417
  }
@@ -430,20 +432,21 @@ function create(mode, ts, getTsPluginClient) {
430
432
  if (!tagInfo) {
431
433
  promises.push((async () => {
432
434
  const attrs = await tsPluginClient?.getElementAttrs(vueCode.fileName, tag) ?? [];
433
- const props = await tsPluginClient?.getComponentProps(vueCode.fileName, tag) ?? [];
435
+ const propsInfo = await tsPluginClient?.getComponentProps(vueCode.fileName, tag) ?? [];
434
436
  const events = await tsPluginClient?.getComponentEvents(vueCode.fileName, tag) ?? [];
435
437
  tagInfos.set(tag, {
436
438
  attrs,
437
- props: props.filter(prop => !prop.startsWith('ref_')),
439
+ propsInfo: propsInfo.filter(prop => !prop.name.startsWith('ref_')),
438
440
  events,
439
441
  });
440
442
  version++;
441
443
  })());
442
444
  return [];
443
445
  }
444
- const { attrs, props, events } = tagInfo;
446
+ const { attrs, propsInfo, events } = tagInfo;
447
+ const props = propsInfo.map(prop => prop.name);
445
448
  const attributes = [];
446
- const _tsCodegen = language_core_1.tsCodegen.get(vueCode.sfc);
449
+ const _tsCodegen = language_core_1.tsCodegen.get(vueCode._sfc);
447
450
  if (_tsCodegen) {
448
451
  if (!templateContextProps) {
449
452
  promises.push((async () => {
@@ -453,8 +456,8 @@ function create(mode, ts, getTsPluginClient) {
453
456
  return [];
454
457
  }
455
458
  let ctxVars = [
456
- ..._tsCodegen.scriptRanges()?.bindings.map(binding => vueCode.sfc.script.content.substring(binding.start, binding.end)) ?? [],
457
- ..._tsCodegen.scriptSetupRanges()?.bindings.map(binding => vueCode.sfc.scriptSetup.content.substring(binding.start, binding.end)) ?? [],
459
+ ..._tsCodegen.scriptRanges.get()?.bindings.map(binding => vueCode._sfc.script.content.substring(binding.start, binding.end)) ?? [],
460
+ ..._tsCodegen.scriptSetupRanges.get()?.bindings.map(binding => vueCode._sfc.scriptSetup.content.substring(binding.start, binding.end)) ?? [],
458
461
  ...templateContextProps,
459
462
  ];
460
463
  ctxVars = [...new Set(ctxVars)];
@@ -474,7 +477,7 @@ function create(mode, ts, getTsPluginClient) {
474
477
  const propNameBase = name.startsWith('on-')
475
478
  ? name.slice('on-'.length)
476
479
  : (name['on'.length].toLowerCase() + name.slice('onX'.length));
477
- const propKey = createInternalItemId('componentEvent', [isGlobal ? '*' : tag, propNameBase]);
480
+ const propKey = parseItemKey('componentEvent', isGlobal ? '*' : tag, propNameBase);
478
481
  attributes.push({
479
482
  name: 'v-on:' + propNameBase,
480
483
  description: propKey,
@@ -485,7 +488,14 @@ function create(mode, ts, getTsPluginClient) {
485
488
  }
486
489
  else {
487
490
  const propName = name;
488
- const propKey = createInternalItemId('componentProp', [isGlobal ? '*' : tag, propName]);
491
+ const propKey = parseItemKey('componentProp', isGlobal ? '*' : tag, propName);
492
+ const propDescription = propsInfo.find(prop => {
493
+ const name = casing.attr === types_1.AttrNameCasing.Camel ? prop.name : (0, language_core_1.hyphenateAttr)(prop.name);
494
+ return name === propName;
495
+ })?.commentMarkdown;
496
+ if (propDescription) {
497
+ tsDocumentations.set(propName, propDescription);
498
+ }
489
499
  attributes.push({
490
500
  name: propName,
491
501
  description: propKey,
@@ -500,7 +510,7 @@ function create(mode, ts, getTsPluginClient) {
500
510
  }
501
511
  for (const event of events) {
502
512
  const name = casing.attr === types_1.AttrNameCasing.Camel ? event : (0, language_core_1.hyphenateAttr)(event);
503
- const propKey = createInternalItemId('componentEvent', [tag, name]);
513
+ const propKey = parseItemKey('componentEvent', tag, name);
504
514
  attributes.push({
505
515
  name: 'v-on:' + name,
506
516
  description: propKey,
@@ -523,7 +533,7 @@ function create(mode, ts, getTsPluginClient) {
523
533
  }
524
534
  for (const [isGlobal, model] of models) {
525
535
  const name = casing.attr === types_1.AttrNameCasing.Camel ? model : (0, language_core_1.hyphenateAttr)(model);
526
- const propKey = createInternalItemId('componentProp', [isGlobal ? '*' : tag, name]);
536
+ const propKey = parseItemKey('componentProp', isGlobal ? '*' : tag, name);
527
537
  attributes.push({
528
538
  name: 'v-model:' + name,
529
539
  description: propKey,
@@ -606,15 +616,19 @@ function create(mode, ts, getTsPluginClient) {
606
616
  }
607
617
  }
608
618
  }
609
- const originals = new Map();
619
+ completionList.items = completionList.items.filter(item => !specialTags.has(parseLabel(item.label).name));
620
+ const htmlDocumentations = new Map();
610
621
  for (const item of completionList.items) {
611
- if (specialTags.has(item.label)) {
612
- completionList.items = completionList.items.filter(i => i !== item);
622
+ const documentation = typeof item.documentation === 'string' ? item.documentation : item.documentation?.value;
623
+ if (documentation && !isItemKey(documentation) && item.documentation) {
624
+ htmlDocumentations.set(item.label, documentation);
613
625
  }
614
- const nameId = readInternalItemId(item.label);
615
- if (nameId) {
616
- const name = nameId.args[0];
617
- item.label = name;
626
+ }
627
+ for (const item of completionList.items) {
628
+ const resolvedLabelKey = resolveItemKey(item.label);
629
+ if (resolvedLabelKey) {
630
+ const name = resolvedLabelKey.tag;
631
+ item.label = resolvedLabelKey.leadingSlash ? '/' + name : name;
618
632
  if (item.textEdit) {
619
633
  item.textEdit.newText = name;
620
634
  }
@@ -626,32 +640,56 @@ function create(mode, ts, getTsPluginClient) {
626
640
  item.sortText = name;
627
641
  }
628
642
  }
629
- const itemIdKey = typeof item.documentation === 'string' ? item.documentation : item.documentation?.value;
630
- let itemId = itemIdKey ? readInternalItemId(itemIdKey) : undefined;
631
- if (itemId) {
632
- let [isEvent, name] = tryGetEventName(itemId);
643
+ const itemKeyStr = typeof item.documentation === 'string' ? item.documentation : item.documentation?.value;
644
+ let resolvedKey = itemKeyStr ? resolveItemKey(itemKeyStr) : undefined;
645
+ if (resolvedKey) {
646
+ const documentations = [];
647
+ if (tsDocumentations.has(resolvedKey.prop)) {
648
+ documentations.push(tsDocumentations.get(resolvedKey.prop));
649
+ }
650
+ let { isEvent, propName } = getPropName(resolvedKey);
633
651
  if (isEvent) {
634
- name = 'on' + name;
652
+ // click -> onclick
653
+ propName = 'on' + propName;
654
+ }
655
+ if (htmlDocumentations.has(propName)) {
656
+ documentations.push(htmlDocumentations.get(propName));
657
+ }
658
+ if (documentations.length) {
659
+ item.documentation = {
660
+ kind: 'markdown',
661
+ value: documentations.join('\n\n'),
662
+ };
663
+ }
664
+ else {
665
+ item.documentation = undefined;
635
666
  }
636
- const original = originals.get(name);
637
- item.documentation = original?.documentation;
638
667
  }
639
668
  else {
640
- let name = item.label;
641
- const isVBind = name.startsWith('v-bind:') ? (name = name.slice('v-bind:'.length), true) : false;
642
- const isVBindAbbr = name.startsWith(':') && name !== ':' ? (name = name.slice(':'.length), true) : false;
669
+ let propName = item.label;
670
+ const isVBind = propName.startsWith('v-bind:') ? (propName = propName.slice('v-bind:'.length), true) : false;
671
+ const isVBindAbbr = propName.startsWith(':') && propName !== ':' ? (propName = propName.slice(':'.length), true) : false;
643
672
  /**
644
673
  * for `is`, `key` and `ref` starting with `v-bind:` or `:`
645
674
  * that without `internalItemId`.
646
675
  */
647
676
  if (isVBind || isVBindAbbr) {
648
- itemId = {
677
+ resolvedKey = {
649
678
  type: 'componentProp',
650
- args: ['^', name]
679
+ tag: '^',
680
+ prop: propName,
681
+ leadingSlash: false
651
682
  };
652
683
  }
653
- else if (!originals.has(item.label)) {
654
- originals.set(item.label, item);
684
+ if (tsDocumentations.has(propName)) {
685
+ const originalDocumentation = typeof item.documentation === 'string' ? item.documentation : item.documentation?.value;
686
+ item.documentation = {
687
+ kind: 'markdown',
688
+ value: [
689
+ tsDocumentations.get(propName),
690
+ originalDocumentation,
691
+ ].filter(str => !!str).join('\n\n'),
692
+ };
655
693
  }
656
694
  }
657
695
  const tokens = [];
@@ -659,23 +697,23 @@ function create(mode, ts, getTsPluginClient) {
659
697
  item.kind = 6;
660
698
  tokens.push('\u0000');
661
699
  }
662
- else if (itemId) {
663
- const isComponent = itemId.args[0] !== '*';
664
- const [isEvent, name] = tryGetEventName(itemId);
665
- if (itemId.type === 'componentProp') {
666
- if (isComponent || specialProps.has(name)) {
700
+ else if (resolvedKey) {
701
+ const isComponent = resolvedKey.tag !== '*';
702
+ const { isEvent, propName } = getPropName(resolvedKey);
703
+ if (resolvedKey.type === 'componentProp') {
704
+ if (isComponent || specialProps.has(propName)) {
667
705
  item.kind = 5;
668
706
  }
669
707
  }
670
708
  else if (isEvent) {
671
709
  item.kind = 23;
672
- if (name.startsWith('vnode-')) {
710
+ if (propName.startsWith('vnode-')) {
673
711
  tokens.push('\u0004');
674
712
  }
675
713
  }
676
714
  if (isComponent
677
715
  || (isComponent && isEvent)
678
- || specialProps.has(name)) {
716
+ || specialProps.has(propName)) {
679
717
  tokens.push('\u0000');
680
718
  if (item.label.startsWith(':')) {
681
719
  tokens.push('\u0001');
@@ -692,7 +730,7 @@ function create(mode, ts, getTsPluginClient) {
692
730
  else {
693
731
  tokens.push('\u0000');
694
732
  }
695
- if (specialProps.has(name)) {
733
+ if (specialProps.has(propName)) {
696
734
  tokens.push('\u0001');
697
735
  }
698
736
  else {
@@ -772,18 +810,29 @@ function create(mode, ts, getTsPluginClient) {
772
810
  }
773
811
  }
774
812
  ;
775
- function createInternalItemId(type, args) {
776
- return '__VLS_::' + type + '::' + args.join(',');
813
+ function parseLabel(label) {
814
+ const leadingSlash = label.startsWith('/');
815
+ const name = label.slice(leadingSlash ? 1 : 0);
816
+ return {
817
+ name,
818
+ leadingSlash
819
+ };
820
+ }
821
+ function parseItemKey(type, tag, prop) {
822
+ return '__VLS_data=' + type + ',' + tag + ',' + prop;
777
823
  }
778
- function isInternalItemId(key) {
779
- return key.startsWith('__VLS_::');
824
+ function isItemKey(key) {
825
+ return key.startsWith('__VLS_data=');
780
826
  }
781
- function readInternalItemId(key) {
782
- if (isInternalItemId(key)) {
783
- const strs = key.split('::');
827
+ function resolveItemKey(key) {
828
+ const { leadingSlash, name } = parseLabel(key);
829
+ if (isItemKey(name)) {
830
+ const strs = name.slice('__VLS_data='.length).split(',');
784
831
  return {
785
- type: strs[1],
786
- args: strs[2].split(','),
832
+ type: strs[0],
833
+ tag: strs[1],
834
+ prop: strs[2],
835
+ leadingSlash
787
836
  };
788
837
  }
789
838
  }
@@ -798,14 +847,14 @@ function getReplacement(list, doc) {
798
847
  }
799
848
  }
800
849
  }
801
- function tryGetEventName(itemId) {
802
- const name = (0, language_core_1.hyphenateAttr)(itemId.args[1]);
850
+ function getPropName(itemKey) {
851
+ const name = (0, language_core_1.hyphenateAttr)(itemKey.prop);
803
852
  if (name.startsWith('on-')) {
804
- return [true, name.slice('on-'.length)];
853
+ return { isEvent: true, propName: name.slice('on-'.length) };
805
854
  }
806
- else if (itemId.type === 'componentEvent') {
807
- return [true, name];
855
+ else if (itemKey.type === 'componentEvent') {
856
+ return { isEvent: true, propName: name };
808
857
  }
809
- return [false, name];
858
+ return { isEvent: false, propName: name };
810
859
  }
811
860
  //# sourceMappingURL=vue-template.js.map
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@vue/language-service",
3
- "version": "2.1.5",
3
+ "version": "2.1.8",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "data",
7
7
  "**/*.js",
8
8
  "**/*.d.ts"
9
9
  ],
10
+ "sideEffects": false,
10
11
  "repository": {
11
12
  "type": "git",
12
13
  "url": "https://github.com/vuejs/language-tools.git",
@@ -16,14 +17,14 @@
16
17
  "update-html-data": "node ./scripts/update-html-data.js"
17
18
  },
18
19
  "dependencies": {
19
- "@volar/language-core": "~2.4.1",
20
- "@volar/language-service": "~2.4.1",
21
- "@volar/typescript": "~2.4.1",
22
- "@vue/compiler-dom": "^3.4.0",
23
- "@vue/language-core": "2.1.5",
24
- "@vue/shared": "^3.4.0",
25
- "@vue/typescript-plugin": "2.1.5",
26
- "computeds": "^0.0.1",
20
+ "@volar/language-core": "~2.4.8",
21
+ "@volar/language-service": "~2.4.8",
22
+ "@volar/typescript": "~2.4.8",
23
+ "@vue/compiler-dom": "^3.5.0",
24
+ "@vue/language-core": "2.1.8",
25
+ "@vue/shared": "^3.5.0",
26
+ "@vue/typescript-plugin": "2.1.8",
27
+ "alien-signals": "^0.2.0",
27
28
  "path-browserify": "^1.0.1",
28
29
  "volar-service-css": "0.0.62",
29
30
  "volar-service-emmet": "0.0.62",
@@ -40,8 +41,8 @@
40
41
  "devDependencies": {
41
42
  "@types/node": "latest",
42
43
  "@types/path-browserify": "latest",
43
- "@volar/kit": "~2.4.1",
44
+ "@volar/kit": "~2.4.8",
44
45
  "vscode-languageserver-protocol": "^3.17.5"
45
46
  },
46
- "gitHead": "a95b51ac0b0db8825f77fbba37e29932b5be61e4"
47
+ "gitHead": "25cccedc53e7361ed4e34296d6ecd43d7de2a095"
47
48
  }