เริ่มต้นใช้งาน Axios ใน Nuxt

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ ในบทช่วยสอนนี้ เราจะเรียนรู้วิธีส่งคำขอในแอปพลิเคชัน Nuxt.js โดยใช้โมดูล Axios เราจะได้เรียนรู้วิธีใช้ ayncData และวิธี fetch ข้อมูลเพื่อดึงข้อมูลทางฝั่งเซิร์ฟเวอร์โดยใช้ Axios และความแตกต่างระหว่างสองวิธี สุดท้าย เราจะเรียนรู้วิธีเพิ่มการตรวจสอบสิทธิ์ในแอปพลิเคชันของเราโดยใช้โมดูลการตรวจสอบสิทธิ์

Nuxt.js มีโมดูล Axios สำหรับการผสานรวมกับแอปพลิเคชันของคุณอย่างง่ายดาย Axios เป็นไคลเอนต์ HTTP ตามสัญญาที่ทำงานในเบราว์เซอร์และสภาพแวดล้อม Node.js หรือพูดง่ายๆ ก็คือเป็นเครื่องมือสำหรับส่งคำขอ (เช่น การเรียก API) ในแอปพลิเคชันฝั่งไคลเอ็นต์และสภาพแวดล้อม Node.js

ในบทช่วยสอนนี้ เราจะเรียนรู้วิธีใช้โมดูล Axios และวิธีส่งคำขอทางฝั่งเซิร์ฟเวอร์โดยใช้ asyncData และดึงข้อมูล ทั้งสองวิธีส่งคำขอทางฝั่งเซิร์ฟเวอร์ แต่มีความแตกต่างบางประการซึ่งเราจะกล่าวถึงด้วย สุดท้าย เราจะเรียนรู้วิธีดำเนินการตรวจสอบสิทธิ์และรักษาความปลอดภัยหน้า/เส้นทางโดยใช้โมดูลการตรวจสอบสิทธิ์และมิดเดิลแวร์ตรวจสอบสิทธิ์

บทความนี้ต้องการความรู้พื้นฐานเกี่ยวกับ Nuxtjs และ Vuejs เนื่องจากเราจะสร้างเพิ่มเติมจากนั้น สำหรับผู้ที่ไม่มีประสบการณ์กับ Vuejs เราขอแนะนำให้คุณเริ่มจากเอกสารอย่างเป็นทางการและหน้าอย่างเป็นทางการของ Nuxt ก่อนดำเนินการต่อในบทความนี้

โมดูล Nuxt.js Axios คืออะไร

ตามเอกสารอย่างเป็นทางการ

“เป็นการผสานรวม Axios ที่ปลอดภัยและง่ายดายกับ Nuxt.js”

นี่คือคุณสมบัติบางอย่าง:

  1. ตั้งค่า URL พื้นฐานสำหรับฝั่งไคลเอ็นต์และฝั่งเซิร์ฟเวอร์โดยอัตโนมัติ
  2. ส่วนหัวคำขอพร็อกซีใน SSR (มีประโยชน์สำหรับการตรวจสอบสิทธิ์)
  3. ดึงคำขอสไตล์
  4. ผสานรวมกับ Nuxt.js Progressbar ขณะส่งคำขอ

หากต้องการใช้โมดูล axios ในแอปพลิเคชันของคุณ คุณจะต้องติดตั้งก่อนโดยใช้ npm หรือ yarn

เส้นด้าย

 yarn add @nuxtjs/axios

NPM

 npm install @nuxtjs/axios

เพิ่มลงในไฟล์ nuxt.config.js ของคุณ:

 modules: [ '@nuxtjs/axios', ], axios: { // extra config eg // BaseURL: 'https://link-to-API' }

อาร์เรย์ modules ยอมรับรายการโมดูล Nuxt.js เช่น dotenv, auth และในกรณีนี้คือ Axios สิ่งที่เราได้ทำคือการแจ้งให้แอปพลิเคชันของเราทราบว่าเราจะใช้โมดูล Axios ซึ่งเราอ้างอิงโดยใช้ @nuxtjs/axios ตามด้วยคุณสมบัติ axios ซึ่งเป็นออบเจ็กต์ของการกำหนดค่า เช่น baseURL สำหรับทั้งฝั่งไคลเอ็นต์และฝั่งเซิร์ฟเวอร์

ตอนนี้คุณสามารถเข้าถึง Axios ได้จากทุกที่ในแอปพลิเคชันของคุณโดยเรียก this.$axios.method หรือ this.$axios.$method ที่ เมธอด สามารถ get post หรือ delete ได้

เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

การขอครั้งแรกโดยใช้ Axios

สำหรับบทช่วยสอนนี้ ฉันได้รวบรวมแอปพลิเคชันง่ายๆ บน Github ที่เก็บประกอบด้วยสองโฟลเดอร์ เริ่มต้นและสิ้นสุด โฟลเดอร์ เริ่มต้น มีทั้งหมดที่คุณต้องการเพื่อเข้าสู่บทช่วยสอน โฟลเดอร์ เสร็จสิ้น มีเวอร์ชันที่สมบูรณ์ของสิ่งที่เราจะสร้าง

หลังจากโคลน repo และเปิดโฟลเดอร์ start เราจะต้องติดตั้งแพ็คเกจทั้งหมดของเราในไฟล์ package.json ดังนั้นให้เปิดเทอร์มินัลของคุณและรันคำสั่งต่อไปนี้:

 npm install

เมื่อเสร็จแล้ว เราสามารถเริ่มแอปของเราโดยใช้คำสั่ง npm run dev นี่คือสิ่งที่คุณควรเห็นเมื่อไปที่ localhost:3000

หน้าที่มีส่วนหัวที่มีโลโก้และลิงก์การนำทาง
หน้า Landing Page ของแอปพลิเคชันของเรา (ตัวอย่างขนาดใหญ่)

สิ่งต่อไปที่เราต้องทำคือสร้างไฟล์ . .env ในโฟลเดอร์รูทของแอปพลิเคชันของเรา และเพิ่ม API URL ของเราเข้าไป สำหรับบทช่วยสอนนี้ เราจะใช้ API ตัวอย่างที่สร้างขึ้นเพื่อรวบรวมรายงานจากผู้ใช้

 API_URL=https://ireporter-endpoint.herokuapp.com/api/v2/

ด้วยวิธีนี้ เราไม่ต้องฮาร์ดโค้ด API ของเราลงในแอปของเรา ซึ่งมีประโยชน์สำหรับการทำงานกับ API สองตัว (การพัฒนาและการผลิต)

ขั้นตอนต่อไปคือการเปิดไฟล์ nuxt.config.js และเพิ่มตัวแปรสภาพแวดล้อมให้กับการกำหนดค่า axios ที่เราเพิ่มไว้ด้านบน

 /* ** Axios module configuration */ axios: { // See https://github.com/nuxt-community/axios-module#options baseURL: process.env.API_URL, },

ในที่นี้ เราบอกให้ Nuxt.js ใช้ baseURL นี้สำหรับคำขอทั้ง ฝั่งไคลเอ็นต์และฝั่ง เซิร์ฟเวอร์ ทุกครั้งที่เราใช้โมดูล Axios นี้

ในการดึงรายการรายงาน ให้เราเปิดไฟล์ index.vue และเพิ่มวิธีการต่อไปนี้ในส่วนสคริปต์

 async getIncidents() { let res = await this.$store.dispatch("getIncidents"); this.incidents = res.data.data.incidents; }

สิ่งที่เราได้ทำคือการสร้างฟังก์ชัน async ที่เราเรียกว่า getIncidents() และเราสามารถบอกได้ว่าชื่อนี้ใช้ทำอะไรจากชื่อ — มันดึงรายการเหตุการณ์โดยใช้วิธีการดำเนินการร้านค้า Vuex this.$store.dispatch เรามอบหมายการตอบสนองจากการกระทำนี้ให้กับทรัพย์สินเหตุการณ์ของเรา เพื่อให้เราสามารถใช้ประโยชน์จากมันในองค์ประกอบ

เราต้องการเรียกใช้ getIncidents() ทุกครั้งที่คอมโพเนนต์ติดตั้ง เราสามารถทำได้โดยใช้ตะขอ mounted

 mounted() { this.getIncidents() }

mounted() เป็นเบ็ดวงจรชีวิตที่ถูกเรียกเมื่อส่วนประกอบเมานต์ ซึ่งจะทำให้การเรียก API เกิดขึ้นเมื่อคอมโพเนนต์ติดตั้ง ตอนนี้ ให้เราไปที่ไฟล์ index.js ในร้านของเรา และสร้างการดำเนินการนี้ที่เราจะทำการร้องขอจาก Axios

 export const actions = { async getIncidents() { let res = await this.$axios.get('/incidents') return res; } }

ที่นี่ เราสร้างการกระทำที่เรียกว่า getIncidents ซึ่งเป็นฟังก์ชัน async จากนั้นเรา รอ การตอบกลับจากเซิร์ฟเวอร์และส่งคืนการตอบกลับนี้ การตอบสนองจากการกระทำนี้จะถูกส่งกลับไปยัง getIncidents() ของเราในไฟล์ index.vue

หากเรารีเฟรชแอปพลิเคชันของเรา ตอนนี้เราควรจะเห็นรายการเหตุการณ์ที่เกิดขึ้นมากมายบนหน้า

รายการเหตุการณ์จำลอง
รายการเหตุการณ์ในหน้า Landing Page (ตัวอย่างขนาดใหญ่)

เราได้ส่งคำขอครั้งแรกโดยใช้ Axios แต่เราจะไม่หยุดเพียงแค่นั้น เราจะลองใช้ asyncData และ fetch เพื่อดูความแตกต่างระหว่างพวกเขากับการใช้ Axios

AsyncData

AsyncData ดึงข้อมูลทางฝั่งเซิร์ฟเวอร์และถูกเรียกก่อนที่จะโหลดองค์ประกอบของหน้า ไม่มีสิทธิ์เข้าถึงเนื่องจากมี this เรียกก่อนที่จะสร้างข้อมูลองค์ประกอบของหน้า this ใช้ได้เฉพาะหลังจากมีการเรียก hook ที่ created แล้ว Nuxt.js จะรวมข้อมูลที่ส่งคืนลงในข้อมูลของส่วนประกอบโดยอัตโนมัติ

การใช้ asyncData นั้นดีสำหรับ SEO เพราะมันดึงเนื้อหาไซต์ของคุณทางฝั่งเซิร์ฟเวอร์และยังช่วยในการโหลดเนื้อหาได้เร็วขึ้น โปรดทราบว่าเมธอด asyncData สามารถใช้ได้ในโฟลเดอร์เพจของแอปพลิเคชันของคุณเท่านั้น เนื่องจากจะใช้ไม่ได้ในโฟลเดอร์คอมโพเนนต์ นี่เป็นเพราะ asyncData hook ถูกเรียกก่อนที่จะสร้างส่วนประกอบของคุณ

รูปภาพแสดงวงจรชีวิตของ Nuxt
ภาพจากบล็อก Nuxt (ตัวอย่างขนาดใหญ่)

ให้เราเพิ่ม asyncData ลงในไฟล์ index.vue และสังเกตว่า ข้อมูล เหตุการณ์ ของเราโหลดเร็วแค่ไหน เพิ่มโค้ดต่อไปนี้หลังคุณสมบัติ ส่วนประกอบ ของเรา และให้เรากำจัด hook ที่ติดตั้งของเรา

 async asyncData({ $axios }) { let { data } = await $axios.get("/incidents"); return { incidents: data.data.incidents }; }, // mounted() { // this.getIncidents(); // },

ที่นี่ เมธอด asyncData ยอมรับคุณสมบัติจากบริบท $axios เราใช้คุณสมบัตินี้เพื่อดึงรายการเหตุการณ์และค่าจะถูกส่งกลับ ค่านี้จะถูกฉีดเข้าไปในส่วนประกอบของเราโดยอัตโนมัติ ตอนนี้คุณสามารถสังเกตได้ว่าเนื้อหาของคุณโหลดได้เร็วเพียงใด หากคุณรีเฟรชหน้าและไม่ต้องแสดงเหตุการณ์ใด ๆ ในเวลา ใด

ดึงข้อมูล

วิธีการดึงข้อมูลยังใช้เพื่อส่งคำขอทางฝั่งเซิร์ฟเวอร์ มันถูกเรียกหลังจาก hook ที่สร้างขึ้นในวงจรชีวิตซึ่งหมายความว่าสามารถเข้าถึงข้อมูลของส่วนประกอบได้ ต่างจากเมธอด asyncData วิธีดึงข้อมูลสามารถใช้ได้ในไฟล์ .vue ทั้งหมดและใช้กับที่ เก็บ Vuex ซึ่งหมายความว่าหากคุณมีสิ่งต่อไปนี้ในฟังก์ชันข้อมูลของคุณ

 data() { return { incidents: [], id: 5, gender: 'male' }; }

คุณสามารถแก้ไข รหัส หรือ เพศ ได้อย่างง่ายดายโดยเรียก this.id หรือ this.gender

การใช้ Axios เป็นปลั๊กอิน

ในระหว่างขั้นตอนการพัฒนากับ Axios คุณอาจพบว่าคุณต้องการการกำหนดค่าเพิ่มเติม เช่น การสร้างอินสแตนซ์และตัวสกัดกั้นสำหรับคำขอของคุณ เพื่อให้แอปพลิเคชันของคุณทำงานได้ตามที่ตั้งใจไว้และโชคดีที่เราสามารถทำได้โดยขยาย Axios ของเราลงในปลั๊กอิน

ในการขยาย axios คุณต้องสร้างปลั๊กอิน (เช่น axios.js ) ในโฟลเดอร์ plugins ของคุณ

 export default function ({ $axios, store, redirect }) { $axios.onError(error => { if (error.response && error.response.status === 500) { redirect('/login') } }) $axios.interceptors.response.use( response => { if (response.status === 200) { if (response.request.responseURL && response.request.responseURL.includes('login')) { store.dispatch("setUser", response); } } return response } ) }

นี่คือตัวอย่างปลั๊กอินที่ฉันเขียนสำหรับแอปพลิเคชัน Nuxt ที่นี่ ฟังก์ชันของคุณใช้วัตถุบริบทของ $axios store และ redirect ที่เราจะใช้ในการกำหนดค่าปลั๊กอิน สิ่งแรกที่เราทำคือการฟังข้อผิดพลาดที่มีสถานะ 500 โดยใช้ $axios.onError และเปลี่ยนเส้นทางผู้ใช้ไปยังหน้าเข้าสู่ระบบ

นอกจากนี้เรายังมีตัวสกัดกั้นที่สกัดกั้นทุกการตอบกลับคำขอที่เราทำในแอปพลิเคชันของเราตรวจสอบว่าสถานะของการตอบกลับที่เราได้รับคือ 200 หรือไม่ หากเป็นเช่นนั้น เราจะดำเนินการต่อและตรวจสอบว่ามี response.request.responseURL และหากมีการเข้าสู่ระบบด้วย หากการเช็คเอาต์เป็นจริง เราจะส่งการตอบกลับนี้โดยใช้วิธีการจัดส่งของร้านค้าของเรา จากนั้นจึงกลายพันธุ์ในสถานะของเรา

เพิ่มปลั๊กอินนี้ในไฟล์ nuxt.config.js ของคุณ:

 plugins: [ '~/plugins/axios' ]

หลังจากทำเช่นนี้ ปลั๊กอิน Axios ของคุณจะสกัดกั้นคำขอใดๆ ของคุณ และตรวจสอบว่าคุณได้กำหนดกรณีพิเศษไว้หรือไม่

บทนำสู่โมดูลการตรวจสอบสิทธิ์

โมดูลการตรวจสอบความถูกต้องใช้สำหรับการตรวจสอบสิทธิ์สำหรับแอปพลิเคชัน Nuxt ของคุณและสามารถเข้าถึงได้จากทุกที่ในแอปพลิเคชันของคุณโดยใช้ $this.auth นอกจากนี้ยังมีให้ใน fetch , asyncData , middleware และ NuxtInitServer จากวัตถุบริบทเป็น $auth

context จัดเตรียมอ็อบเจ็กต์/พารามิเตอร์เพิ่มเติมจากคอมโพเนนต์ Nuxt ถึง Vue และพร้อมใช้งานในพื้นที่วงจรชีวิต nuxt พิเศษดังที่กล่าวไว้ข้างต้น

หากต้องการใช้โมดูลการตรวจสอบสิทธิ์ในแอปพลิเคชันของคุณ คุณจะต้องติดตั้งโดยใช้ yarn หรือ npm

เส้นด้าย

 yarn add @nuxtjs/auth

NPM

 npm install @nuxtjs/auth

เพิ่มลงในไฟล์ nuxt.config.js ของคุณ

 modules: [ '@nuxtjs/auth' ], auth: { // Options }

คุณสมบัติ การรับรอง ความถูกต้องยอมรับรายการคุณสมบัติ เช่น strategies และการ redirect ที่นี่ strategies ยอมรับวิธีการรับรองความถูกต้องที่คุณต้องการ ซึ่งสามารถ:

  • local
    สำหรับชื่อผู้ใช้/อีเมลและขั้นตอนที่ใช้รหัสผ่าน
  • facebook
    สำหรับการใช้บัญชี Facebook เป็นวิธีการรับรองความถูกต้อง
  • Github
    สำหรับการพิสูจน์ตัวตนผู้ใช้ด้วยบัญชี Github
  • Google
    สำหรับการพิสูจน์ตัวตนผู้ใช้ด้วยบัญชี Google
  • Auth0
  • หนังสือเดินทาง Laravel

คุณสมบัติเปลี่ยนเส้นทาง ยอมรับอ็อบเจ็กต์ของลิงก์สำหรับ:

  • login
    ผู้ใช้จะถูกเปลี่ยนเส้นทางไปยังลิงก์นี้หากจำเป็นต้องเข้าสู่ระบบ
  • logout
    ผู้ใช้จะถูกเปลี่ยนเส้นทางที่นี่หากหลังจากออกจากระบบเส้นทางปัจจุบันได้รับการป้องกัน
  • home
    ผู้ใช้จะถูกเปลี่ยนเส้นทางที่นี่หลังจากเข้าสู่ระบบ

ตอนนี้ ให้เราเพิ่มสิ่งต่อไปนี้ในไฟล์ nuxt.config.js ของเรา

 /* ** Auth module configuration */ auth: { redirect: { login: '/login', logout: '/', home: '/my-reports' }, strategies: { local: { endpoints: { login: { url: "/user/login", method: "post", propertyName: "data.token", }, logout: false, user: false, }, tokenType: '', tokenName: 'x-auth', autoFetchUser: false }, }, }

โปรด auth ว่าวิธีการตรวจสอบสิทธิ์จะทำงานได้ดีที่สุดเมื่อมีปลายทางของ user ที่ให้ไว้ในตัวเลือกด้านบน

ภายในอ็อบเจ็กต์ auth config เรามีตัวเลือกการ redirect ซึ่งเราตั้งค่าเส้นทางการเข้าสู่ระบบเป็น /login เส้นทาง ออกจากระบบ ไปยัง / และเส้นทาง กลับบ้าน ไปยัง /my-reports ซึ่งทั้งหมดจะทำงานตามที่คาดไว้ นอกจากนี้เรายังมีคุณสมบัติ tokenType ซึ่งแสดงถึงประเภทการให้สิทธิ์ในส่วนหัวของคำขอ Axios ของเรา มันถูกตั้งค่าเป็น Bearer โดยค่าเริ่มต้นและสามารถเปลี่ยนให้ทำงานกับ API ของคุณได้

สำหรับ API ของเรานั้น ไม่มีประเภทโทเค็น และนี่คือเหตุผลที่เราจะปล่อยให้มันเป็นสตริงว่าง tokenName แสดงถึงชื่อการอนุญาต (หรือคุณสมบัติส่วนหัวที่คุณต้องการแนบโทเค็นของคุณ) ภายในส่วนหัวของคุณในคำขอ Axios ของคุณ

โดยค่าเริ่มต้น มันถูกตั้งค่าเป็น Authorization แต่สำหรับ API ของเรา ชื่อการให้สิทธิ์คือ x-auth คุณสมบัติ autoFetchUser ใช้เพื่อเปิดใช้งานการดึงข้อมูลผู้ใช้โดย user คุณสมบัติจุดปลายผู้ใช้หลังจากเข้าสู่ระบบ มันเป็น true โดยค่าเริ่มต้น แต่ API ของเราไม่มีจุดปลาย user ดังนั้นเราจึงตั้งค่านั้น false

สำหรับบทช่วยสอนนี้ เราจะใช้กลยุทธ์ในพื้นที่ ในกลยุทธ์ของเรา เรามีตัวเลือกในพื้นที่ซึ่งมีจุดสิ้นสุดสำหรับการเข้าสู่ระบบ ผู้ใช้ และออกจากระบบ แต่ในกรณีของเรา เราจะใช้ตัวเลือก *login* เท่านั้น เนื่องจาก API สาธิตของเราไม่มีจุดสิ้นสุด *logout* และวัตถุผู้ใช้ของเราจะถูกส่งคืน เมื่อ *login* สำเร็จ

หมายเหตุ: auth การตรวจสอบสิทธิ์ไม่มีตัวเลือกจุดสิ้นสุดการลงทะเบียน ซึ่งหมายความว่าเราจะลงทะเบียนด้วยวิธีดั้งเดิมและเปลี่ยนเส้นทางผู้ใช้ไปยังหน้าเข้าสู่ระบบซึ่งเราจะดำเนินการตรวจสอบสิทธิ์โดยใช้ this.$auth.loginWith นี่คือวิธีการที่ใช้ในการตรวจสอบผู้ใช้ของคุณ ยอมรับ 'กลยุทธ์' (เช่น local ) เป็นอาร์กิวเมนต์แรก จากนั้นเป็นอ็อบเจ็กต์เพื่อดำเนินการตรวจสอบสิทธิ์ด้วย ลองดูตัวอย่างต่อไปนี้

 let data { email: '[email protected]', password: '123456' } this.$auth.loginWith('local', { data })

การใช้โมดูลการตรวจสอบสิทธิ์

ตอนนี้เราได้กำหนดค่าโมดูลการตรวจสอบความถูกต้องแล้ว เราสามารถไปยังหน้าการลงทะเบียนของเราได้ หากคุณไปที่หน้า /register คุณจะเห็นแบบฟอร์มการลงทะเบียน

หน้าแบบฟอร์มลงทะเบียน
หน้าลงทะเบียน. (ตัวอย่างขนาดใหญ่)

ให้เราทำให้แบบฟอร์มนี้ใช้งานได้โดยเพิ่มรหัสต่อไปนี้:

 methods: { async registerUser() { this.loading = true; let data = this.register; try { await this.$axios.post("/user/create", data); this.$router.push("/login"); this.loading = false; this.$notify({ group: "success", title: "Success!", text: "Account created successfully" }); } catch (error) { this.loading = false; this.$notify({ group: "error", title: "Error!", text: error.response ? error.response.data.error : "Sorry an error occured, check your internet" }); } } }

ที่นี่ เรามีฟังก์ชัน async ที่เรียกว่า registerUser ซึ่งเชื่อมโยงกับเหตุการณ์การคลิกในเทมเพลตของเรา และทำให้คำขอ Axios รวมอยู่ใน บล็อก try/catch ไปยังจุดปลาย /user/create สิ่งนี้จะเปลี่ยนเส้นทางไปยังหน้า /login และแจ้งให้ผู้ใช้ลงทะเบียนสำเร็จ นอกจากนี้เรายังมีบล็อกตรวจจับที่แจ้งเตือนผู้ใช้ถึงข้อผิดพลาดหากคำขอไม่สำเร็จ

หากการลงทะเบียนสำเร็จ คุณจะถูกนำไปที่หน้าเข้าสู่ระบบ

หน้าแบบฟอร์มเข้าสู่ระบบ
หน้าเข้าสู่ระบบพร้อมองค์ประกอบการแจ้งเตือน (ตัวอย่างขนาดใหญ่)

ที่นี่ เราจะใช้วิธีตรวจสอบสิทธิ์ this.$auth.loginWith('local', loginData) หลังจากนั้นเราจะใช้ this.$auth.setUser(userObj) เพื่อตั้งค่าผู้ใช้ในอินสแตนซ์ auth ของเรา

เพื่อให้หน้าเข้าสู่ระบบทำงาน ให้เพิ่มรหัสต่อไปนี้ในไฟล์ login.vue ของเรา

 methods: { async logIn() { let data = this.login; this.loading = true; try { let res = await this.$auth.loginWith("local", { data }); this.loading = false; let user = res.data.data.user; this.$auth.setUser(user); this.$notify({ group: "success", title: "Success!", text: "Welcome!" }); } catch (error) { this.loading = false; this.$notify({ group: "error", title: "Error!", text: error.response ? error.response.data.error : "Sorry an error occured, check your internet" }); } } }

เราได้สร้างฟังก์ชัน async ที่เรียกว่า logIn โดยใช้วิธี auth this.$auth.loginWith('local, loginData) หากความพยายามเข้าสู่ระบบนี้สำเร็จ เราจะกำหนดข้อมูลผู้ใช้ให้กับอินสแตนซ์การตรวจสอบสิทธิ์ของเราโดยใช้ this.$auth.setUser(userInfo) และเปลี่ยนเส้นทางผู้ใช้ไปยังหน้า /my-report

ตอนนี้คุณสามารถรับข้อมูลผู้ใช้โดยใช้ this.$auth.user หรือกับ Vuex โดยใช้ this.$store.state.auth.user แต่นั่นไม่ใช่ทั้งหมด อินสแตนซ์การตรวจสอบความถูก auth มีคุณสมบัติอื่นๆ ซึ่งคุณสามารถดูได้ว่าคุณเข้าสู่ระบบหรือตรวจสอบสถานะของคุณโดยใช้เครื่องมือ Vue dev ของคุณหรือไม่

หากคุณบันทึก this.$store.state.auth ลงในคอนโซล คุณจะเห็นสิ่งนี้:

 { "auth": { "user": { "id": "d7a5efdf-0c29-48aa-9255-be818301d602", "email": "[email protected]", "lastName": "Xo", "firstName": "Tm", "othernames": null, "isAdmin": false, "phoneNumber": null, "username": null }, "loggedIn": true, "strategy": "local", "busy": false } }

auth สแตนซ์การตรวจสอบ loggedIn มีคุณสมบัติการเข้าสู่ระบบที่เป็นประโยชน์ในการสลับไปมาระหว่างลิงก์ที่ตรวจสอบสิทธิ์ในส่วนการนำทาง/ส่วนหัวของแอปพลิเคชันของคุณ นอกจากนี้ยังมีวิธีกลยุทธ์ที่ระบุประเภทของกลยุทธ์ที่อินสแตนซ์กำลังทำงานอยู่ (เช่น ในพื้นที่)

ตอนนี้ เราจะใช้ประโยชน์จากคุณสมบัติที่ loggedIn นี้เพื่อจัดเรียงลิงก์ nav ทางของเรา อัปเดตองค์ประกอบ navBar ของคุณดังต่อไปนี้:

 <template> <header class="header"> <div class="logo"> <nuxt-link to="/"> <Logo /> </nuxt-link> </div> <nav class="nav"> <div class="nav__user" v-if="auth.loggedIn"> <p>{{ auth.user.email }}</p> <button class="nav__link nav__link--long"> <nuxt-link to="/report-incident">Report incident</nuxt-link> </button> <button class="nav__link nav__link--long"> <nuxt-link to="/my-reports">My Reports</nuxt-link> </button> <button class="nav__link" @click.prevent="logOut">Log out</button> </div> <button class="nav__link" v-if="!auth.loggedIn"> <nuxt-link to="/login">Login</nuxt-link> </button> <button class="nav__link" v-if="!auth.loggedIn"> <nuxt-link to="/register">Register</nuxt-link> </button> </nav> </header> </template> <script> import { mapState } from "vuex"; import Logo from "@/components/Logo"; export default { name: "nav-bar", data() { return {}; }, computed: { ...mapState(["auth"]) }, methods: { logOut() { this.$store.dispatch("logOut"); this.$router.push("/login"); } }, components: { Logo } }; </script> <style></style>

ในส่วนเทมเพลตของเรา เรามีลิงก์หลายลิงก์ไปยังส่วนต่างๆ ของแอปพลิเคชันซึ่งขณะนี้เราใช้ auth.loggedIn เพื่อแสดงลิงก์ที่เหมาะสมตามสถานะการตรวจสอบสิทธิ์ เรามีปุ่มออกจากระบบที่มีเหตุการณ์การ click พร้อมฟังก์ชันล็อกเอาต์ logOut() ติดอยู่ นอกจากนี้เรายังแสดงอีเมลของผู้ใช้ที่ได้รับจากคุณสมบัติการรับรองความถูกต้องซึ่งเข้าถึงได้จากร้านค้า Vuex ของเราโดยใช้เมธอด mapState ซึ่งแมปการตรวจสอบสถานะของเรากับคุณสมบัติที่คำนวณขององค์ประกอบการนำทาง นอกจากนี้เรายังมีวิธีการ logout ที่เรียกการดำเนินการออกจากระบบ logOut และเปลี่ยนเส้นทางผู้ใช้ไปยังหน้า login

ตอนนี้ ให้เราไปข้างหน้าและอัปเดตร้านค้าของเราเพื่อให้มีการ logOut การออกจากระบบ

 export const actions = { // .... logOut() { this.$auth.logout(); } }

การดำเนินการ logOut เอาต์จะเรียกวิธีการ logout auth ซึ่งจะล้างข้อมูลผู้ใช้ ลบโทเค็นจาก localStorage และตั้งค่าการ loggedIn สู่ระบบ false

แขกผู้เข้าพัก ไม่ควรมองเห็นเส้นทางเช่น /my-reports และ report-incident แต่ ณ จุดนี้ในแอปของเรา นั่นไม่ใช่กรณี Nuxt ไม่มีการ์ดนำทางที่สามารถปกป้องเส้นทางของคุณได้ แต่มีมิดเดิลแวร์รับรองความถูกต้อง มันให้อิสระแก่คุณในการสร้างมิดเดิลแวร์ของคุณเอง เพื่อให้คุณสามารถกำหนดค่าให้ทำงานตามที่คุณต้องการ

สามารถตั้งค่าได้สองวิธี:

  1. ต่อเส้นทาง.
  2. ทั่วโลกสำหรับทั้งแอปในไฟล์ nuxt.config.js ของคุณ
 router: { middleware: ['auth'] }

มิดเดิลแวร์ auth ความถูกต้องนี้ทำงานร่วมกับอินสแตนซ์ auth ตรวจสอบสิทธิ์ของคุณ ดังนั้นคุณไม่จำเป็นต้องสร้างไฟล์ auth.js ในโฟลเดอร์มิดเดิลแวร์ของคุณ

ให้เราเพิ่มมิดเดิลแวร์นี้ในไฟล์ my-reports.vue และ report-incident.vue ของเรา เพิ่มบรรทัดโค้ดต่อไปนี้ในส่วนสคริปต์ของแต่ละไฟล์

 middleware: 'auth'

ตอนนี้ แอปพลิเคชันของเราจะตรวจสอบว่าผู้ใช้ที่พยายามเข้าถึงเส้นทางเหล่านี้มีค่า auth.loggedIn true หรือไม่ โดยจะเปลี่ยนเส้นทางไปยังหน้าเข้าสู่ระบบโดยใช้ตัวเลือกการเปลี่ยน เส้นทาง ในไฟล์กำหนดค่าการตรวจสอบสิทธิ์ หากคุณไม่ได้ลงชื่อเข้าใช้และพยายามเข้าชม /my-report หรือ report-incident คุณจะถูกเปลี่ยนเส้นทางไปที่ /login

หากคุณไปที่ /report-incidents นี่คือสิ่งที่คุณควรเห็น

แบบฟอร์มแจ้งเหตุ
รายงานหน้าเหตุการณ์ (ตัวอย่างขนาดใหญ่)

หน้านี้มีไว้สำหรับเพิ่มเหตุการณ์ แต่ขณะนี้แบบฟอร์มไม่ส่ง เหตุการณ์ ไปยังเซิร์ฟเวอร์ของเรา เนื่องจากเราไม่ได้ทำการเรียกไปยังเซิร์ฟเวอร์เมื่อผู้ใช้พยายามส่งแบบฟอร์ม เพื่อแก้ปัญหานี้ เราจะเพิ่มเมธอด reportIncident ซึ่งจะถูกเรียกเมื่อผู้ใช้คลิกที่ Report เราจะมีสิ่งนี้ในส่วนสคริปต์ของส่วนประกอบ วิธีนี้จะส่งข้อมูลแบบฟอร์มไปยังเซิร์ฟเวอร์ อัปเดตไฟล์ report-incident.vue ของคุณดังนี้:

 <template> <section class="report"> <h1 class="report__heading">Report an Incident</h1> <form class="report__form"> <div class="input__container"> <label for="title" class="input__label">Title</label> <input type="text" name="title" v-model="incident.title" class="input__field" required /> </div> <div class="input__container"> <label for="location" class="input__label">Location</label> <input type="text" name="location" v-model="incident.location" required class="input__field" /> </div> <div class="input__container"> <label for="comment" class="input__label">Comment</label> <textarea name="comment" v-model="incident.comment" class="input__area" cols="30" rows="10" required ></textarea> </div> <input type="submit" value="Report" class="input__button" @click.prevent="reportIncident" /> <p class="loading__indicator" v-if="loading">Please wait....</p> </form> </section> </template> <script> export default { name: "report-incident", middleware: "auth", data() { return { loading: false, incident: { type: "red-flag", title: "", location: "", comment: "" } }; }, methods: { async reportIncident() { let data = this.incident; let formData = new FormData(); formData.append("title", data.title); formData.append("type", data.type); formData.append("location", data.location); formData.append("comment", data.comment); this.loading = true; try { let res = await this.$store.dispatch("reportIncident", formData); this.$notify({ group: "success", title: "Success", text: "Incident reported successfully!" }); this.loading = false; this.$router.push("/my-reports"); } catch (error) { this.loading = false; this.$notify({ group: "error", title: "Error!", text: error.response ? error.response.data.error : "Sorry an error occured, check your internet" }); } } } }; </script> <style> </style>

ที่นี่ เรามีแบบฟอร์มพร้อมช่องป้อนข้อมูลสำหรับชื่อ ตำแหน่ง และความคิดเห็นพร้อมการเชื่อมโยงข้อมูลแบบสองทางโดยใช้ v-model เรายังมีปุ่ม submit พร้อมเหตุการณ์การคลิก ในส่วนสคริปต์ เรามีวิธีรายงานเหตุการณ์ที่รวบรวมข้อมูลทั้งหมดที่ระบุในแบบฟอร์ม และส่งไปยังเซิร์ฟเวอร์ของเราโดยใช้ reportIncident เนื่องจาก API ได้รับการออกแบบให้ยอมรับรูปภาพและวิดีโอด้วย

แบบฟอร์มนี้แนบข้อมูลกับการกระทำของ formData โดยใช้วิธีการจัดส่ง หากคำขอสำเร็จ คุณจะถูกเปลี่ยนเส้นทางไปที่ /my-reports พร้อมการแจ้งเตือนที่แจ้งให้คุณทราบว่าคำขอนี้สำเร็จแล้ว มิฉะนั้น คุณจะได้รับแจ้งข้อผิดพลาดพร้อมข้อความแสดงข้อผิดพลาด .

ณ จุดนี้ เรายังไม่มีการดำเนินการ reportIncident ในร้านของเรา ดังนั้นในคอนโซลเบราว์เซอร์ของคุณ คุณจะเห็นข้อผิดพลาดหากคุณพยายามคลิกส่งในหน้านี้

ข้อความแสดงข้อผิดพลาดที่อ่าน '[Vuex] ประเภทการดำเนินการที่ไม่รู้จัก: reportIncident'
ข้อความแสดงข้อผิดพลาด Vuex (ตัวอย่างขนาดใหญ่)

ในการแก้ไขปัญหานี้ ให้เพิ่มการดำเนินการ reportIncident ในไฟล์ index.js ของคุณ

 export const actions = { // ... async reportIncident({}, data) { let res = await this.$axios.post('/incident/create', data) return res; } }

ที่นี่ เรามีฟังก์ชัน reportIncident ที่รับวัตถุบริบทที่ว่างเปล่าและข้อมูลที่เราส่งจากแบบฟอร์มของเรา ข้อมูลนี้จะถูกแนบไปกับคำขอ post ที่สร้างเหตุการณ์และย้อนกลับไปยังไฟล์ report-incident.vue ของเรา

ณ จุดนี้ คุณควรจะเพิ่มรายงานได้โดยใช้แบบฟอร์ม หลังจากนั้นคุณจะถูกเปลี่ยนเส้นทางไปยังหน้า /my-reports

หน้ารายงานของฉันว่างเปล่า
หน้ารายงานของฉันว่างเปล่า (ตัวอย่างขนาดใหญ่)

หน้านี้ควรแสดงรายการเหตุการณ์ที่ผู้ใช้สร้างขึ้น แต่ตอนนี้แสดงเฉพาะสิ่งที่เราเห็นด้านบน ไปแก้ไขกัน

เราจะใช้วิธี fetch ที่เราได้เรียนรู้เพื่อให้ได้รายการนี้ อัปเดตไฟล์ my-reports.vue ของคุณดังนี้:

 <script> import incidentCard from "@/components/incidentCard.vue"; export default { middleware: "auth", name: "my-reports", data() { return { incidents: [] }; }, components: { incidentCard }, async fetch() { let { data } = await this.$axios.get("/user/incidents"); this.incidents = data.data; } }; </script>

ที่นี่ เราใช้วิธี fetch เพื่อรับเหตุการณ์เฉพาะผู้ใช้และกำหนดการตอบสนองให้กับอาร์เรย์เหตุการณ์ของเรา

หากคุณรีเฟรชหน้าของคุณหลังจากเพิ่มเหตุการณ์ คุณควรเห็นสิ่งนี้

หน้ารายงานของฉันพร้อมรายงานเดียว
หน้ารายงานของฉันพร้อมรายงาน (ตัวอย่างขนาดใหญ่)

ณ จุดนี้ เราจะสังเกตเห็นความแตกต่างในการ fetch และ asyncData โหลดข้อมูลของเรา

บทสรุป

จนถึงตอนนี้ เราได้เรียนรู้เกี่ยวกับโมดูล Axios และคุณลักษณะทั้งหมดแล้ว นอกจากนี้เรายังได้เรียนรู้เพิ่มเติมเกี่ยวกับ asyncData และวิธีที่เราสามารถดึงข้อมูลทั้งสองเข้าด้วยกันแม้ว่าจะมีความแตกต่างกัน นอกจากนี้เรายังได้เรียนรู้วิธีดำเนินการตรวจสอบสิทธิ์ในแอปพลิเคชันของเราโดยใช้โมดูลการตรวจสอบสิทธิ์และวิธีใช้มิดเดิลแวร์การตรวจสอบสิทธิ์เพื่อปกป้องเส้นทางของเรา ต่อไปนี้คือแหล่งข้อมูลที่มีประโยชน์ซึ่งจะพูดถึงทุกสิ่งที่เราพูดถึงมากขึ้น

  • เริ่มต้นใช้งานเมตาแท็กใน Nuxjs
  • การใช้โมดูล dotenv ใน Nuxt
  • การใช้การดึงข้อมูลในแอป Nuxt ของคุณ
  • เริ่มต้นใช้งาน asyncData

ทรัพยากร

  1. “โมดูลการตรวจสอบสิทธิ์” NuxtJS.org
  2. “โมดูล Axios: บทนำ” NuxtJS.org
  3. FormData , เอกสารเว็บ MDN
  4. “API: วิธี asyncData ” NuxtJS.org
  5. “อินสแตนซ์ Vue: แผนภาพวงจรชีวิต” VueJS.org
  6. “ทำความเข้าใจว่าการ fetch ทำงานอย่างไรใน Nuxt 2.12” NuxtJS.org