iT邦幫忙

2025 iThome 鐵人賽

DAY 20
0
Modern Web

設計 x 開發:從 Figma 到 Vue,打造 LINE 互動形象網站!系列 第 20

20 從專案畫面到 LINE 註冊完成!(下):用 Nuxt 完成第一版網站功能

  • 分享至 

  • xImage
  •  

前言

延續上一篇完成的 UI 畫面與元件素材,在這個篇章我們將加入 LIFF 提供的登入機制與完成註冊流程,完成 LINE 互動網站功能!
關於註冊流程的所有步驟,可以參考第四篇,裡面有完整的 User Flow 路線圖。以及在先前有提到,要使用 LIFF 功能記得先前往 LINE Developers 新增一個 LINE application,詳細的新增步驟可參考第十六篇,在這篇會聚焦在「註冊與註冊完成後的 Nuxt 實作流程」。

實作「會員註冊」LIFF 功能

  1. 首先,因為註冊流程是會透過 LINE 登入,所以請先安裝 @line/liff 套件:
npm install --save @line/liff

關於更多的 LINE Login 與 LIFF 介紹,可以參考第十六篇了解 LIFF 的初始化與功能說明,這邊主要會著重在實作流程的部份。

  1. 接著前往 plugins 資料夾新增 liff.js,建立 LIFF 外掛。
import liff from '@line/liff'

export default defineNuxtPlugin(() => {
  return {
    provide: {
      liff
    }
  }
})
  1. 由於 Nuxt 3 的 plugin 機制是將套件注入到 NuxtApp 上,在 useNuxtApp() 新增一個 $liff 變數,它是 Nuxt 的外掛系統(Plugin Injection)所注入的全域變數,讓我們可以在元件裡面使用 LIFF 函式。
<script setup>
.....
const { $swal, $liff } = useNuxtApp()
  1. 回到signup.vue,在註冊的第一步,我們先前已加上隱私權政策與服務條款視窗,接著我們要再加上,如果彈窗點選「同意」後,新增 $swal.then 內容,執行 liff 初始化並且驗證 liffid 是否有效,完成後判斷目前是否已經透過 LIFF 完成登入,如果沒有就執行 $liff.login() 指令觸發LINE登入,若已經登入透過 router.push('/member') 前往會員首頁。
  <script setup>
  ......
  const router = useRouter()
  const onLineSignupClick = async () => {
          if (!process.client) return
	  await $swal.fire({
	  ......
	  })
	.then( async(result) => {
	    if (result.isConfirmed) {
	        try {
	            await $liff.init({ liffId: "<填入LIFF ID>" })
	            if (!$liff.isLoggedIn()) {
	                $liff.login()
	                return
	            }
	            await router.push('/member')
	        } catch (error) {
	            console.error('執行錯誤:', error)
	        }
	    }
	})
  }

其他延伸說明,在實務專案中,當使用者登入成功後,通常會接著:

  • 進一步透過驗證機制,確認該使用者的合法性與目前狀態(例如 是否為啟用中狀態的帳號 等)。
  • 呼叫後端 API,取得使用者註冊時所儲存的會員資料。

不過在本篇介紹,主要聚焦在「前端互動流程的模擬」,所以選擇使用 useState() 來模擬登入狀態,暫不納入完整的後端驗證流程與串接資料庫來獲取資料。

  1. 建立 middleware 資料夾,再新增 login-auth.global.js 檔案。
    如果已登入就開始宣告 profile 變數,用 useState() 儲存 liff.getDecodedIDToken() 獲得的會員資訊。
export default defineNuxtRouteMiddleware(async (to, from) => {
    const { $liff } = useNuxtApp()
    if (process.client) {
        await $liff.init({ liffId: '<填入LIFF ID>' })
        if ($liff.isLoggedIn()) {
            const profile = useState('userProfile', () => '')
            profile.value = await $liff.getDecodedIDToken()
        }
    }
})

實作「會員首頁」取得資訊

接下來,我們將製作註冊完登入後前往的「會員首頁 」,進一步模擬使用者註冊完的實際情境。

  1. 先在「會員首頁」加入以下內容:

    • <script setup>加入 profile,取得 middleware 中的 useState 資料。
    • 加入 img 並且判斷如果 profile.picture 有值就顯示,如果沒有顯示原本的 svg
    • input 透過 v-model 取得值,其餘非欄位元素使用 {{}} 取值。
<script setup>
    const profile = useState('userProfile')
</script>
<template>
	.....
	<img v-if="profile.picture" :src="profile.picture" :alt="profile.name" />
	<svg v-else xmlns="http://www.w3.org/2000/svg" class="text-[#E2E8F0]" width="4rem" height="4em" viewBox="0 0 24 24">
		<path d="M8.5 13.498l2.5 3.006l3.5-4.506l4.5 6H5m16 1v-14a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2z" fill="currentColor" />
	</svg>
       ......
        <h1 class="text-2xl font-medium text-[#525252] mb-2">嗨 {{ profile.name }} 你好!</h1>
                <p class="text-[#98A0AE] text-sm">LINE ID {{ profile.sub }}</p>
       ......
        <div class="max-w-md mx-auto space-y-8">
                <div class="space-y-2">
                    <label class="text-[#98A0AE] text-base font-medium">姓名</label>
                    <div class="border-b border-[#CCCECF] pb-2">
                    <input
                        v-model="profile.name"
                        type="text"
                        class="w-full border-0 bg-transparent p-0 text-[#525252] placeholder:text-[#98A0AE] focus:outline-none"
                    />
                    </div>
                </div>
                <div class="space-y-2">
                    <label class="text-[#98A0AE] text-base font-medium">信箱</label>
                    <div class="border-b border-[#CCCECF] pb-2">
                    <input
                        v-model="profile.email"
                        type="email"
                        class="w-full border-0 bg-transparent p-0 text-[#525252] placeholder:text-[#98A0AE] focus:outline-none"
                    />
                    </div>
                </div>
            </div>

成果展示

  1. 接著我們來實際註冊看看吧!點擊「LINE 註冊」,並且閱讀完條款後點擊「同意」。
    20 從專案畫面到LINE註冊完成!(下):用 Nuxt 完成第一版網站功能 - 圖示1

  2. 接著會出現 LINE 登入許可頁面,點擊「登入」。
    20 從專案畫面到LINE註冊完成!(下):用 Nuxt 完成第一版網站功能 - 圖示2

  3. 最後註冊完成,登入後抵達「會員首頁」,首頁欄位會顯示 LINE 個人資訊。
    20 從專案畫面到LINE註冊完成!(下):用 Nuxt 完成第一版網站功能 - 圖示3

結語

到這裡,我們已經完成了從 UI 設計到註冊流程、再到會員首頁的完整模擬,已經打造出一個具備 LINE 快速登入、會員資料帶入顯示、條款彈窗交互體驗的互動網站!
其他在第四篇「使用者流程」有提到的其他流程互動細節,例如「登入成功後導向會員頁」或「點擊條款彈出說明」等小功能,以及第十九篇與本篇提到的內容,已一併實作在 GitHub 專案中,歡迎參考原始碼:專案 GitHub 網址小提醒:在運行專案之前,請先將專案中的 <填入LIFF ID> ,替換為自行申請的 LIFF ID,專案才能正常運行哦。

謝謝各位的閱讀,再來會分享 Nuxt 的延伸應用,我們下一篇見!🚀

參考資料與延伸閱讀

LINE Developers 官網來源
npm 安裝 liff 來源
Nuxt useNuxtApp 參考來源
GitHub 官網


上一篇
19 從專案初始化到畫面完成!(上):用 Nuxt 完成第一版網站功能
下一篇
21 在 Nuxt 中串接 API 顯示動態內容
系列文
設計 x 開發:從 Figma 到 Vue,打造 LINE 互動形象網站!26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言