JavaScript >> Javascript 文檔 >  >> Vue.js

使用 Nuxt、Vuex 和 Firebase 構建用戶帳戶

最近,我正在努力將用戶帳戶實現到我一直在構建的應用程序中,其中 Nuxt 作為前端,Firebase 用於後端/數據庫。我發現了很多有用的文章,但總是有一些警告。有些人只展示了過程的一部分(通常是我已經弄清楚的部分),或者他們使用了一種比我的情況要求的更冗長的方法。這把我們帶到了這裡!話不多說,以我所知道的最簡單的方式使用 Nuxt、Firebase 和 Vuex 構建用戶帳戶。

  1. 設置您的 Nuxt 項目
  2. 設置 Firebase
  3. 設置 Vuex
  4. 構建用戶界面
  5. 獎勵:構建用戶登錄的標題組件

對閱讀不感興趣?您可以在此處查看源代碼。

設置你的 Nuxt 項目

Vue 和 Nuxt 的一大優點是它們的文檔以及它們使新項目的啟動和運行變得多麼容易。如果您訪問此處的文檔,您會發現它是多麼容易。

要啟動一個新項目,您只需在終端中輸入“npx create-nuxt-app project-name”即可開始比賽!在這種情況下,我將使用命令“npx create-nuxt-app nuxt-firebase-vuex-tutorial”。

npx create-nuxt-app nuxt-firebase-vuex-tutorial

運行此命令後,您的終端會提示您一些問題,以幫助您設置新的 Nuxt 應用程序。

首先,它會詢問您一些一般信息:姓名、描述和作者。之後,它將要求您提供其他信息以幫助您設置新項目。為了篇幅,我只列出我選擇的選項而不是截圖

  • 項目名稱:nuxt-firebase-vuex-tutorial
  • 項目描述:(留空 - 默認為“我的優秀 Nuxt.js 項目”)
  • 作者姓名:德魯
  • 包管理器:NPM
  • UI 框架:Tailwind CSS
  • Nuxt.js 模塊:DotEnv(如果您想保護敏感密鑰的安全,則很有用)
  • Linting 工具:ESLint(用於乾淨的代碼格式)
  • 渲染模式:單頁應用 (SPA)

在設置時使用這些選項將為您節省一些時間並讓您更快地啟動和運行。能夠在一開始就選擇它們,而 Nuxt 只是為您處理設置只是 Nuxt 採取額外步驟讓您專注於您正在構建的內容的眾多方式之一。 (注意:有一些方法可以在他們的 CLI 之外設置 Nuxt,您可以更好地控製配置和使用的工具,但對於 MVP,這就足夠了 )。

您現在可以使用新的 Nuxt 應用了!

設置 Firebase

在我們進入一些代碼之前,我們需要為我們的應用程序設置一個 Firebase 帳戶,以便我們稍後使用。你必須登錄到一個活躍的谷歌帳戶,所以一定要設置一個@gmail.com 電子郵件,或者花點時間創建一個。

要開始訪問 firebase.google.com 並查看屏幕右上角。在語言下拉菜單的右側,您會看到藍色文本中的“轉到控制台”。點擊那個!您會看到下面看到的屏幕,您需要點擊“創建項目”。

以下屏幕將詢問您項目名稱以及您是否要啟用 Google Analytics。如果您選擇是 GA,第三個屏幕將詢問您要連接到哪個 Google 帳戶。

從那裡您將看到您的 Firebase 應用儀表板!在該儀表板中,您將看到下圖所示的此部分。很難錯過,因為它就在視線水平、前面和中心。對於我們的項目,我們需要一個網絡應用程序,因此我們將選擇第三個帶有“”的圓圈。

點擊之後,它會要求一個應用暱稱。

提供暱稱後,您將收到此提示,其中包含您要保留的重要信息。除了本教程之外,我的應用程序中沒有任何內容,但為了安全起見,我會保留我的內容(直到我忘記並稍後公開它們:D)

我們主要對 var firebaseConfig ={...}; 感興趣。 firebase.initializeApp(firebase.Config) 部分包含我們項目所需的不同 API 密鑰和 URL。您可以輕鬆地從項目儀表板中檢索這些內容,或者,如果您願意,可以將它們放入您選擇的文本編輯器中的臨時文件中。我們稍後會用到它們,所以請隨身攜帶。

在 Firebase 儀表板中我們還需要做一件事。在屏幕左側,單擊身份驗證鏈接,然後從那裡單擊右側的登錄方法選項卡。請務必啟用電子郵件和密碼,因為這是我們將使用的登錄方法。

現在我們已經準備好該部分,是時候進入我們的編輯器並在那裡進行一些設置了。我們將首先安裝 firebase 包,然後在我們的 Nuxt 應用程序中配置插件。我正在使用 VSCode,所以我在集成終端中工作。 (注意:確保您在 Nuxt 項目的正確目錄中 )。

npm install firebase --save //you can also use Yarn add firebase

如果您查看第一次運行 create-nuxt-app 時創建的 Nuxt 目錄,您會看到一個名為“plugins”的文件夾。在該文件夾中,創建一個名為 firebase.js 的文件 . (注意:你可以隨意命名文件,只要記住名字,因為我們稍後會引用它 )。

這是一些有趣的代碼開始發生的地方!在這個文件中,我們將做一些事情。我們將從之前安裝的包中導入 Firebase 和 Firebase auth,建立我們的 API 密鑰和其他配置,檢查 Firebase 的實例是否已經在運行——如果沒有,那麼我們的應用程序將創建一個,最後,我們將從我們的文件中導出 firebase 和 auth,以便我們以後可以使用它們。 (注意:這是您需要我們之前討論過的重要信息的地方。如果您忘記記下來,您可以輕鬆地從 Firebase 信息中心的項目設置中檢索它 )。
查看代碼

// ~/plugins/firebase.js

import * as firebase from 'firebase/app'
import 'firebase/auth'

// Your web app's Firebase configuration
var firebaseConfig = {
  apiKey: "Put your API here",
  authDomain: "your-project-name.firebaseapp.com",
  databaseURL: "https://your-project-name.firebaseio.com",
  projectId: "your-project-name",
  storageBucket: "your-project-name.appspot.com",
  messagingSenderId: "Put your messaging sender ID here",
  appId: "Put your app ID here"
};
// Initialize Firebase
!firebase.apps.length ? firebase.initializeApp(firebaseConfig) : ''

export const auth = firebase.auth()
export default firebase

接下來,跳轉到目錄根目錄中的 nuxt.config.js 文件以註冊 firebase 插件。

// ~/nuxt.config.js

/*
  ** Plugins to load before mounting the App
  */
  plugins: [
    '~/plugins/firebase.js',
  ],

現在你的基本 Nuxt/Firebase 配置已經設置好了,但是在我們繼續之前我們還有一個步驟來實現身份驗證。在這裡,我們將設置一些代碼,以幫助我們稍後使用 Vuex。

在您的 plugins 文件夾中,創建一個名為 fireauth.js 的文件(注意:同樣,您可以將其命名為任何名稱 - 只需確保稍後以正確的名稱引用它 )。

在這裡,我們將從 '~/plugins/firebase.js' 中導入 auth 模塊 我們之前創建的組件。之後,我們將編寫一個導出函數來做一些事情,但現在最重要的是設置 Firebase 提供的方法 'onAuthStateChanged'。

它的作用是監視用戶的身份驗證狀態並向 Firebase 發送更新。因此,當他們登錄時,它基本上會說“嘿,他們剛剛登錄。對他們進行身份驗證”,當他們註銷時,它會發送另一個更新,上面寫著“嘿,那個人離開了。刪除該身份驗證。”在我們的導出函數中,我們將返回一個新的 Promise 來處理一些邏輯——我們將把這個 Promise 設置為一個箭頭函數,並將參數“resolve”和“reject”傳遞給它。

// ~/plugins/fireauth.js

import { auth } from '~/plugins/firebase.js'

export default (context) => {
  const { store } = context

  return new Promise((resolve, reject) => {

  })
}

Promise 是任何值的佔位符,它在創建時可能不知道 - 所以你的 Promise 要么返回它需要的值並自行解決,要么出錯並拒絕。

在我們的 Promise 中,我們將調用從 Firebase 插件導入的 auth 函數,並為其提供“onAuthStateChanged”方法。我們也將其設置為箭頭函數,並將其傳遞給用戶參數。這是您的代碼將向 Firebase 發出請求的地方,如果一切設置正確,它將為傳遞的任何憑據返回一個用戶對象(在我們的例子中,我們將使用電子郵件和密碼 - 稍後)。

return new Promise((resolve, reject) => {
  auth.onAuthStateChanged(user => {

   // here is you would want to build your user
    // object, but for now, we'll just take everything

    store.commit('setUser', user)
    resolve()
  })
})

查看代碼

有一件事我們要提前一點,那就是繼續編寫一些我們的 Vuex 商店稍後將使用的代碼。

我們首先將參數 'context' 傳遞給導出函數,然後在該函數內部設置變量 const { store } =context .基本上,它所做的是能夠獲取一些稍後將通過這裡的數據並將其發送到 Vuex 存儲。為此,在我們的 'auth.onAuthStateChanged' 函數中,我們將使用一個名為 'setUser' 的函數提交返回到我們存儲的數據 - 我們將在稍後進行設置,並傳遞用戶參數也在那裡。在所有這些都說完之後,我們將 resolve() 我們的承諾。
查看代碼

// ~/plugins/fireauth.js

import { auth } from '~/plugins/firebase.js'

export default (context) => {
  const { store } = context

  return new Promise((resolve, reject) => {
    auth.onAuthStateChanged(user => {

      // here is you would want to build your user
      // object, but for now, we'll just take everything

      store.commit('setUser', user)
      resolve()
    })
  })
}

現在我們將跳回到我們的 nuxt.config.js 文件並導入 fireauth 插件。

// ~/nuxt.config.js

/*
  ** Plugins to load before mounting the App
  */
  plugins: [
    '~/plugins/firebase.js',
    '~/plugins/fireauth.js'
  ],

這有點囉嗦,但是我們希望圍繞 Firebase auth 和 Vuex 有很多活動的部分,並且至少有一個粗略的了解。

我想提一提的是 firebase.js 和 fireauth.js 如何協同工作。 Firebase.js 將 Firebase 引入我們的應用程序 - 它為我們導入的模塊之一是 Firebase 的身份驗證。 Fireauth.js 正在運行該身份驗證方法,登錄我們的用戶,然後在我們的 Vuex 存儲中設置用戶身份驗證狀態。因此,firebase 將所有部分都帶入其中,而 fireauth 正在監視我們的身份驗證狀態並將其存儲在 Vuex 中。

設置 Vuex

Nuxt 的另一個優點是它帶有 Vuex,因此沒有太多的配置。您所要做的就是將其導入正確的文件並開始編寫您需要它做的事情。

我們將首先在 Nuxt 為您創建的 /store 文件夾中創建一個 index.js 文件。在這個文件中,我們將 從 'vuex' 導入 Vuex , 從 '~/plugins/firebase.js' 導入 { auth } (是的,與我們在 fireauth.js 中使用的相同,但出於不同的原因),我們將創建變量 const createStore 並將其設置為箭頭函數。在箭頭函數內部,我們將 return new Vuex.Store({}) 它為我們創建了我們的 Vuex 存儲,最後我們將導出默認的 createStore。

// ~/store/index.js

import Vuex from 'vuex'
import { auth } from '~/plugins/firebase.js'

const createStore = () => {

}

export default createStore

在我們的 Vuex.store 中,我們將創建一些對象。我們將創建一個狀態對象,我們的登錄狀態將存在,一個 getters 對象將返回我們用戶的狀態,如果它找到一個它將設置 isAuthenticated,一個突變對象將保存我們的 setUser 突變(記住'setUser ' 來自我們的 fireauth.js?),以及一個操作對象,它將保存我們的用戶可以執行的操作(登錄/註冊/退出)。

// ~/store/index.js

import Vuex from 'vuex'
import { auth } from '~/plugins/firebase.js'

const createStore = () => {
  return new Vuex.Store({
    state: {

    },

    getters: {
      user() {

      },

      isAuthenticated() {

      }
    },

    mutations: {
      setUser() {

      }
    },

    actions: {
      signUp() {

      },

      signInWithEmail() {

      },

      signOut() {

      }
    }
  })
}

export default createStore

在這裡我們有我們的空對象,所以讓我們跳進去和他們一起創造一些魔法!

在我們的狀態對像中,我們只是想將用戶的狀態設置為一個空字符串,因此默認情況下始終有一個具有未經身份驗證狀態的空用戶。

// ~/store/index.js

state: {
  user: '',
},

在我們的 getter 中,我們有兩個函數,一個用戶函數和一個 isAuthenticated 函數。對於我們的用戶函數,我們希望將參數“狀態”傳遞給它,然後在函數內部 return state.user .這是在我們的狀態中檢索我們上面聲明的用戶對象。對於 isAuthenticated,我們再次希望傳遞 'state' 參數,但這次我們將檢查是否有用戶對象處於狀態並返回它 return !!state.user

// ~/store/index.js

getters: {
  user(state) {
    return state.user
  },

  isAuthenticated(state) {
    return !!state.user
  }
}

在我們的 mutation 對像中,我們將創建 setUser 函數,我們之前創建的 fireauth.js 使用該函數在用戶登錄時設置用戶。該函數將採用兩個參數,狀態和有效負載。在函數中,我們會說 state.user =payload .這樣做的目的是,當我們的用戶登錄並通過身份驗證時,它會獲取從 firebase 返回的所有數據,並將其放入我們在 Vuex 商店頂部創建的 state.user 中。

// ~/store/index.js

mutations: {
  setUser(state, payload) {
    state.user = payload
  }
}

最後,對於我們的操作對象,我們將創建三個函數,這些函數稍後將與我們的一些 UI 相關聯。

第一個是我們的 signUp 函數,它將接受兩個對像作為參數。我們將傳遞它 { commit } 和 { email, password }。提交是為了讓我們的 fireauth 獲得在 Vuex 存儲中設置狀態所需的內容,並且 email/password 會將用戶註冊的電子郵件和密碼傳遞給我們的 firebase 方法以進行登錄和身份驗證。所以,我們已經傳遞了兩個參數,然後在裡面我們將 return auth.createUserWithEmailAndPassword(email, password) .如果一切順利,這將創建一個用戶帳戶並登錄!

我們這裡的第二個函數是 signInWithEmail 函數。這與我們的 signUp 函數非常相似,但我們將使用 .signInWithEmailandPassword() 方法來代替。

// ~/store/index.js

actions: {
  signUp({ commit }, { email, password }) {
    return auth.createUserWithEmailAndPassword(email, password)
  },

  signInWithEmail({ commit }, { email, password }) {
    return auth.signInWithEmailAndPassword(email, password)
  },
}

我們的 signOut 函數稍微簡單一些,因為我們傳遞的數據不如我們清除它的多。在 signOut 函數中,我們將再次調用 auth,然後將 Firebase 中的 signOut 方法提供給它,例如“auth.signOut()”。從那裡開始,我們將使用 .then 和箭頭函數將 state.user 設置回 null(因為他們已經退出),使用 .then(() ={ commit('setUser', null})。

// ~/store/index.js

actions: {
  signUp({ commit }, { email, password }) {
    return auth.createUserWithEmailAndPassword(email, password)
  },

  signInWithEmail({ commit }, { email, password }) {
    return auth.signInWithEmailAndPassword(email, password)
  },

  signOut() {
    return auth.signOut()
  }
}

查看代碼

恭喜!您現在已經設置了 Nuxt 應用程序以使用 Firebase 和 Vuex。我們現在可以開始構建一個用戶界面以供用戶交互,所以我們開始吧!

構建用戶界面

現在我們將進入用戶將與之交互的應用程序的前端。

首先,我們將設置我們的標題組件,因為我們將在那裡放置指向我們頁面的鏈接,然後顯示一個登錄的用戶。因此,在您的組件文件夾中創建一個名為 Header.vue 的文件。

對於那些不知道的人,Vue 使用所謂的單文件組件 (SFC) 結構。在這些 SFC 中包含三個部分 - 您的模板、腳本和样式。讓我們繼續把它架起來。如果您正在使用 VScode,您可以從 sarah.drasner 安裝擴展 Vue VScode Snippets,然後鍵入 vbase,它將為您搭建一個空模板。您將有幾個使用 vbase 的選項 - default、ts 和 css。我總是使用 vbase-css。我們將在其中放置一個 H1,以便我們可以渲染一些東西。

<!-- ~/components/Header.vue -->

<template>
  <div>
    <h1>Hi, I'm the header.</h1>
  </div>
</template>

<script>
 export default {}
</script>

<style scoped>
</style>

在我們構建這個頭文件之前,讓我們跳到佈局文件夾中的 default.vue 文件,然後繼續將組件放置到位。

首先,我們要導入並註冊我們的組件。您的導入始終內部 您的腳本標籤,但 外部 您的導出默認值{} .所以,我們將 'import Header from "~/components/Header.vue"' 然後在我們的 export default ,我們將創建一個組件:{} 對象並在那裡註冊我們的 Header。

<!--  In the script tag of ~/layouts/default.vue -->

<script>
import Header from "~/components/Header.vue";

export default {
  components: {
    Header
  }
};
</script>

接下來,我們將跳轉到我們的模板並像這樣放置我們的組件。我們在這裡添加的另一件事是 div 包裝 Nuxt 組件,然後給它一個 mt-12 的 Tailwind 類 .這純粹是為了樣式/定位,不是必需的。
查看代碼

<!-- In the template tag~/layouts/default.vue -->

<template>
  <div>
    <Header />
    <div class="mt-12">
      <nuxt />
    </div>
  </div>
</template

如果我們運行 npm run dev 在我們的終端並跳轉到我們的瀏覽器,我們會看到我們的標頭已正確導入。

我們將整理一個粗略的標題,並且感謝我們之前設置的 Tailwind CSS,我們可以很容易地設置它的樣式。所以我們要做的是,在標題的父 div 內部,我們將創建另一個 div,在該 div 內部,我們將為我們的“徽標”放置一個 H1 和一個指向標誌的 nuxt-link -in 頁面(我們還沒有創建這個頁面 - 但它正在製作中)。

現在,您不必創建額外的 div - 我這樣做是因為我想要一個跨越瀏覽器整個寬度的陰影,但我希望我們的標題內容被限制在兩邊都有邊距的容器中。只是為了一些額外的樣式,我們將 class="py-2 shadow" 放在我們的父 div 上。這些由 Tailwind 提供,它們使快速輕鬆地構建這些 UI 變得非常容易。在我們的第二個 div 上,我們將在那裡拋出一個 class="container mx-auto flex justify-between"。容器設置該元素的最大寬度,mx-auto 設置 margin:0 auto,flex 設置 display:flex,justify-between 將兩個元素固定在標題的每一側。所以這就是我們的代碼的樣子。

<!-- ~/components/Header.vue -->

<template>
  <div class="py-2 shadow">
    <div class="container mx-auto flex justify-between">
      <h1 class="leading-tight font-bold text-green-500 text-2xl">RadAPP</h1>

      <nuxt-link to="/signin">Sign In</nuxt-link>
    </div>
  </div>
</template>

<script>
export default {}
</script>

<style scoped>
</style> 

如果我們跳轉到瀏覽器,我們會看到我們漂亮的標題組件!

如果您安裝了 vue 開發工具(我使用的是 Chrome 瀏覽器)並檢查我們的 vuex 商店,您會看到我們的 setUser 函數正在觸發,並且在底部,您會看到我們的用戶對象為 null 並且我們的isAuthenticated 設置為 false。到目前為止一切順利!

接下來,我們將跳回到我們的 index.vue 並構建我們的註冊表單。

由於時間和空間的原因,我們將把我們的註冊表單放在主頁上,所以跳轉到你的頁面目錄中的 index.vue,我們將把一個表單放在一起。在這種形式中,我們需要兩個輸入。一個用於電子郵件,一個用於密碼。我假設你有一些 HTML 知識,所以我不會分解關於下面表單的所有內容,你可以看到我的代碼。我繼續在那里扔了一些 Tailwind 課程,這樣我們就有了一些很好的工作。

<!-- ~/pages/index.vue -->

<template>
  <div class="p-6 w-1/5 container mx-auto shadow-md">
    <form>
      <h2 class="mb-2 text-xl text-green-500">Sign Up</h2>

      <div class="mb-4">
        <label class="block mb-2 text-gray-500" for="email">Email</label>
        <input class="border w-full px-2 py-1" type="text" id="email"/>
      </div>

      <div class="mb-4">
        <label class="block mb-2 text-gray-500" for="password">Password</label>
        <input class="border w-full px-2 py-1" type="password" id="password"/>
      </div>
    </form>
  </div>
</template>

所以這就是我們漂亮的表格的樣子!

要開始向我們的表單添加一些功能,我們首先要聲明我們要與之交互的兩條數據並將它們設置為 null。所以在我們的腳本標籤中,在我們的導出默認函數中,我們將在下面創建這個數據對象。

<!-- In the script tag of ~/pages/index.vue -->

<script>
export default {

  data: function() {
    return {
      email: "",
      password: ""
    };
  },
}
</script>

現在我們需要將表單輸入綁定到這個數據模型,幸運的是,Vue 讓這變得超級簡單。在它們各自的輸入上,放置 v-model="insert data-name"。它應該如下所示。

<!-- In the template tag of ~/pages/index.vue -->

<div class="mb-4">
  <label class="block mb-2 text-gray-500" for="email">Email</label>
  <input class="border w-full px-2 py-1" type="text" id="email"/>
</div>

<div class="mb-4">
  <label class="block mb-2 text-gray-500" for="password">Password</label>
  <input class="border w-full px-2 py-1" type="password" id="password"/>
</div>

我們的下一步是創建一個註冊方法,該方法將在填寫表單並單擊註冊按鈕時創建一個新用戶帳戶。我們將首先為我們的方法創建一個部分,在其中,我們將創建一個 userSignUp 函數。

<!-- In the script tag of ~/pages/index.vue -->

<script>
export default {

  data: function() {
    return {
      email: "",
      password: ""
    };
  },

  methods: {
    userSignUp: function() {

    }
  }
}
</script>

接下來,我們將使用我們在 vuex 存儲中創建的 signUp 函數並將電子郵件和密碼數據傳遞給它。我們通過調用 this.$store.dispatch() 來做到這一點 - 這基本上是說“查看 vuex 存儲並向我們發送我們要請求的任何函數。所以,在我們的 .dispatch() 調用中,我們將傳遞我們想要的 Vuex 函數的名稱,在這個情況,那就是 signUp .我們還需要傳遞電子郵件和密碼,我們通過使用 this.email 和 this.password 引用我們的數據對象來做到這一點。這告訴函數查看我們之前在 SFC 中聲明的數據,並使用這些名稱將它們傳遞給我們的 Vuex 函數。 (注意:我們將 err 傳遞給我們的函數,因此我們可以稍後引用它以進行一些錯誤處理 )

<!-- In the script tag of ~/pages/index.vue -->

<script>
export default {

  data: function() {
    return {
      email: "",
      password: ""
    };
  },

  methods: {
    userSignUp: function(err) {
      this.$store
        .dispatch('signUp', {
          email: this.mail,
          password: this.password
        })
    }
  }
}
</script>

從那裡我們將調用 .then 並編寫一個箭頭函數,將我們的電子郵件和密碼數據設置回 null。我們不想在用戶完成表單的用途後存儲他們提供給我們的信息,所以這只是保證他們數據安全的一點安全措施。

// In the script tag of ~/pages/index.vue

methods: {
  userSignUp: function(err) {
    this.$store
      .dispatch('signUp', {
        email: this.mail,
        password: this.password
      })
      .then(() => {
        this.email = "";
        this.password = "";
        //if you wanted to redirect after sign id you'd that here with this.$router.push('/pagename')
      })
  }
}

最後,我們將運行 .catch() 來處理任何錯誤,為了演示,我們將把它放入警報中。

// In the script tag of ~/pages/index.vue

methods: {
  userSignUp: function(err) {
    this.$store
      .dispatch('signUp', {
        email: this.mail,
        password: this.password
      })
      .then(() => {
        this.email = "";
        this.password = "";
        //if you wanted to redirect after sign id you'd that here with this.$router.push('/pagename')
      })
      .catch(err => {
        alert(err.message)
      })
  }
}

在我們完成這里之前,我們需要告訴表單提交後要做什麼。 Vue 使用 '@' 符號使事件處理變得超級簡單。所以在這裡我們要 @submit.prevent="userSignUp" .因此,我們將跳轉到開始的表單標籤並添加 @submit.prevent="userSignUp" (注意:.prevent 與函數中的 .preventDefault 相同)。

<!-- In the template of ~/pages/index.vue -->

<form @submit.prevent="userSignUp">

這是您的完整 index.vue 文件現在應該是什麼樣子。
查看代碼

<!-- ~/pages/index.vue -->

<template>
  <div class="p-6 w-1/5 container mx-auto shadow-md">
    <form @submit.prevent="userSignUp">
      <h2 class="mb-2 text-xl text-green-500 font-bold">Sign Up</h2>

      <div class="mb-4">
        <label class="block mb-2 text-gray-500" for="email">Email</label>
        <input class="border w-full px-2 py-1" type="text" id="email" v-model="email" />
      </div>

      <div class="mb-4">
        <label class="block mb-2 text-gray-500" for="password">Password</label>
        <input class="border w-full px-2 py-1" type="password" id="password" v-model="password" />
      </div>

      <button class="bg-green-500 text-white uppercase py-2 w-full shadow">Sign Up</button>
    </form>
  </div>
</template>

<script>
import Logo from "~/components/Logo.vue";

export default {
  components: {
    Logo
  },

  data: function() {
    return {
      email: "",
      password: ""
    };
  },

  methods: {
    userSignUp: function(err) {
      this.$store
        .dispatch("signUp", {
          email: this.email,
          password: this.password
        })
        .then(() => {
          this.email = "";
          this.password = "";
          //if you wanted to redirect after sign in you'd do that here with this.$router.push('/pagename')
        })
        .catch(err => {
          alert(err.message);
        });
    }
  }
};
</script>

成功!你可以使用你的 Vue 開發工具來檢查 Vuex 存儲,你會看到我們的 setUser 突變被再次調用,現在我們的狀態用戶在其中有一個對象,我們的 isAuthenticated 設置為 true。

我們可以檢查這是否有效的另一種方法是跳轉到我們的 Firebase 控制台並查看“身份驗證”選項卡。如果成功,您將看到您的第一個帳戶!

現在我們有了一個用戶帳戶,讓我們構建登錄和註銷功能,以便他們在我們的應用程序上進行交互。登錄與我們的註冊非常相似,所以讓我們先做一個。

在您的 pages 文件夾中,創建一個 signup.vue 文件。我們可以通過使用 v-base(如果您安裝了 vue 代碼片段)並複制我們剛剛從 index.vue 創建的表單來節省一點時間。由於我們的兩個表單使用相同的數據,您所要做的就是更改 up to in 的任何實例,就可以了。跳轉到您的瀏覽器並訪問 /signin 以驗證頁面是否正確呈現。

<!-- In the template of ~/pages/signin.vue -->

<template>
  <div class="p-6 w-1/5 container mx-auto shadow-md">
    <form @submit.prevent="userSignIn">
      <h2 class="mb-2 text-xl text-green-500 font-bold">Sign In</h2>

      <div class="mb-4">
        <label class="block mb-2 text-gray-500" for="email">Email</label>
        <input class="border w-full px-2 py-1" type="text" id="email" v-model="email" />
      </div>

      <div class="mb-4">
        <label class="block mb-2 text-gray-500" for="password">Password</label>
        <input class="border w-full px-2 py-1" type="password" id="password" v-model="password" />
      </div>

      <button class="bg-green-500 text-white uppercase py-2 w-full shadow">Sign In</button>
    </form>
  </div>
</template>

這個文件的很多內容與我們剛剛創建的文件非常相似,可以復製過來。這裡的區別是我們要求 'signInWithEmail' 在我們的 .dispatch() 調用中。(注意:打開導出默認{}函數後,請務必為您的 signin.vue 命名,如下所示)。

<!-- The script tag of ~/pages/signin.vue -->

<script>
export default {
  name: "signin",

  data: function() {
    return {
      email: "",
      password: ""
    };
  },

  methods: {
    userSignIn: function(err) {
      this.$store
        .dispatch("signInWithEmail", {
          email: this.email,
          password: this.password
        })
        .then(() => {
          this.email = "";
          this.password = "";
        })
        .catch(err => {
          alert(err.message);
        });
    }
  }
};
</script>

畢竟,您應該有一個正常運行的登錄頁面!這是您的代碼的外觀。

<!-- ~/pages/signin.vue -->

<template>
  <div class="p-6 w-1/5 container mx-auto shadow-md">
    <form @submit.prevent="userSignIn">
      <h2 class="mb-2 text-xl text-green-500 font-bold">Sign In</h2>

      <div class="mb-4">
        <label class="block mb-2 text-gray-500" for="email">Email</label>
        <input class="border w-full px-2 py-1" type="text" id="email" v-model="email" />
      </div>

      <div class="mb-4">
        <label class="block mb-2 text-gray-500" for="password">Password</label>
        <input class="border w-full px-2 py-1" type="password" id="password" v-model="password" />
      </div>

      <button class="bg-green-500 text-white uppercase py-2 w-full shadow">Sign In</button>
    </form>
  </div>
</template>

<script>
export default {
  name: "signin",

  data: function() {
    return {
      email: "",
      password: ""
    };
  },

  methods: {
    userSignIn: function(err) {
      this.$store
        .dispatch("signInWithEmail", {
          email: this.email,
          password: this.password
        })
        .then(() => {
          this.email = "";
          this.password = "";
        })
        .catch(err => {
          alert(err.message);
        });
    }
  }
};
</script>

查看代碼

我們的下一步是跳回我們的標題,這樣我們就可以構建我們的退出按鈕,這也將導致我們構建我們的用戶登錄顯示。

所以在我們的 Header.vue 組件中,我們將在這裡做的是將我們的登錄鏈接包裝在一個 div 中,並在該 div 中添加一個退出按鈕。我們在這裡將它們包裝在一個 div 中,因此我們之前在其父元素上添加的 tailwind flex 類將它們定位為一對。

當我們在這裡時,我們將繼續為我們的退出按鈕放置一些代碼。首先是一個讓我們的按鈕做出反應的點擊事件。 Vue 再次為我們簡化了這一切,所以我們所要做的就是把 @click="signOut" (記住你放在這裡的內容,因為我們稍後必須在文件中為函數命名相同的東西)。

為了對我們自己有點幻想,我們將在這裡添加一個 v-if 語句,以便我們的退出按鈕僅在有可能需要退出的用戶時呈現。我們將通過檢查我們的 vuex 存儲是否有用戶對象來做到這一點。所以在我們的按鈕上,我們將添加 v-if="$store.state.user" .這本身不起作用,我們必須在下面添加更多代碼才能使其工作。

<!-- Inside ~/components/Header.vue -->

<div>
  <nuxt-link to="/signin" class="opacity-50 hover:opacity-100">Sign In</nuxt-link>
  <button
    @click="signOut"
    class="pl-4 opacity-50 hover:opacity-100"
    v-if="$store.state.user"
  >Sign Out</button>
</div>

為了使 v-if 語句起作用,我們需要做一些事情。首先,我們需要從 Vuex 導入 mapGetters。你能猜到這是做什麼的嗎?調用時,它將映射到我們 Vuex 存儲中的所有 getter 並返回它們的數據。我們將獲取這些數據並使用計算屬性從中獲取我們需要的內容。在我們的計算對像中,我們將遍歷我們的 mapGetters 並將 user 設置為“user”。此時,我們的 v-if 語句應該可以工作了。

<!-- In the script tag of ~/components/Header.vue -->

<script>
import mapGetters from "vuex"

export default {
  computed: {
    ...mapGetters({
      user: "user"
    })
  }
}
</script>

之後,我們將要創建一個註銷方法(請記住使用您之前提供的 @click 事件相同的方法)。由於我們在這裡沒有處理任何數據,只是將其刪除,我們需要做的就是使用 this.$store.dispatch() 調用我們的 Vuex 存儲 並將其傳遞給“signOut”(或任何您命名的註銷函數)。我們將再次添加一個 .catch(err⇒ {alert(err.message)} 所以如果出現任何問題,我們可以看到它是什麼。

<!-- In the script tag of ~/components/Header.vue -->

<script>
import mapGetters from "vuex"

export default {
  computed: {
    ...mapGetters({
      user: "user"
    })
  },

  methods: {
    signOut: function(err) {
      this.$store.dispatch("signOut").catch(err => {
        alert(err.message);
      });
    }
  }
}
</script>

這是您的標頭代碼的外觀。 查看代碼

<!-- ~/components/Header.vue -->

<template>
  <div class="py-2 shadow">
    <div class="container mx-auto flex justify-between">
      <nuxt-link to="/" class="leading-tight font-bold text-green-500 text-2xl">RadAPP</nuxt-link>

      <div>
        <span v-if="$store.state.user">{{$store.state.user.email}}</span>
        <nuxt-link to="/signin" class="opacity-50 hover:opacity-100" v-else>Sign In</nuxt-link>
        <button
          @click="signOut"
          class="pl-4 opacity-50 hover:opacity-100"
          v-if="$store.state.user"
        >Sign Out</button>
      </div>
    </div>
  </div>
</template>

<script>
import { mapGetters } from "vuex";

export default {
  computed: {
    ...mapGetters({
      user: "user"
    })
  },

  methods: {
    signOut: function(err) {
      this.$store.dispatch("signOut").catch(err => {
        alert(err.message);
      });
    }
  }
};
</script>

所以!現在,您的退出按鈕應該根據您的用戶是否登錄來切換其可見性!恭喜!離世界霸主又近了一步……我的意思是,構建這個用戶帳戶界面!

構建帶有用戶登錄顯示的標題

我們旅程的最後一部分是在這裡顯示登錄用戶的電子郵件。一些網絡應用程序可能會顯示用戶名或頭像,但我們將在此處使用電子郵件。最重要的是,我們需要做的很多工作已經到位,所以不需要太多工作就可以實現!

我們在這裡要做的是在我們的登錄鏈接和我們用戶的電子郵件之間進行交換。我們這樣做是因為如果有人已經登錄,那麼他們不需要看到登錄頁面的鏈接。還記得我們之前使用的 v-if 嗎?我們將在這裡使用相同的技術。

由於我們已經在這個文件中發生了 mapGetters,我們所要做的就是根據我們的用戶設置一個 v-if v-else 條件。我們通過在 nuxt-link 上方創建一個 span 並使用相同的 v-if 來檢查用戶的 vuex 存儲。如果用戶登錄,我們希望顯示該電子郵件。該電子郵件是 Firebase 返回給我們的用戶對象的一部分,因此要訪問它,我們只需將 .email 添加到 v-if 條件中相同的 $store.state.user 語句的末尾。要完成此操作,您只需將 v-else 添加到我們的登錄 nuxt-link。

<!-- In the template tag of ~/components/Header.vue -->

<div>
  <span v-if="$store.state.user">{{$store.state.user.email}}</span>
  <nuxt-link to="/signin" class="opacity-50 hover:opacity-100" v-else>Sign In</nuxt-link>
  <button
    @click="signOut"
    class="pl-4 opacity-50 hover:opacity-100"
    v-if="$store.state.user"
  >Sign Out</button>
</div>

瞧!現在,您可以使用 Nuxt 和 Firebase 進行有效的登錄/註銷/註冊設置了!我想重申一下,可能還有更多可以添加的流程,如果您的應用程序有更多的部件和移動部件,這可能會更加複雜,但這是它的基本功能!

現在,用你的抱負去征服世界吧。

你可以在這裡查看源代碼..


Tutorial JavaScript 教程
  1. Vue - 使用 Axios 客戶端獲取 Github 存儲庫

  2. 為什麼不直接修改 React 狀態

  3. Metrics v3.0,拉皮條你的 GitHub 個人資料的終極工具!

  4. JavaScript 語法 (0, fn)(args)

  5. 使用 Jest 進行 Node.js 測試

  6. NextAuth.js 介紹 [1 of 3]:一鍵註冊

  7. 部署 JavaScript 應用程序的完整指南 - 第 2 部分:單頁應用程序、日誌記錄、SSL

  1. 對象解構 101

  2. DevSahaaya:面向 Javascript 開發人員的資源

  3. 在 React 中使用 useContext 鉤子

  4. 讓我們從頂部開始!

  5. 使用 Tailwind CSS 為 React 組件庫製作 NPM 包

  6. 如何使用 Node.js 和 SlackBots.js 構建 SlackBot

  7. 區分文件下載與頁面更改的 onbeforeunload

  1. 開始使用 Jamstack

  2. 使用 React 和 CSS 變量進行自定義夜間模式切換

  3. 按鈕渲染時表單事件觸發:Reacts 渲染過程中的一個討厭的陷阱

  4. Note App - 第 2 部分:React 站點