Skip to content

Layer cung cấp gì

@tasco/nuxt-layer-baseđiểm vào duy nhất của framework. Một dòng extends mang theo toàn bộ plugin, middleware, layout, route BFF và cấu hình mặc định. Trang này liệt kê chính xác những gì dự án nhận được, thứ tự chúng chạy, và cách ghi đè từng phần.

ts
// nuxt.config.ts
export default defineNuxtConfig({
  extends: ['@tasco/nuxt-layer-base'],
})

Nuxt layer hoạt động thế nào

Layer là một dự án Nuxt đóng gói thành package. Khi extends, Nuxt gộp file theo đường dẫn: file cùng đường dẫn ở dự án luôn thắng file của layer; file chỉ có ở layer thì vẫn được nạp. Không có cơ chế "gộp một nửa" — ghi đè là thay cả file.

Với cấu hình thì ngược lại: nuxt.config.tsapp.config.ts được merge sâu, dự án chỉ cần khai phần muốn đổi. Mảng thì được nối (phần tử của dự án đứng trước, của layer nối sau) — nhờ vậy modulescss của layer không bị mất khi dự án khai thêm. Layer để navtopNav rỗng nên menu hiển thị đúng những gì dự án khai.

Tối đa 2 tầng

Quy ước của core: @tasco/nuxt-layer-base → app sản phẩm. Thêm tầng thứ ba (layer dùng chung cho vài sản phẩm) làm thứ tự ghi đè khó lần và phải mở RFC trước.

Bảng những gì layer mang theo

NhómNội dungGhi đè bằng cách
Module@ant-design-vue/nuxt (có extractStyle), @nuxt/fonts (self-host Quicksand + Montserrat)Khai thêm modules trong dự án — danh sách được nối, không thay thế
CSS nền@tasco/theme/base.css, @tasco/ui/style.cssThêm CSS của dự án qua css: [...], nạp sau
Renderssr: true + routeRules: { '/**': { ssr: false } }routeRules của dự án, xem Chế độ render
Auto-importuseApi, useAuth, usePermission, useTable, useThemeMode
Component toàn cục17 component C* thương hiệu (plugin 01.ui)
Plugin01.ui02.auth03.permission04.errorTạo plugin cùng tên trong app/plugins/
Middlewareauth.global, permission.globalTạo file cùng tên trong app/middleware/
Layoutapp/layouts/default.vue — khung sider + header + contentTạo app/layouts/default.vue trong dự án
Trangapp/pages/auth/login.vue, app/error.vueTạo file cùng đường dẫn
Component<TascoLoginForm>, <Can> (auto-import)
Serverserver/api/[...].ts (proxy /api/**), server/routes/auth/*Xem mục dưới
Cấu hìnhruntimeConfig mặc định, app.config.ts (tasco.*).env / app.config.ts của dự án

Thứ tự chạy khi mở một trang

1. Nitro khởi động — routeRules áp dụng (mặc định trang render phía client)
2. Plugin 01.ui         → đăng ký component C* toàn cục
3. Plugin 02.auth       → GET /auth/session, đổ vào useState('tasco:auth:user')
4. Plugin 03.permission → đăng ký directive v-can
5. Plugin 04.error      → gắn errorHandler toàn cục, cung cấp $tascoError
6. Middleware auth.global       → chưa đăng nhập, route không khai auth:false → /auth/login
7. Middleware permission.global → thiếu quyền trong meta.permissions → ném 403
8. app.vue      → <a-config-provider> (theme Tasco + locale vi_VN) + biến CSS --tasco-*
9. layouts/default.vue → sider (menu từ app.config, đã lọc quyền) + header + nội dung trang

Tiền tố số trong tên plugin quyết định thứ tự: 02.auth phải chạy trước 03.permission vì directive đọc user từ state. Middleware chạy theo thứ tự tên file, nên auth.global trước permission.global.

Ghi đè từng phần

Không cần ghi đè layout — khai báo trong app.config.ts của dự án:

ts
export default defineAppConfig({
  tasco: {
    appTitle: 'Quản lý đơn hàng',
    footerText: '© Tập đoàn Tasco',
    themeMode: 'light',
    topNav: [{ label: 'Điều hành', path: '/ops' }],
    nav: [{ label: 'Đơn hàng', path: '/orders', permission: '/orders/search' }],
  },
})

Layout riêng

Tạo app/layouts/default.vue trong dự án là layer không còn tác dụng cho layout đó. Khi đó dự án tự chịu trách nhiệm: lọc menu theo quyền (usePermission().filterByPermission), nút đổi sáng/tối (useThemeMode), menu tài khoản và logout. Cân nhắc dùng lại CAppLayout + CSideNav + CTopNav thay vì dựng từ đầu.

Trang đăng nhập riêng

vue
<!-- app/pages/auth/login.vue -->
<script setup lang="ts">
definePageMeta({ auth: false, layout: false })
</script>

<template>
  <div class="login-brand">
    <TascoLoginForm title="ONE AUTO" subtitle="Đăng nhập hệ thống" @success="navigateTo('/')" />
  </div>
</template>

app.vue riêng

Hạn chế ghi đè. Nếu buộc phải, giữ lại <a-config-provider> với theme + vi_VN và phần inject biến CSS — thiếu chúng thì toàn bộ màu, mật độ và bản địa hoá của antdv sai. Chép từ @tasco/nuxt-layer-base/app/app.vue rồi sửa.

Route server riêng

Route cụ thể trong server/ của dự án thắng catch-all server/api/[...].ts của layer. Dùng khi cần tổng hợp nhiều lời gọi, hoặc khi backend trả định dạng khác hẳn:

ts
// server/api/orders/summary.get.ts — thắng catch-all cho đúng đường dẫn này
export default defineEventHandler(async (event) => {
  // Cần token thì đọc session của layer, đừng tự giải mã cookie.
  const session = getTascoSession(event)
  // ...
})

Xem BFF: /api/** đi đâu.

Kiểm tra layer đã nạp đúng

bash
npx nuxi info          # liệt kê layer đang extends

Dấu hiệu layer chưa nạp: <CTable> báo unknown component, useApi không auto-import, vào trang không bị chuyển về /auth/login.

Liên quan