new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Vue · Guide · all subjects

template-syntax

153 notes in this subject, read out of this brain and free to use. This is page 2 of 3.

v-for with integer range

v-for can take an integer to repeat a template that many times based on a range. For example, v-for="n in 10" will iterate with n starting at 1 (not 0) through 10.

v-for on template tag

You can use a <template> tag with v-for to render a block of multiple elements without adding an extra wrapper element. This is similar to using <template> with v-if.

v-if and v-for precedence issue

When v-if and v-for exist on the same node, v-if has higher priority than v-for, meaning the v-if condition will not have access to variables from the v-for scope. This combination should be avoided due to implicit precedence. To fix this, move v-for to a wrapping <template> tag.

Filtering lists with v-for

To filter items in a list using v-for, replace the array with a new computed property that returns your filtered list, rather than using v-if on the same element. For example, instead of v-for="user in users" v-if="user.isActive", create a computed property activeUsers and use v-for="user in activeUsers".

Hiding entire v-for list

To avoid rendering a list if it should be hidden, move v-if to a container element (such as ul or ol) rather than using it on the same element as v-for. For example, instead of v-for="user in users" v-if="shouldShowUsers", place v-if on the wrapping ul element.

v-for key attribute purpose

The key attribute gives Vue a hint to track each node's identity, allowing it to reuse and reorder existing elements. Without a key, Vue uses an 'in-place patch' strategy where it patches each element in-place instead of moving DOM elements to match the order of data items.

v-for key placement with template

When using <template v-for>, the key attribute should be placed on the <template> container itself, not on the child elements inside it.

v-for key binding requirements

The key binding in v-for expects primitive values such as strings and numbers. Do not use objects as v-for keys. It is recommended to provide a key attribute with v-for whenever possible, unless the iterated DOM content is simple (contains no components or stateful DOM elements) or you are intentionally relying on the default behavior for performance gains.

When key attribute is essential

The key attribute is essential when your list render output relies on child component state or temporary DOM state such as form input values. Without keys, Vue's in-place patch strategy can lose this state when the order of data items changes.

v-for on components

You can use v-for directly on a component like any normal element, but you must provide a key attribute. However, this does not automatically pass any data to the component since components have isolated scopes. You must explicitly pass data using props, such as v-for="(item, index) in items" :item="item" :index="index" :key="item.id".

Why v-for data is not auto-injected to components

Data from v-for is not automatically injected into components because that would tightly couple the component to how v-for works. Being explicit about where data comes from makes the component reusable in other situations.

Array mutation methods detected by Vue

Vue detects when reactive array mutation methods are called and triggers necessary updates. The detected mutation methods are: push(), pop(), shift(), unshift(), splice(), sort(), and reverse().

Replacing arrays with non-mutating methods

Non-mutating array methods like filter(), concat(), and slice() return a new array without mutating the original. When working with these methods, replace the old array with the new one. For example, in the Composition API use items.value = items.value.filter(...), and in the Options API use this.items = this.items.filter(...).

Vue array replacement efficiency

Replacing an array with another array containing overlapping objects is a very efficient operation because Vue implements smart heuristics to maximize DOM element reuse. Vue does not throw away existing DOM and re-render the entire list when you replace the array.

Filtered or sorted results with computed property

To display a filtered or sorted version of an array without mutating the original data, create a computed property that returns the filtered or sorted array. For example, create a computed property evenNumbers that returns numbers.value.filter((n) => n % 2 === 0).

Filtered or sorted results with method

In situations where computed properties are not feasible, such as inside nested v-for loops, you can use a method to filter or sort results. For example, define a method even(numbers) that returns numbers.filter(...) and call it in the template like v-for="n in even(numbers)".

Avoid mutating methods in computed property

Be careful with reverse() and sort() in a computed property because these methods mutate the original array, which should be avoided in computed getters. Create a copy of the original array before calling these methods, such as return [...numbers].reverse() instead of return numbers.reverse().

ref attribute for DOM element access

The ref attribute is a special attribute that allows obtaining a direct reference to a specific DOM element or child component instance after it is mounted. Use ref="name" on the target element in the template.

useTemplateRef() Composition API helper

In Vue 3.5+, use the useTemplateRef() helper from the Composition API to obtain a reference to a template ref. The first argument must match the ref value in the template. The reference is stored in a .value property that can be accessed after the component is mounted.

Accessing refs before version 3.5 with Composition API

In versions before 3.5, declare a ref with ref(null) and ensure the variable name matches the template ref attribute's value. When using <script setup>, the ref will be automatically exposed; otherwise, return it from setup().

Accessing refs with Options API

In Options API, access refs through this.$refs after the component is mounted. The ref name in the template becomes a property on this.$refs.

Refs are unavailable until after mount

Template refs can only be accessed after the component is mounted. On the first render, accessing a ref will return undefined (Options API) or null (Composition API) because the element does not exist until after the first render completes.

Watching template refs with Composition API

When watching template ref changes with watchEffect, account for the possibility that the ref has a null value, which occurs when the component is not yet mounted or when the element was unmounted (e.g., by v-if).

Template refs inside v-for

When ref is used inside v-for (requires v3.5+), the corresponding ref should contain an array value that will be populated with the elements after mount. Note that the ref array does not guarantee the same order as the source array.

v-for refs before version 3.5

In versions before 3.5, when using ref inside v-for with Composition API, declare the ref with ref([]) to hold an array. In Options API, this.$refs.itemName will automatically be an array containing the corresponding elements.

Function refs for dynamic storage

Instead of a string key, the ref attribute can be bound to a function using :ref="(el) => { }" syntax. This function is called on each component update and receives the element reference as the first argument. When the element is unmounted, the argument will be null. This provides full flexibility for storing element references.

Vue templates compile to optimized JavaScript

Vue compiles templates into highly-optimized JavaScript code. Combined with the reactivity system, Vue intelligently determines the minimal number of components to re-render and applies minimal DOM manipulations when app state changes.

Text interpolation with mustache syntax

Text interpolation uses double curly braces (mustache syntax) to bind data to the DOM. The syntax is {{ propertyName }}. The mustache tag is replaced with the value of the property from the component instance and updates whenever that property changes.

v-html directive for rendering raw HTML

The v-html directive outputs real HTML content instead of treating it as plain text. Use it with <span v-html="rawHtml"></span> to render HTML from a component property. Data bindings inside the HTML are ignored, and the element's inner HTML is completely replaced with the property value interpreted as HTML.

v-html security warning

Dynamically rendering arbitrary HTML with v-html can lead to XSS vulnerabilities. Only use v-html on trusted content and never on user-provided content.

v-bind directive for attribute bindings

Mustaches cannot be used inside HTML attributes. Use the v-bind directive to bind attributes: <div v-bind:id="dynamicId"></div>. If the bound value is null or undefined, the attribute will be removed from the rendered element.

v-bind shorthand syntax

v-bind has a shorthand syntax using a colon (:) instead of writing the full directive. <div v-bind:id="dynamicId"></div> can be shortened to <div :id="dynamicId"></div>. Attributes starting with : are valid characters for attribute names and do not appear in final rendered markup.

Same-name shorthand for v-bind

In Vue 3.4+, if the attribute name matches the variable name being bound, the syntax can be further shortened to omit the attribute value. <div :id="id"></div> can be shortened to <div :id></div> or <div v-bind:id></div>. This works similarly to JavaScript object property shorthand.

Boolean attributes with v-bind

For boolean attributes like disabled, v-bind includes the attribute if the value is truthy or an empty string, and omits it for other falsy values. Example: <button :disabled="isButtonDisabled">Button</button> will include the disabled attribute when isButtonDisabled is truthy.

Dynamically binding multiple attributes

To bind multiple attributes from a JavaScript object to an element, use v-bind without an argument: <div v-bind="objectOfAttrs"></div>. The object should contain key-value pairs like { id: 'container', class: 'wrapper', style: 'background-color:green' }.

JavaScript expressions in Vue templates

Vue supports full JavaScript expressions inside data bindings. Expressions can be used in text interpolations (mustaches) and in the attribute value of any Vue directives. Examples: {{ number + 1 }}, {{ ok ? 'YES' : 'NO' }}, {{ message.split('').reverse().join('') }}, <div :id="`list-${id}`"></div>.

Bindings can only contain one single expression

Each binding in Vue templates can only contain one single expression. An expression is code that can be evaluated to a value. A simple check is whether it can be used after return. Statements like variable declarations (var a = 1) and flow control (if statements) will not work in bindings.

Calling functions in binding expressions

Component-exposed methods can be called inside binding expressions: <time :title="toTitleDate(date)">{{ formatDate(date) }}</time>. Functions called in binding expressions are called every time the component updates, so they should not have side effects like changing data or triggering asynchronous operations.

Template expressions have restricted global access

Template expressions are sandboxed and only have access to a restricted list of globals including commonly used built-ins like Math and Date. User-attached properties on window are not accessible. Additional globals can be defined by adding them to app.config.globalProperties.

Vue directives are special attributes with v- prefix

Directives are special attributes prefixed with v- that apply special reactive behavior to rendered DOM. Vue provides built-in directives including v-html, v-bind, v-if, v-on, v-for, and v-slot. Directive attribute values are expected to be single JavaScript expressions, except for v-for, v-on, and v-slot.

v-if directive for conditional rendering

The v-if directive removes or inserts an element based on the truthiness of an expression value. Example: <p v-if="seen">Now you see me</p> will only render the paragraph element when the seen property is truthy.

Directive arguments

Some directives can take an argument, denoted by a colon after the directive name. The v-bind directive uses arguments to specify which attribute to bind: <a v-bind:href="url"></a> where href is the argument. The shorthand syntax condenses this to <a :href="url"></a>. Similarly, v-on uses an argument for the event name: <a v-on:click="doSomething"></a> or <a @click="doSomething"></a>.

Dynamic directive arguments

JavaScript expressions can be used in directive arguments by wrapping them with square brackets. Example: <a v-bind:[attributeName]="url"></a> or <a :[attributeName]="url"></a>. The attributeName will be dynamically evaluated as a JavaScript expression, and its value becomes the final argument. Similarly for events: <a v-on:[eventName]="doSomething"></a> or <a @[eventName]="doSomething"></a>.

Dynamic argument value constraints

Dynamic arguments must evaluate to a string, with the exception of null. The special value null can be used to explicitly remove the binding. Any other non-string value will trigger a warning.

Dynamic argument syntax constraints

Dynamic argument expressions have syntax constraints because certain characters like spaces and quotes are invalid inside HTML attribute names. Expressions like :['foo' + bar] will trigger a compiler warning. For complex dynamic arguments, use a computed property instead. In in-DOM templates (templates directly in HTML files), avoid naming keys with uppercase characters as browsers coerce attribute names to lowercase. Single-File Component templates are not subject to this constraint.

Modifiers on directives

Modifiers are special postfixes denoted by a dot that indicate a directive should be bound in a special way. Example: <form @submit.prevent="onSubmit"></form> where .prevent tells v-on to call event.preventDefault() on the triggered event. Modifiers are used with v-on and v-model directives.

h() function creates vnodes

The h() function is Vue's hyperscript function for creating vnodes programmatically. It accepts a type as the first argument (tag name or component), optional props as the second argument, and optional children as the third argument. All arguments except type are optional. The function is called 'h' (short for hyperscript), though it could be named createVNode().

h() function basic syntax and flexibility

The h() function supports flexible argument patterns: h('div') with just a tag, h('div', { id: 'foo' }) with props, h('div', { class: 'bar', innerHTML: 'hello' }) with attributes and properties, h('div', 'hello') with just children, and h('div', [h('span', 'hello')]) with vnodes as children. Props modifiers use '.' prefix for .prop modifier and '^' prefix for .attr modifier. Class and style support the same object/array syntax as templates. Event listeners are passed as onXxx props.

vnode object structure

A vnode object created by h() has four main properties: type (the tag or component name), props (the props object), children (the children array), and key (null if not specified). The vnode has other internal properties but these should not be relied upon.

Composition API render function in setup()

When using render functions with Composition API, return a function from setup() instead of a template. The render function has access to props and reactive state declared in the same scope. The setup() hook is called once, but the returned render function is called multiple times. You can return a single vnode, a string, or an array of vnodes.

Options API render function

With Options API, declare a render() method that returns a vnode. The render() function has access to the component instance via 'this'. You can return a single vnode, a string, or an array of vnodes.

Vnodes must be unique in the component tree

All vnodes in a component tree must be unique. Do not render the same vnode instance multiple times (e.g., storing a vnode in a variable and using it in an array twice). To render identical elements multiple times, use a factory function that creates new vnodes each time, such as Array.from({ length: 20 }).map(() => h('p', 'hi')).

Using vnodes in templates

A vnode object created in setup() can be used in templates by wrapping it in <component :is="vnode"> or using it directly as <vnode />. However, this does not create a new component instance and renders the vnode as-is. This pattern should be used with care and is not a replacement for normal components.

JSX syntax in Vue

JSX is an XML-like extension to JavaScript that allows writing code like const vnode = <div>hello</div>. Dynamic values are embedded in curly braces: <div id={dynamicId}>hello, {userName}</div>. create-vue and Vue CLI support JSX scaffolding. Manual configuration requires @vue/babel-plugin-jsx.

Vue JSX differences from React JSX

Vue's JSX transform is different from React's. HTML attributes like 'class' and 'for' are used as-is in Vue JSX (no need for 'className' or 'htmlFor'). Passing children to components (slots) works differently in Vue.

JSX type inference with TypeScript

Starting in Vue 3.4, Vue no longer implicitly registers the global JSX namespace. To use Vue's JSX type definitions, include in tsconfig.json: { "compilerOptions": { "jsx": "preserve", "jsxImportSource": "vue" } }. Alternatively, add /* @jsxImportSource vue */ comment at the top of a file. To retain pre-3.4 behavior, explicitly import or reference 'vue/jsx'.

v-if equivalent in render functions

The v-if directive is implemented using ternary operators in render functions. Template: <div v-if="ok">yes</div><span v-else>no</span> becomes: h('div', [ok.value ? h('div', 'yes') : h('span', 'no')]) in Composition API or h('div', [this.ok ? h('div', 'yes') : h('span', 'no')]) in Options API. In JSX: {ok.value ? <div>yes</div> : <span>no</span>}.

v-for equivalent in render functions

The v-for directive is implemented using .map() in render functions. Template: <ul><li v-for="{ id, text } in items" :key="id">{{ text }}</li></ul> becomes: h('ul', items.value.map(({ id, text }) => h('li', { key: id }, text))) in Composition API or h('ul', this.items.map(({ id, text }) => h('li', { key: id }, text))) in Options API. In JSX: <ul>{items.value.map(({ id, text }) => <li key={id}>{text}</li>)}</ul>.

v-on and event listeners in render functions

Props with names starting with 'on' followed by an uppercase letter are treated as event listeners. For example, onClick is equivalent to @click in templates. Usage: h('button', { onClick(event) { /* ... */ } }, 'Click Me') or in JSX: <button onClick={(event) => { /* ... */ }}>Click Me</button>.

Event modifiers in render functions

The .passive, .capture, and .once event modifiers are concatenated after the event name using camelCase in render functions. Examples: onClickCapture (capture mode), onKeyupOnce (triggers only once), onMouseoverOnceCapture (once + capture). For other event and key modifiers, use the withModifiers helper: h('div', { onClick: withModifiers(() => {}, ['self']) }).

Give your agent this brain