今天要結合前兩天的成果,完成 LIFF APP 串接 發送認證碼 API 的功能
要完成的功能有兩個:
Send Mail
這邊我們選用 axios 處理 Request,當然如果你習慣用 jQuery AJAX / fetch 也是可以的。
npm i axios --save-dev
別忘了在 vite.config.js
加上設定:
export default defineConfig({
plugins: [vue()],
base: '/{YOUR_PROJECT_NAME}/dist/',
optimizeDeps: {
include: ["axios"]
}
})
在 src 資料夾底下建立一個 service 資料夾,裡面新增一個 api.js 如下:
import axios from 'axios';
export const sendValidationCodePost = (name, mail, token) => {
const targetUrl = "YOUR_GAS_API_URL";
let data = JSON.stringify({name, mail, token});
return axios.post(targetUrl, data, {
headers: { 'content-type': 'application/x-www-form-urlencoded' }
}).then(response => {
if (response) {
return response;
} else {
return Promise.reject();
}
}).catch(error => {
console.log('error', error);
});
};
因為我們需要兩個 Component
所以我們將原本 BindMail.vue 拆成以下三個 Component:
修改 BindMail.vue 如下
<script setup>
import {onMounted, ref, provide} from 'vue'
import BindMailForm from "./BindMailForm.vue";
import BindMailResult from "./BindMailResult.vue";
const errorMsg = ref("");
// 判斷要顯示表單元件還是結果元件
const bindStep = ref('form');
// API 回應結果
const resMessage = ref('');
provide('resMessage', resMessage);
// 切換至結果元件顯示
const next = (event) => {
resMessage.value = event
bindStep.value = 'result'
}
// 判斷是否登入以及是否使用 Line 開啟 LIFF
const initializeApp = () => {
if (!liff.isLoggedIn() || !liff.isInClient()) {
errorMsg.value = "please use line liff open";
}
};
// 初始化 LIFF APP
onMounted(() => {
liff.init({
liffId: 'YOUR_LIFF_ID'
}).then(() => {
initializeApp();
}).catch((err) => {
errorMsg.value = "initialize LIFF fail";
});
});
</script>
<template>
<h1>驗證碼小幫手 - 身份認證</h1>
<component v-if="!errorMsg" :is="(bindStep === 'form') ? BindMailForm : BindMailResult" @nextStep="next"></component>
<p v-else class="error">{{ errorMsg }}</p>
</template>
新增 BindMailForm.vue 如下
<script setup>
import {onMounted, ref, defineEmits} from 'vue'
import {sendValidationCodePost} from '/src/service/api'
const userName = ref("");
const userToken = ref("");
const userEmail = ref("");
const inputEmail = ref("");
const emit = defineEmits(['nextStep'])
const submit = (mail) => {
sendValidationCodePost(userName.value, mail, userToken.value)
.then((res) => {
const result = res.data.message;
emit('nextStep', result);
})
.catch((err) => {
console.log("err: ", err);
});
}
onMounted(() => {
liff.ready.then(() => {
const user = liff.getDecodedIDToken();
userName.value = user && user.name;
userToken.value = user && user.sub;
userEmail.value = user && user.email;
})
})
</script>
<template>
<template v-if="userEmail">
<p>將發送身份認證碼到 {{ userEmail }}</p>
<button type="button" class="btn" @click="submit(userEmail)">確定</button>
</template>
<template v-else>
<p>發送身份認證碼到 <input type="email" v-model="inputEmail" placeholder="請輸入 Email"></p>
<button type="button" class="btn" @click="submit(inputEmail)">確定</button>
</template>
</template>
新增 BindMailResult.vue 如下
<template>
<p>{{(result === 'success') ? '已將驗證碼發送至信箱' : '發送失敗,請稍後再試'}}</p>
<button type="button" class="btn" @click="closeLiff">關閉</button>
</template>
<script setup>
import {inject} from "vue";
const result = inject('resMessage');
const closeLiff = () => {
liff.closeWindow();
}
</script>
接著就可以執行 npm run build
,然後將打包好的靜態檔案部署到 Github Pages 測試結果囉~