Nuxt3 features

概念

打通web後端到前端的開發方式,優勢上是語言的一致,資料類型即的一致。在NuxtJS也提供各種功能,來做到SSR(Server Side Render)機制,並利用專案的資料夾結構去綁定這些功能。

功能資料夾包含:

├─page
├─layouts
├─components
├─composable
├─public
├─server
├─content
└─middleware

以上這些我將依據前後端的使用情境,將它們歸類,並就我理解的使用方式作補充。

使用版本 "nuxt": "^3.0.0-rc.3"


前端

├─page

在前端每個頁面路徑(path)都能在這個資料夾內找到對應的頁面檔。比如'/'對應'index.vue,'/about'對應'about.vue'。

nuxt也支援path上帶有動態的參數,page的檔名命名方式為"[paramName].vue"。

nuxt page docopen in new window

├─layouts

而在各頁面中可以使用共用的佈局模板,在這個資料夾預設使用為default.vue,搭配slot特性與頁面去做嵌套。

#default.vue
<div>
    <Nav />
    <div class="content-wrapper">
      <slot />
    </div>
</div>

├─components

而不管是在page、layouts中還可以切分出更多共用的單位組件時,比如Nav組件使用在不同layout組件時,就會在這個資料夾下新增Nav.vue。

同時,在Nuxt框架下,也提供各種組件來使用,比如,NuxtLink組件,來實作連結。

#Nav.vue
<template>
  <header
    class="flex items-center justify-between h-20 px-[5%] lg:px-[15%] nav-header"
  >
    <NuxtLink to="/" class="font-bold text-2xl lg:text-4xl">
      <span class="text-primary">N</span>otes
    </NuxtLink>
  </header>
</template>

Nuxt3 components docopen in new window

├─public

在資料夾下放置的靜態檔案,可以讓客戶端直接訪問取得。比如放置favicon.ico,在部署後可以透過 https://nuxt3-notes.vercel.app/favicon.ico 訪問。

目前nuxt3文件示意參照nuxt2 static說明。 Nuxt2 static docopen in new window

├─composable

在資料夾結構中的每支檔案可以管理目前頁面間的共同狀態,使用方式是會自動import到page、layout的vue檔來呼叫,這也包含nuxt本身提供的方法,比如useHead()、useAsyncData()...等等。

nuxt composable docopen in new window

範例:

// composables/useAuth.js
const decode = (cookie = 'null') => JSON.parse(cookie);
const encode = (cookie) => JSON.stringify(cookie);

export const useAuth = () => {
  const authCookie = useCookie('auth', {
    encode,
    decode,
    default: () => null,
  });

  const deleteCookie = async (guessWord) => {
    authCookie.value = await $fetch(`/api/auth`, {
      method: 'DELETE',
    });
  };

  return { authCookie, deleteCookie };
};

//使用
const { authCookie, deleteCookie } = useAuth();

├─middleware

在資料夾中可定義路由的中間層,作為像是訪問權限的確認。 範例:

//auth.global.js
export default defineNuxtRouteMiddleware((to, from)=>{
  console.log('in nuxt middleware auth.js')
  const { authCookie, deleteCookie } = useAuth();
  if(to.path === '/'){
      return navigateTo('/')
  }else if(!authCookie.value){
      return navigateTo('/')
  }else{
      return navigateTo(to.path)
  }
})

後端

├─server

在server/api資料夾下,nuxt提供前端呼叫API server的模擬機制,來把資料回應給前端。 以範例來解說,defineEventHandler是nuxt定義的事件函式,event模擬的request中包含了呼叫請求的資訊。

//server/api/user/index.js
import { v4 as uuid } from 'uuid';
import { sendError } from 'h3';

//模擬使用
const db = {
  users: [],
};

export default defineEventHandler(async (event) => {
  switch (event.req.method) {
    
    //GET http://localhost:3000/api/user
    case 'GET': {
      return db.users;
    }
    //POST http://localhost:3000/api/user
    case 'POST': {
      const body = await useBody(event);
      if (!body.userName) {
        const badRequestErr = createError({
          statusCode: 400,
          statusMessage: 'userName is not found',
        });
        sendError(event, badRequestErr);
      }
      const newUser = {
        id: uuid(),
        item: body.userName,
        online: true,
      };

      db.users.push(newUser);
      return newUser;
    }
  }
});

前端部分,使用$fetch()、useFetch()呼叫server/api對應結構的檔案


const resultGet = await $fetch("/api/user",{method:"GET"});

const resultPost = await $fetch("/api/user",{method:"POST"});

├─content

在這個資料夾中可放置各種文檔和資料,如.md、.json,概念在客戶端不能直接透過路徑去訪問到這些檔案,而是需要透過nuxt提供的queryContent()來調取檔案。 範例:

#加入一個lineBot串接.md
content
├─1.blog
  ├─1.Third Part Tools
    ├─1.lineBot串接.md
//透過檔案路徑取得檔案 (目前版本中文字元會被取代掉)
const filePath = "blog/third-part-tools/lineBot";
const { data: blog } = await useAsyncData(filePath, () => {
  return queryContent(filePath).findOne();
});

nuxt quertyContent docopen in new window

nuxt.config.js

nuxt config docopen in new window


連結

範例內容open in new window