@vue/language-service 2.1.4 → 2.1.6

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
  {
@@ -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
  {
@@ -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) {
@@ -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");
@@ -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;
@@ -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(),
@@ -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
  {
@@ -430,18 +432,19 @@ 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
449
  const _tsCodegen = language_core_1.tsCodegen.get(vueCode.sfc);
447
450
  if (_tsCodegen) {
@@ -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,14 +616,18 @@ 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(item.label));
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];
626
+ }
627
+ for (const item of completionList.items) {
628
+ const resolvedLabelKey = resolveItemKey(item.label);
629
+ if (resolvedLabelKey) {
630
+ const name = resolvedLabelKey.tag;
617
631
  item.label = name;
618
632
  if (item.textEdit) {
619
633
  item.textEdit.newText = name;
@@ -626,32 +640,55 @@ 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,
651
681
  };
652
682
  }
653
- else if (!originals.has(item.label)) {
654
- originals.set(item.label, item);
683
+ if (tsDocumentations.has(propName)) {
684
+ const originalDocumentation = typeof item.documentation === 'string' ? item.documentation : item.documentation?.value;
685
+ item.documentation = {
686
+ kind: 'markdown',
687
+ value: [
688
+ tsDocumentations.get(propName),
689
+ originalDocumentation,
690
+ ].filter(str => !!str).join('\n\n'),
691
+ };
655
692
  }
656
693
  }
657
694
  const tokens = [];
@@ -659,23 +696,23 @@ function create(mode, ts, getTsPluginClient) {
659
696
  item.kind = 6;
660
697
  tokens.push('\u0000');
661
698
  }
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)) {
699
+ else if (resolvedKey) {
700
+ const isComponent = resolvedKey.tag !== '*';
701
+ const { isEvent, propName } = getPropName(resolvedKey);
702
+ if (resolvedKey.type === 'componentProp') {
703
+ if (isComponent || specialProps.has(propName)) {
667
704
  item.kind = 5;
668
705
  }
669
706
  }
670
707
  else if (isEvent) {
671
708
  item.kind = 23;
672
- if (name.startsWith('vnode-')) {
709
+ if (propName.startsWith('vnode-')) {
673
710
  tokens.push('\u0004');
674
711
  }
675
712
  }
676
713
  if (isComponent
677
714
  || (isComponent && isEvent)
678
- || specialProps.has(name)) {
715
+ || specialProps.has(propName)) {
679
716
  tokens.push('\u0000');
680
717
  if (item.label.startsWith(':')) {
681
718
  tokens.push('\u0001');
@@ -692,7 +729,7 @@ function create(mode, ts, getTsPluginClient) {
692
729
  else {
693
730
  tokens.push('\u0000');
694
731
  }
695
- if (specialProps.has(name)) {
732
+ if (specialProps.has(propName)) {
696
733
  tokens.push('\u0001');
697
734
  }
698
735
  else {
@@ -772,18 +809,19 @@ function create(mode, ts, getTsPluginClient) {
772
809
  }
773
810
  }
774
811
  ;
775
- function createInternalItemId(type, args) {
776
- return '__VLS_::' + type + '::' + args.join(',');
812
+ function parseItemKey(type, tag, prop) {
813
+ return '__VLS_data=' + type + ',' + tag + ',' + prop;
777
814
  }
778
- function isInternalItemId(key) {
779
- return key.startsWith('__VLS_::');
815
+ function isItemKey(key) {
816
+ return key.startsWith('__VLS_data=');
780
817
  }
781
- function readInternalItemId(key) {
782
- if (isInternalItemId(key)) {
783
- const strs = key.split('::');
818
+ function resolveItemKey(key) {
819
+ if (isItemKey(key)) {
820
+ const strs = key.slice('__VLS_data='.length).split(',');
784
821
  return {
785
- type: strs[1],
786
- args: strs[2].split(','),
822
+ type: strs[0],
823
+ tag: strs[1],
824
+ prop: strs[2],
787
825
  };
788
826
  }
789
827
  }
@@ -798,14 +836,14 @@ function getReplacement(list, doc) {
798
836
  }
799
837
  }
800
838
  }
801
- function tryGetEventName(itemId) {
802
- const name = (0, language_core_1.hyphenateAttr)(itemId.args[1]);
839
+ function getPropName(itemKey) {
840
+ const name = (0, language_core_1.hyphenateAttr)(itemKey.prop);
803
841
  if (name.startsWith('on-')) {
804
- return [true, name.slice('on-'.length)];
842
+ return { isEvent: true, propName: name.slice('on-'.length) };
805
843
  }
806
- else if (itemId.type === 'componentEvent') {
807
- return [true, name];
844
+ else if (itemKey.type === 'componentEvent') {
845
+ return { isEvent: true, propName: name };
808
846
  }
809
- return [false, name];
847
+ return { isEvent: false, propName: name };
810
848
  }
811
849
  //# sourceMappingURL=vue-template.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/language-service",
3
- "version": "2.1.4",
3
+ "version": "2.1.6",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "data",
@@ -20,9 +20,9 @@
20
20
  "@volar/language-service": "~2.4.1",
21
21
  "@volar/typescript": "~2.4.1",
22
22
  "@vue/compiler-dom": "^3.4.0",
23
- "@vue/language-core": "2.1.4",
23
+ "@vue/language-core": "2.1.6",
24
24
  "@vue/shared": "^3.4.0",
25
- "@vue/typescript-plugin": "2.1.4",
25
+ "@vue/typescript-plugin": "2.1.6",
26
26
  "computeds": "^0.0.1",
27
27
  "path-browserify": "^1.0.1",
28
28
  "volar-service-css": "0.0.62",
@@ -43,5 +43,5 @@
43
43
  "@volar/kit": "~2.4.1",
44
44
  "vscode-languageserver-protocol": "^3.17.5"
45
45
  },
46
- "gitHead": "5e197d08eaef57209ff2927c943ba1db3bf4eff6"
46
+ "gitHead": "fd61953ce9eb924eeaf4df0bf8d2237267321194"
47
47
  }