Vue Built-in Attributes

Special attributes for enhanced functionality

🏷️ Built-in Attributes

Vue provides special built-in attributes like key, ref, and is for enhanced component functionality. These attributes help with list rendering optimization, DOM access, dynamic components, and performance improvements in your applications.


<!-- Using built-in attributes -->
<template>
  <div v-for="item in items" :key="item.id">
    {{ item.name }}
  </div>
</template>
                                    

Core Built-in Attributes

🔑

key

Unique identifier for list items

<div 
  v-for="item in items" 
  :key="item.id"
>
📌

ref

Direct DOM element access

<input ref="inputRef" />

// Access: inputRef.value
🔄

is

Dynamic component rendering

<component 
  :is="currentComponent" 
/>

v-once

Render element only once

<div v-once>
  {{ staticContent }}
</div>

🔹 The key Attribute

Use key for efficient list rendering:

<script setup>
const users = ref([
  { id: 1, name: 'John', age: 25 },
  { id: 2, name: 'Jane', age: 30 },
  { id: 3, name: 'Bob', age: 35 }
])

function removeUser(id) {
  users.value = users.value.filter(u => u.id !== id)
}
</script>

<template>
  <div>
    <!-- ✅ GOOD: Using unique key -->
    <div 
      v-for="user in users" 
      :key="user.id"
      class="user-card"
    >
      <h3>{{ user.name }}</h3>
      <p>Age: {{ user.age }}</p>
      <button @click="removeUser(user.id)">Remove</button>
    </div>
    
    <!-- ❌ BAD: Using index as key -->
    <div 
      v-for="(user, index) in users" 
      :key="index"
    >
      {{ user.name }}
    </div>
  </div>
</template>

Why use key?

  • Helps Vue track element identity
  • Improves rendering performance
  • Prevents state bugs in lists
  • Always use unique, stable values

🔹 The ref Attribute

Access DOM elements and components directly:

<script setup>
import { ref, onMounted } from 'vue'

// Template refs
const inputRef = ref(null)
const componentRef = ref(null)

onMounted(() => {
  // Focus input on mount
  inputRef.value.focus()
  
  // Access component methods
  componentRef.value.someMethod()
})

function handleClick() {
  // Get input value
  console.log(inputRef.value.value)
  
  // Manipulate DOM
  inputRef.value.style.border = '2px solid blue'
}
</script>

<template>
  <div>
    <!-- Element ref -->
    <input 
      ref="inputRef" 
      type="text" 
      placeholder="Type here..."
    />
    
    <button @click="handleClick">Get Value</button>
    
    <!-- Component ref -->
    <ChildComponent ref="componentRef" />
  </div>
</template>

🔹 The is Attribute

Dynamically switch between components:

<script setup>
import { ref } from 'vue'
import HomeView from './HomeView.vue'
import AboutView from './AboutView.vue'
import ContactView from './ContactView.vue'

const currentView = ref('HomeView')

const components = {
  HomeView,
  AboutView,
  ContactView
}
</script>

<template>
  <div>
    <!-- Navigation -->
    <button @click="currentView = 'HomeView'">Home</button>
    <button @click="currentView = 'AboutView'">About</button>
    <button @click="currentView = 'ContactView'">Contact</button>
    
    <!-- Dynamic component -->
    <component :is="components[currentView]" />
    
    <!-- With KeepAlive to preserve state -->
    <KeepAlive>
      <component :is="components[currentView]" />
    </KeepAlive>
  </div>
</template>

🔹 v-once Directive

Render content only once for performance:

<script setup>
const staticTitle = ref('Welcome to Vue')
const dynamicCount = ref(0)
</script>

<template>
  <div>
    <!-- Rendered once, never updates -->
    <h1 v-once>{{ staticTitle }}</h1>
    
    <!-- Updates on every change -->
    <p>Count: {{ dynamicCount }}</p>
    
    <button @click="dynamicCount++">Increment</button>
    
    <!-- Static content with v-once -->
    <div v-once>
      <p>This content is rendered once</p>
      <p>Even if data changes, this won't update</p>
    </div>
  </div>
</template>

Use v-once for: Static content, terms and conditions, copyright notices, or any content that never changes

🔹 v-memo Directive

Memoize template sub-trees for performance:

<script setup>
const items = ref([
  { id: 1, name: 'Item 1', selected: false },
  { id: 2, name: 'Item 2', selected: false },
  { id: 3, name: 'Item 3', selected: false }
])

const globalCount = ref(0)
</script>

<template>
  <div>
    <p>Global Count: {{ globalCount }}</p>
    <button @click="globalCount++">Increment</button>
    
    <!-- Only re-renders when item.selected changes -->
    <div 
      v-for="item in items" 
      :key="item.id"
      v-memo="[item.selected]"
    >
      <h3>{{ item.name }}</h3>
      <p>Selected: {{ item.selected }}</p>
      <button @click="item.selected = !item.selected">
        Toggle
      </button>
    </div>
  </div>
</template>

🔹 v-cloak Directive

Hide uncompiled templates until ready:

<template>
  <!-- Prevents flash of uncompiled content -->
  <div v-cloak>
    <h1>{{ title }}</h1>
    <p>{{ description }}</p>
  </div>
</template>

<style>
/* Hide element until Vue is ready */
[v-cloak] {
  display: none;
}
</style>

🔹 v-pre Directive

Skip compilation for raw content:

<template>
  <div>
    <!-- Vue will compile this -->
    <p>{{ message }}</p>
    
    <!-- Vue will skip this, show raw mustaches -->
    <p v-pre>{{ This will not be compiled }}</p>
    
    <!-- Useful for displaying Vue syntax -->
    <pre v-pre>
      <code>
        <template>
          {{ message }}
        </template>
      </code>
    </pre>
  </div>
</template>

🧠 Test Your Knowledge

What is the primary purpose of the key attribute in v-for?