Bài 7: Kỹ thuật nâng cao trong Vue.js 3

Bài 7: Kỹ thuật nâng cao trong Vue.js 3

Sau khi nắm chắc cơ bản (component, props, Pinia, API, routing), bạn nên học những kỹ thuật nâng cao để xử lý ứng dụng phức tạp, tối ưu hiệu năng, và trải nghiệm người dùng mượt mà.

Trong bài này, ta sẽ tìm hiểu:

  1. Dynamic component & Async component

  2. Teleport

  3. Suspense

  4. Transition & Animation

  5. Directive tự định nghĩa

  6. Plugin trong Vue

  7. SSR (Server Side Rendering) với Nuxt.js 3

  8. Code splitting & Performance optimization

1. Dynamic Component & Async Component

Dynamic component

Dùng <component :is="..."> để render component tùy theo state:

<template>
  <div>
    <button @click="view = 'A'">Component A</button>
    <button @click="view = 'B'">Component B</button>

    <component :is="viewComponent" />
  </div>
</template>

<script setup>
import CompA from './CompA.vue'
import CompB from './CompB.vue'
import { ref, computed } from 'vue'

const view = ref('A')
const viewComponent = computed(() => (view.value === 'A' ? CompA : CompB))
</script>

Async component

Dùng khi component nặng, chỉ load khi cần (code-splitting):

import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() => import('./BigComponent.vue'))

2. Teleport

Giúp render một phần giao diện ra ngoài root (ví dụ modal):

<template>
  <div>
    <button @click="show = true">Open Modal</button>

    <teleport to="body">
      <div v-if="show" class="modal">
        <p>Đây là modal</p>
        <button @click="show = false">Đóng</button>
      </div>
    </teleport>
  </div>
</template>

<script setup>
import { ref } from 'vue'
const show = ref(false)
</script>

<style>
.modal {
  position: fixed;
  top: 40%;
  left: 40%;
  background: white;
  padding: 20px;
  border: 1px solid #aaa;
}
</style>

3. Suspense

Dùng để chờ async component hoặc async setup:

<template>
  <Suspense>
    <template #default>
      <AsyncData />
    </template>
    <template #fallback>
      <p>⏳ Đang tải...</p>
    </template>
  </Suspense>
</template>

<script setup>
import { defineAsyncComponent } from 'vue'

const AsyncData = defineAsyncComponent(() => import('./AsyncData.vue'))
</script>

4. Transition & Animation

Vue hỗ trợ animation khi thêm/xóa component:

<template>
  <div>
    <button @click="show = !show">Toggle</button>
    <transition name="fade">
      <p v-if="show">Hello Vue Transition 🚀</p>
    </transition>
  </div>
</template>

<script setup>
import { ref } from 'vue'
const show = ref(true)
</script>

<style>
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter-from, .fade-leave-to {
  opacity: 0;
}
</style>

5. Directive tự định nghĩa

Bạn có thể tạo directive riêng, ví dụ v-focus để auto focus input:

// directives/focus.js
export const vFocus = {
  mounted(el) {
    el.focus()
  },
}

Dùng trong component:

<template>
  <input v-focus placeholder="Auto focus here" />
</template>

<script setup>
import { vFocus } from './directives/focus'
</script>

6. Plugin trong Vue

Plugin cho phép bạn mở rộng Vue. Ví dụ plugin logger:

// plugins/logger.js
export default {
  install(app) {
    app.config.globalProperties.$log = (msg) => {
      console.log('Log:', msg)
    }
  },
}

Dùng trong main.js:

import { createApp } from 'vue'
import App from './App.vue'
import Logger from './plugins/logger'

const app = createApp(App)
app.use(Logger)
app.mount('#app')

Trong component:

<script setup>
import { getCurrentInstance } from 'vue'

const { proxy } = getCurrentInstance()
proxy.$log('Hello Plugin!')
</script>

7. SSR (Server Side Rendering) với Nuxt.js 3

Khi cần SEO tốt hơn hoặc performance ban đầu nhanh hơn → dùng Nuxt.js 3.
Ví dụ tạo project Nuxt:

npx nuxi init my-nuxt-app
cd my-nuxt-app
npm install
npm run dev

Nuxt hỗ trợ sẵn: routing, store, SSR, static generation.

8. Code Splitting & Performance Optimization

  • Dùng async component để lazy-load.

  • Chia nhỏ bundle với Vite/Rollup.

  • Dùng <Suspense> cho dữ liệu async.

  • Prefetch và preload cho route quan trọng.

  • Tối ưu hình ảnh, dùng CDN.

  • Kết hợp Pinia + service layer để tránh gọi API lặp lại.


🎯 Tổng kết

  • Dynamic/Async component: linh hoạt UI, lazy load.

  • Teleport: modal/toast dễ quản lý.

  • Suspense: chờ dữ liệu async.

  • Transition & Animation: trải nghiệm mượt mà.

  • Directive & Plugin: mở rộng Vue.

  • SSR với Nuxt 3: tối ưu SEO & tốc độ.

  • Code splitting: cải thiện hiệu năng.