Template Syntax
About 1268 wordsAbout 4 min
Vue3Template
2025-01-18
Basic Syntax of v-bind
<img v-bind:src="imageSrc" />
<div v-bind="objectProps"></div>
objectProps is an object whose key-value pairs will be dynamically bound to the attributes of the div.
New Dynamic Argument for v-bind [key]
<template>
<div>
<button v-bind="[buttonProps]">Click me</button>
</div>
</template>
<script>
export default {
data() {
return {
buttonProps: {
[this.dynamicKey]: 'Click me!',
},
dynamicKey: 'title',
};
}
};
</script>
In this example, v-bind="[buttonProps]" will dynamically bind all key-value pairs in the buttonProps object to the button, and the key (title) is dynamic.
Support for Multiple v-model Bindings
Single Binding Example
<template>
<input v-model="inputValue" />
</template>
<script>
export default {
data() {
return {
inputValue: ''
};
}
};
</script>
In this example, the value of the input will be two-way bound with inputValue.
Multiple Bindings Example
<template>
<custom-input
v-model:title="title"
v-model:content="content"
/>
</template>
<script>
import { ref } from 'vue';
import CustomInput from './CustomInput.vue';
export default {
components: {
CustomInput
},
setup() {
const title = ref('Hello');
const content = ref('This is some content.');
return { title, content };
}
};
</script>
Implementation in Custom Components
In custom components, v-model will perform two-way binding based on the bound prop and event. By using v-model:propName for each prop, you can explicitly handle these different values within the component.
<template>
<input
:value="title"
@input="$emit('update:title', $event)"
/>
<textarea
:value="content"
@input="$emit('update:content', $event)"
/>
</template>
<script>
export default {
props: {
title: String,
content: String
}
};
</script>
Important
Starting from Vue 3.4, using defineModel()
is more convenient. The compiler will expand it into a property (and create a ref to sync with it) and an event to update this property. When the ref value changes, the update event is automatically triggered.
Summary
- Multiple v-model: Vue 3 allows a single component to have multiple v-model bindings. By using custom modelValue and event names, you can handle multiple two-way bound data in one component.
- Syntax: In the parent component, use v-model:propName to bind each property.
- Custom Events: In the child component, use update:propName to trigger update events for two-way binding.
Performance Differences between v-if and v-show in Conditional Rendering
Basic Differences between v-if and v-show
v-if: v-if is lazy-loaded, meaning that when the condition is false, Vue will not render the element at all. Only when the condition is true will Vue create and insert the element, and each time the condition changes, it will destroy and recreate the element.
v-show: v-show is always rendered, it renders the element and keeps it in the DOM, the only difference is that it controls the visibility of the element by modifying the display CSS property. When the condition is false, it applies display: none to the element, but the element still exists in the DOM.
Performance Differences
Performance Overhead of v-if:
v-if only creates DOM elements when the condition is true. When the condition switches to false, Vue destroys the element and all its child elements, and then recreates them when the condition becomes true again. This brings higher overhead, especially when the condition switches frequently, as each switch leads to the destruction and recreation of DOM elements.
Performance Overhead of v-show:
v-show always renders the element and only controls the visibility of the element by modifying display, so it has higher overhead during the initial rendering. Especially when there are many elements on the page that need to control visibility, this overhead may affect performance. However, switching the visibility state afterwards will have better performance with v-show, as it does not need to destroy and recreate DOM elements.
Custom Modifiers
Vue 3 allows you to add custom modifiers to event listeners or directives.
<template>
<input v-on:keyup.enter="handleEnter" placeholder="Press Enter">
</template>
<script>
export default {
methods: {
handleEnter() {
console.log('Enter key was pressed');
}
}
};
</script>
In this example, .enter is a built-in event modifier in Vue 3, which means that the handleEnter method is only triggered when the keyup event's key is 'Enter'.
Suppose you want to listen to a custom event, such as triggering an event only when a specific key is pressed on a certain input element, you can define a custom event modifier to achieve this.
<template>
<input v-on:keyup.shift="handleShiftKey" placeholder="Press Shift key">
</template>
<script>
export default {
methods: {
handleShiftKey() {
console.log('Shift key was pressed');
}
}
};
</script>
In this example, we use .shift as a custom modifier. This modifier listens to the keyup event and only triggers the event when the Shift key is pressed.
In addition to event modifiers, Vue also allows adding modifiers to custom directives.
For example:
// main.js or app.js
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
app.directive('focus', {
beforeMount(el, binding) {
if (binding.modifiers.autofocus) {
el.focus();
}
}
});
app.mount('#app');
<template>
<!-- The element will auto-focus on load only if the autofocus modifier is present -->
<input v-focus.autofocus placeholder="This will auto-focus on load">
</template>
- v-focus is the name of the custom directive.
- autofocus is a custom modifier, indicating that the element will auto-focus on mount only if this modifier is present.
- In the beforeMount hook, we check if the autofocus modifier is present, and if so, execute el.focus() to focus the element.
Slots
Classification
Used to pass dynamic content from parent components to child components, including:
Basic Slots
, where the parent component inserts content into the specified position of the child component
// Child component
<template>
<div>
<h2>Header</h2>
<!-- Slot -->
<slot></slot>
<h2>Footer</h2>
</div>
</template>
<script>
export default {
name: 'MyComponent',
};
</script>
// Parent component
<template>
<MyComponent>
<p>This is some content from the parent.</p>
</MyComponent>
</template>
<script>
import MyComponent from './MyComponent.vue';
export default {
components: { MyComponent },
};
</script>
Named Slots
// Child component
<template>
<div>
<header>
<slot name="header">Default Header</slot>
</header>
<main>
<slot>Default Content</slot>
</main>
<footer>
<slot name="footer">Default Footer</slot>
</footer>
</div>
</template>
// Parent component
<template>
<MyComponent>
<template #header>
<h1>Custom Header</h1>
</template>
<template #default>
<p>Main content from parent.</p>
</template>
<template #footer>
<p>Custom Footer</p>
</template>
</MyComponent>
</template>
Scoped Slots
, scoped slots allow child components to provide data to parent components, enabling dynamic rendering of content by the parent component.
// Child component
<template>
<ul>
<li v-for="(item, index) in items" :key="index">
<slot :item="item" :index="index">
<!-- Default content -->
{{ item }}
</slot>
</li>
</ul>
</template>
// Parent component
<template>
<MyComponent :items="['Apple', 'Banana', 'Cherry']">
<template #default="{ item, index }">
<strong>{{ index + 1 }}. {{ item }}</strong>
</template>
</MyComponent>
</template>
Dynamic Slot Names
Dynamic slot names allow the slot name to be determined at runtime.
// Child component
<template>
<div>
<slot :name="currentSlot"></slot>
</div>
</template>
<script>
export default {
name: 'MyComponent',
props: {
currentSlot: {
type: String,
required: true,
},
},
};
</script>
// Parent component
<template>
<div>
<MyComponent :currentSlot="activeSlot">
<template #slot1>
<p>Content for Slot 1</p>
</template>
<template #slot2>
<p>Content for Slot 2</p>
</template>
</MyComponent>
<button @click="activeSlot = 'slot1'">Show Slot 1</button>
<button @click="activeSlot = 'slot2'">Show Slot 2</button>
</div>
</template>
<script>
import MyComponent from './MyComponent.vue';
export default {
components: { MyComponent },
data() {
return {
activeSlot: 'slot1',
};
},
};
</script>
Other Template Languages
By using the lang
attribute of the template, you can switch the template syntax to other template languages, such as pug, markdown, ejs.
As long as the corresponding template compiler or loader is installed and configured, you can use it in Vue components.