在Vue.js和Firebase应用程序中管理用户状态
在这篇文章中,我们将讨论如何使用Vuex 4和Vue 3.0中的Composition API来建立一个状态管理系统,用Firebase Auth来验证用户。
这些组件将帮助我们拥有一个全局状态,我们可以从Vue.js应用程序的任何地方访问。
先决条件
要跟上,你需要。
- 对Vue.js和Composition API有一个基本的了解。
- 熟悉Firebase第9版。
- 在你的本地机器上安装Node.js。
- 一个网络浏览器。
目标
- 使用Vuex 4和Composition API。
- 在Vue.js应用程序中管理用户状态。
- 在Vue.js中整合Firebase。
入门
要创建一个Vue.js应用程序,你需要有Vue CLI。要安装它,请在你的终端运行以下命令。
npm install -g @vue/cli
安装完成后,继续用下面的命令创建一个Vue应用程序。
vue create firebase-vue-user-management
在这个屏幕上,选择Vue 3 。

最后在这个屏幕上选择Use NPM 。

上述配置将创建一个以npm为包管理器的Vue 3应用程序。
现在,运行以下命令来安装我们将在项目中使用的依赖项。
npm install vue-router@4
npm install vuex@next --save
- vue-router@4 - 要在Vue应用程序中设置路由。
- vuex@next - 用于状态管理。
设置Firebase Auth
要创建一个新的Firebase项目,请在顶部导航栏中选择Go to console 。
在这里,点击Add new project ,将项目命名为vue-firebase-auth 。

你会被重定向到项目的仪表板。在仪表板上,点击网络图标来注册你的前端应用程序。

将你的应用程序命名为vuex-firebase-authentication ,并点击Register app 。
复制Firebase提供的配置,然后点击Continue to console 。
回到仪表板上,点击左侧边栏的Authentication 。

最后,启用Email/Password 和save 。
将Firebase添加到Vue.js应用程序中
打开终端,输入以下命令来安装Firebase。
npm install firebase
安装完成后,在src 文件夹中创建一个新的文件夹,命名为firebase 。
在这个文件夹中,创建一个config.js 文件。用以下代码修改该文件。
//Import the required methods
import { initializeApp } from 'firebase/app'
import { getAuth } from 'firebase/auth'
//The config we copied from firebase(Replace with your config)
const firebaseConfig = {
apiKey: "",
authDomain: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: ""
};
//initialize the firebase app
initializeApp(firebaseConfig)
//initialize firebase auth
const auth = getAuth()
//export the auth object
export { auth }
在上面的代码中,我们已经。
-
从Firebase导入了所需的函数。我们将使用
initializaApp()来创建一个Firebase应用实例,使用getAuth()来创建一个Firebase Auth对象。 -
我们还使用了Firebase平台的配置文件,然后调用了
initializeApp()方法,并将firebaseConfig作为参数传入。 -
最后,我们使用
getAuth()方法创建了一个auth对象。
创建一个商店
我们现在需要创建一个全局存储来帮助进行状态管理。这将使我们能够从任何组件中访问和改变用户的状态。
要做到这一点,在src 目录下创建一个文件夹store 。在这个store 文件夹中,创建一个index.js 文件并粘贴以下代码。
import { createStore } from 'vuex'
//Firebase imports
import { auth } from '../firebase/config'
import {
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut
} from 'firebase/auth'
const store = createStore({
state: {
//The user state will initially be null. After login, this state will be updated
user: null
},
mutations: {
//Mutation to update the user state
//Takes in two arguments, the state and the payload. When we call this mutation, the payload will be user object from firebase auth
//When the user logs out, we call the mutation and the payload will be null
setUser(state, payload) {
state.user = payload
//Log out the user state
console.log(state.user)
}
},
actions: {
async signup(context, { email, password }){
const response = await createUserWithEmailAndPassword(auth, email, password)
if (response) {
context.commit('setUser', response.user)
} else {
throw new Error('signup failed')
}
},
async login(context, { email, password }){
const response = await signInWithEmailAndPassword(auth, email, password)
if (response) {
context.commit('setUser', response.user)
} else {
throw new Error('login failed')
}
},
async logout(context){
await signOut(auth)
context.commit('setUser', null)
}
}
})
// export the store
export default store
在上面的代码中,我们有。
-
从
vuex中导入createStore(),这将我们创建一个全局存储。 -
从Firebase文件夹中导入了
auth对象。 -
导入了3个方法。
createUserWithEmailAndPassword()帮助创建一个带有电子邮件和密码的用户账户。signInWithEmailAndPassword()允许用户用电子邮件和密码登录。signOut()注销一个用户。
我们还使用createStore() 方法创建了一个全局存储,并传入一个包含state 、mutations 和actions 的对象。
state mutations 用于突变/更新 。 提交 ,然后更新 。state actions mutations state
在state 里面,我们有user 状态,最初是空的。当用户登录时,这部分状态将被更新。
setUser() 突变是用来更新user 状态的。它接收两个参数,state 和payload 。这个突变在每次用户登录、注册或注销时都会提交。
当用户注册或登录时,payload 将是Firebase发回的用户对象,作为一个响应。当用户签出时,有效载荷将为空。
还有三个动作将从不同的页面被派发。
signup()动作接收了email 和password ,这两个数据将从派发动作的页面中传递出来。
这个动作使用signInWithEmailAndPassword() 方法向Firebase发送一个请求,并将auth,email, 和password 作为参数进行解析。
Firebase以对象的形式发回一个响应,它被存储在constresponse 。
如果有来自Firebase的响应,setUser() 的突变被提交,response.user 作为有效载荷被传递。否则就会抛出一个错误。
login()动作使用的逻辑与signup() 动作相同。
logout()动作使用signOut() 方法,该方法接收auth 对象作为唯一参数。然后,它提交了setUser() 突变,并将null 作为有效载荷。
创建页面
我们将用Tailwind CSS来设计我们的项目。要了解你如何用Vue设置Tailwind,请点击这里。
在你用Vue.js设置了Tailwind之后,你可能会遇到这样的错误:Error: PostCSS plugin tailwindcss requires PostCSS 8 。为了纠正这个错误,请运行这些命令。
npm uninstall tailwindcss postcss autoprefixer
npm install tailwindcss@npm:@tailwindcss/postcss7-compat @tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9
npm run serve
现在,在src/components 文件夹中,创建一个名为Navbar.vue 的文件,并粘贴以下代码。
<template>
<nav class="flex items-center justify-between">
<h1 class="text-2xl">Firebase Vuex Auth</h1>
<!-- for all users -->
<div class="">
<router-link to="/">Home</router-link>
</div>
<!-- for logged in users -->
<div class="flex space-x-4">
<button>Logout</button>
</div>
<!-- for logged out users -->
<div class="flex space-x-4">
<router-link to="/login">Login</router-link>
<router-link to="/signup">Signup</router-link>
</div>
</nav>
</template>
<script>
export default {
}
</script>
在上面的代码中,我们已经创建了一个基本的导航栏,以Firebase Vuex Auth 作为主要文本。它还包含了不同的文本,供用户根据其登录状态查看。
我们还使用router-link 将这些按钮链接到相应的页面。
接下来,在src 文件夹中,创建一个views 文件夹。在这个目录中,我们将创建以下页面。
Home.vue- 这将是主页。Login.vue- 这将有一个登录页面。Signup.vue- 这将有一个注册页面。
打开Home.vue 页面并粘贴以下代码。
<template>
<div class="mt-4">
<div v-for="blog in blogs" :key="blog.id">
<div class="mt-4 mb-4">
<h3 class="text-xl underline">{{ blog.title }}</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Pariatur aspernatur consectetur doloremque sunt ducimus enim iure animi fugit nulla et! Perferendis autem deleniti quo eum corrupti reiciendis voluptatem ab ducimus?</p>
</div>
</div>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const blogs = ref([
{ title: 'What is programming?', id: 1 },
{ title: 'What is JS?', id: 2 },
{ title: 'What is Python?', id: 3 },
])
return {
blogs
}
}
}
</script>
代码解释。
在上面的代码中,我们使用了Vue的setup()钩子,并创建了一个blogs 数组,其中包含3个对象:title 和id 。
然后我们通过blogs 数组在template 部分进行映射,并使用blog.id 作为键。
接下来,打开Login.vue 文件并粘贴以下代码。
<template>
<form @submit.prevent="handleSubmit" class="mt-4 flex flex-col">
<h3 class="text-xl underline">Login</h3>
<label for="email">Email:</label>
<input class="border w-4/12" type="email" name="email" v-model="email" required>
<label for="email">Password:</label>
<input class="border w-4/12" type="password" name="password" v-model="password" required>
<button class="w-max mt-4 px-4 py-2 text-center rounded-full bg-blue-500 text-white">Login</button>
<div v-if="error">{{ error }}</div>
</form>
</template>
<script>
import { ref } from 'vue'
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'
export default {
setup() {
const email = ref('')
const password = ref('')
const error = ref(null)
const store = useStore()
const router = useRouter()
const handleSubmit = async () => {
try {
await store.dispatch('login', {
email: email.value,
password: password.value
})
router.push('/')
}
catch (err) {
error.value = err.message
}
}
return { handleSubmit, email, password, error }
}
}
</script>
在上面的代码中,我们已经创建了一个有两个输入字段(电子邮件和密码字段)的登录表单,一个提交按钮和一个div ,如果有错误,就显示错误。
在setup() 钩子中,我们有一个异步的handleSubmit 函数,从商店中调度login 动作。
当调度这个动作时,email 和password 被作为参数传入。
当登录尝试成功时,用户会被重定向到主页上。如果遇到错误,表格上会显示错误信息。
最后,打开Signup.vue 文件并粘贴以下代码。
<template>
<form @submit.prevent="handleSubmit" class="mt-4 flex flex-col">
<h3 class="text-xl underline">Sign up</h3>
<label for="email">Email:</label>
<input class="border w-4/12" type="email" name="email" v-model="email" required>
<label for="email">Password:</label>
<input class="border w-4/12" type="password" name="password" v-model="password" required>
<button class="w-max mt-4 px-4 py-2 text-center rounded-full bg-blue-500 text-white">Sign up</button>
<div v-if="error">{{ error }}</div>
</form>
</template>
<script>
import { ref } from 'vue'
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'
export default {
setup() {
const email = ref('')
const password = ref('')
const error = ref(null)
const store = useStore()
const router = useRouter()
const handleSubmit = async () => {
try {
await store.dispatch('signup', {
email: email.value,
password: password.value
})
router.push('/')
}
catch (err) {
error.value = err.message
}
}
return { handleSubmit, email, password, error }
}
}
</script>
上述代码使用的逻辑与Login.vue 页面相同。
设置路由
在src 文件夹中,创建一个名为router 的文件夹。在这个文件夹中,创建一个index.js 文件并粘贴以下代码。
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import Signup from '../views/Signup.vue'
import Login from '../views/Login.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/signup',
name: 'Signup',
component: Signup
},
{
path: '/login',
name: 'Login',
component: Login
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
代码解释。
在上面的代码中,我们已经导入了所有的views 。然后我们创建了一个routes 数组,其中包含3个对象。
这些对象有路径和相应的组件,以便在访问该路径时呈现。然后我们使用createRouter() 方法创建我们的路由器。
配置Vue应用程序以使用路由器和商店
为了实现这一点,打开main.js 文件,用下面的代码替换现有的代码。
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import './index.css'
// import store
import store from './store/index'
createApp(App).use(router).use(store).mount('#app')
最后,打开App.vue 文件,用下面的代码替换现有的代码。
<template>
<div class="w-4/5 mx-auto mt-4">
<Navbar />
<router-view/>
</div>
</template>
<script>
import Navbar from './components/Navbar'
export default {
components: {Navbar}
}
</script>
测试应用程序
运行下面的代码,启动一个本地开发服务器。
npm run serve
在你的浏览器上进入localhost:8080 ,你会看到这个屏幕。

从这里你可以测试登录和注册的动作。
总结
在这篇文章中,我们讨论了如何在Firebase、Vue.js应用程序中实现认证。
然而,这个项目还可以进一步改进。例如,你可以添加更多的登录选项和添加自定义错误信息。