Vue、Google firestore、およびGoogle認証とシンプルなtodoアプリ
63091 ワード
導入
私は、最速の最も簡単な意味のプロジェクトを行うことによってプログラミング言語を学ぶ.実際のプロジェクトを行うことで、デザインから利益を得ることができますし、プロジェクトを最初から最後まで管理します.この記事では、我々はアプリケーションを使用してビルドを学ぶVue VUEアプリケーションの状態管理Vuex
この記事では次のことを学びます
ソースコード
からの完全なソースを見つけることができますGitHub
前提条件
npm install -g @vue/cli
プロジェクト作成
あなたのマシンにインストールされているVueコマンドラインインターフェイス(CLI)を確認してください.VUE CLIを以下のコマンドを実行してインストールできます
ToDoアプリケーションプロジェクトを作成する
vue create todo-app
上記のコマンドは新しいVueプロジェクトを名前で作成しますtodo-app
ディレクトリを新しいプロジェクトに変更
cd todo-app
インストール
npm install vuex --save
Vueブートストラップのインストール
npm install bootstrap bootstrap-vue --save
Firebaseをインストールする
npm install firebase --save
コンパイルとホットリロードの開発
npm run serve
生産のためのコンパイルとミニフィケーション
npm run build
ファイルとフィックスファイル
npm run lint
カスタマイズ設定
参照Configuration Reference .
VSコードでプロジェクトを開きます
VSコードでプロジェクトを開きます
code .
Vue CLIによって生成されたデフォルトのファイル構造が表示されます
HelloWorldを削除します.Vueコンポーネント今すぐ.後でコンポーネントを追加します.
組み合わせコードキー( Ctrl + JまたはCMD + J )を押してVSコードで端末を開きます.
firebaseを作成します。js
Firebaseは認証とデータベースイベント( CRUD )を提供します.
FireBaseプロジェクトを既に構成していることを確認してくださいGoogle Firebase
新しい名前を作成するfirebase.js
の下にsrc
ディレクトリ
次のコードをファイルにコピーします
import firebase from 'firebase';
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
// Add your firebase config here
};
const firebaseapp = firebase.initializeApp(firebaseConfig);
// database
const db = firebaseapp.firestore();
// authentication
const auth = firebase.auth();
const provider = new firebase.auth.GoogleAuthProvider();
export { auth, provider };
export default db;
設定を変更してくださいfirebaseConfig
あなたと
ステート管理用のオブジェクトを作成する
ソースディレクトリ(src)ディレクトリの下にあるすべての州を持ちたい.
次に、srcフォルダの下にあるストアという名前のフォルダを作成します.
ユーザー状態を作成する
ユーザーの状態をGoogle Firebaseを使用してサインアウトユーザーを管理する.これは、署名されたユーザーを制御したり、署名した.とユーザーインターフェイスは、ユーザーのステータスに基づいて更新されます.
新しいJavaScriptファイルを作成するuser.js
ストアディレクトリの下で.
次のコードをファイルにコピーします
const state = {
user: null
};
const getters = {
user: state => state.user
};
const actions = {
signIn ({commit}, user) {
commit('signIn', user);
},
signOut({commit}) {
commit('signOut');
}
};
const mutations = {
signIn: (state, user) => {
state.user = user;
},
signOut: state => state.user = null
};
export default {
state,
getters,
actions,
mutations
};
を作成する
ToDoリストとToDo項目を管理する状態をtodos.の状態を制御します
vue create todo-app
cd todo-app
npm install vuex --save
npm install bootstrap bootstrap-vue --save
npm install firebase --save
npm run serve
npm run build
npm run lint
VSコードでプロジェクトを開きます
code .
Vue CLIによって生成されたデフォルトのファイル構造が表示されますHelloWorldを削除します.Vueコンポーネント今すぐ.後でコンポーネントを追加します.
組み合わせコードキー( Ctrl + JまたはCMD + J )を押してVSコードで端末を開きます.
firebaseを作成します。js
Firebaseは認証とデータベースイベント( CRUD )を提供します.
FireBaseプロジェクトを既に構成していることを確認してくださいGoogle Firebase
新しい名前を作成するfirebase.js
の下にsrc
ディレクトリ
次のコードをファイルにコピーします
import firebase from 'firebase';
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
// Add your firebase config here
};
const firebaseapp = firebase.initializeApp(firebaseConfig);
// database
const db = firebaseapp.firestore();
// authentication
const auth = firebase.auth();
const provider = new firebase.auth.GoogleAuthProvider();
export { auth, provider };
export default db;
設定を変更してくださいfirebaseConfig
あなたと
ステート管理用のオブジェクトを作成する
ソースディレクトリ(src)ディレクトリの下にあるすべての州を持ちたい.
次に、srcフォルダの下にあるストアという名前のフォルダを作成します.
ユーザー状態を作成する
ユーザーの状態をGoogle Firebaseを使用してサインアウトユーザーを管理する.これは、署名されたユーザーを制御したり、署名した.とユーザーインターフェイスは、ユーザーのステータスに基づいて更新されます.
新しいJavaScriptファイルを作成するuser.js
ストアディレクトリの下で.
次のコードをファイルにコピーします
const state = {
user: null
};
const getters = {
user: state => state.user
};
const actions = {
signIn ({commit}, user) {
commit('signIn', user);
},
signOut({commit}) {
commit('signOut');
}
};
const mutations = {
signIn: (state, user) => {
state.user = user;
},
signOut: state => state.user = null
};
export default {
state,
getters,
actions,
mutations
};
を作成する
ToDoリストとToDo項目を管理する状態をtodos.の状態を制御します
import firebase from 'firebase';
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
// Add your firebase config here
};
const firebaseapp = firebase.initializeApp(firebaseConfig);
// database
const db = firebaseapp.firestore();
// authentication
const auth = firebase.auth();
const provider = new firebase.auth.GoogleAuthProvider();
export { auth, provider };
export default db;
ソースディレクトリ(src)ディレクトリの下にあるすべての州を持ちたい.
次に、srcフォルダの下にあるストアという名前のフォルダを作成します.
ユーザー状態を作成する
ユーザーの状態をGoogle Firebaseを使用してサインアウトユーザーを管理する.これは、署名されたユーザーを制御したり、署名した.とユーザーインターフェイスは、ユーザーのステータスに基づいて更新されます.
新しいJavaScriptファイルを作成する
user.js
ストアディレクトリの下で.次のコードをファイルにコピーします
const state = {
user: null
};
const getters = {
user: state => state.user
};
const actions = {
signIn ({commit}, user) {
commit('signIn', user);
},
signOut({commit}) {
commit('signOut');
}
};
const mutations = {
signIn: (state, user) => {
state.user = user;
},
signOut: state => state.user = null
};
export default {
state,
getters,
actions,
mutations
};
を作成する
ToDoリストとToDo項目を管理する状態をtodos.の状態を制御します
todos.js
ストアディレクトリの下で.次のコードをファイルにコピーします
import db from '../firebase'
// State declaration
const state = {
/**
* each todo item will have the format
* {
* id: String,
* title: String,
* completed: Boolean
* }
*/
todos: []
};
// Getters
const getters = {
// Get all todo items in the current state
allTodos: state => state.todos
};
// actions
const actions = {
/**
* Loading todos
* This is fetch data from database
*/
fetchTodos ({commit}, user) {
db.collection('user')
.doc(user.uid)
.collection('todos')
.onSnapshot(snapshot => {
commit('setTodos', snapshot.docs.map(doc => {
return {
id: doc.id,
doc: doc.data()
}
}));
})
},
/**
* Add a new todo action
* This is fired when the user submit the form add a new todo
* @param {String} payload - The title string of the the new todo
*/
addTodo({ commit}, payload) {
const uid = payload.user.uid;
const title = payload.title;
const newtodo = {
title,
completed: false
};
db.collection('user')
.doc(uid)
.collection('todos')
.add(newtodo)
.then(docRef => {
commit('addTodo', {
id: docRef.id,
data: newtodo
});
})
},
/**
* Update the status of the todo item in the state
* @param {Object} payload - The object contains
* - the id to identify the todo item in the collection list
* - completed property to update the status of the todo item
*/
toggleCompleted ({commit}, payload) {
const uid = payload.user.uid;
const id = payload.id;
const completed = payload.completed;
db.collection('user')
.doc(uid)
.collection('todos')
.doc(id)
.update({
completed: completed
})
commit('toggleCompleted', {
id,
completed
});
},
/**
*
* @param {*} param0
* @param {Number} payload - The number id to identify the todo item in the collection
*/
deleteTodo ({commit}, payload) {
const uid = payload.user.uid;
const id = payload.id;
db.collection('user')
.doc(uid)
.collection('todos')
.doc(id)
.delete();
commit('deleteTodo', id);
}
};
// mutations
const mutations = {
setTodos: (state, todos) => {
state.todos = todos.map(todo => {
return {
id: todo.id,
title: todo.doc.title,
completed: todo.doc.completed
}
});
},
addTodo: (state, {id, data}) => {
console.log('addTodo');
const newtodo = {
id,
title: data.title,
completed: data.completed
};
const oldTodos = [...state.todos];
const index = oldTodos.findIndex(todo => todo.id === id);
// adding new todo the list
if (index < 0) {
state.todos.unshift(newtodo); // = [newtodo, ...state.todos];
}
console.log(state.todos);
},
toggleCompleted: (state, {id, completed}) => {
const index = state.todos.findIndex((todo) => todo.id === id);
if (index >= 0) {
state.todos[index].completed = completed;
}
},
deleteTodo: (state, id) => {
const index = state.todos.findIndex((todo) => todo.id === id);
if (index >= 0) {
state.todos.splice(index, 1);
}
}
};
export default {
state,
getters,
actions,
mutations
};
クリエイトブイ
現在、我々は両方のために州を持ちますuser
and todos
, 私たちは店のコレクションにそれらを使用したい
新しいファイルを作成するstore.js
の下にsrc
フォルダ.
次のコードをファイルにコピーします
// Create a store
import Vue from 'vue'
import Vuex from 'vuex'
import todos from './todos';
import user from './user';
Vue.use(Vuex);
// create store
export default new Vuex.Store({
modules: {
todos,
user
}
});
プロジェクトへのストアの追加
開けるmain.js
我々のアプリケーションにストアを追加します.
また、ここで我々のアプリケーションにブートストラップを追加します
import Vue from 'vue'
import App from './App.vue'
// Import store
import store from './store/store'
// Bootstrap
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
// import bootstrap and BootstrapVue css
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.use(BootstrapVue);
Vue.use(IconsPlugin);
Vue.config.productionTip = false;
new Vue({
render: h => h(App),
store
}).$mount('#app')
コンポーネントの作成
現在、我々はすべてのセットアップを持っています.アプリケーションのコンポーネントを作成します.我々のアプリケーションは、次のコンポーネントがあります
// Create a store
import Vue from 'vue'
import Vuex from 'vuex'
import todos from './todos';
import user from './user';
Vue.use(Vuex);
// create store
export default new Vuex.Store({
modules: {
todos,
user
}
});
開ける
main.js
我々のアプリケーションにストアを追加します.また、ここで我々のアプリケーションにブートストラップを追加します
import Vue from 'vue'
import App from './App.vue'
// Import store
import store from './store/store'
// Bootstrap
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
// import bootstrap and BootstrapVue css
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.use(BootstrapVue);
Vue.use(IconsPlugin);
Vue.config.productionTip = false;
new Vue({
render: h => h(App),
store
}).$mount('#app')
コンポーネントの作成
現在、我々はすべてのセットアップを持っています.アプリケーションのコンポーネントを作成します.我々のアプリケーションは、次のコンポーネントがあります
Login
コンポーネント-ログインするユーザーを表示するか、またはログアウトしましたNewTodo
コンポーネント-新しいToDo項目を追加するフォームコンポーネントですTodoList
コンポーネント-それぞれのToDo項目を表示するリストビューですTodoItem
コンポーネント-これは表示されるToDo項目ですログインコンポーネント
新しいファイルを作る
Login.vue
コンポーネントフォルダの下に.ファイルに次のスクリプトをコピーします<template>
<div class="login">
<div @click="logout" v-if="user" class="logout">
<b-avatar variant="info" :src="imageSrc" class="mr-3"></b-avatar>
<span class="mr-auto">{{user.user.displayName}}</span>
</div>
<b-button v-else variant="primary" @click="login">Sign In</b-button>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex';
import { auth, provider } from '../firebase'
export default {
name: 'Login',
data() {
return {
imageSrc: ''
};
},
computed: mapGetters(['user']),
methods: {
...mapActions(['signIn', 'signOut']),
login() {
auth
.signInWithPopup(provider)
.then(authUser => {
this.imageSrc = authUser.user.photoURL;
this.signIn(authUser);
})
.catch(error => alert(error.message))
},
logout() {
this.signOut();
}
}
}
</script>
<style>
.login {
text-align: center;
}
.logout {
cursor: pointer;
}
</style>
コンポーネントの作成
新しいファイルを作る
NewTodo.vue
コンポーネントフォルダの下に.ファイルに次のスクリプトをコピーします<template>
<b-form @submit="AddNewTodo">
<b-form-group
label="Add new todo"
label-for="newTodo"
>
<b-form-input
id="newTodo"
placeholder="What needs to be done"
v-model="todo"
required
>
</b-form-input>
</b-form-group>
<b-button type="submit" variant="primary">Add New Todo</b-button>
</b-form>
</template>
<script>
// import actions
import { mapGetters, mapActions } from 'vuex'
export default {
name: "NewTodo",
data() {
return {
// data for binding to the input text
todo: ''
}
},
computed: mapGetters(['user']),
methods: {
...mapActions(['addTodo']),
/**
* Form submit hanlder
*/
AddNewTodo (event) {
event.preventDefault();
if (this.todo && this.todo !== "") {
// update data base
this.addTodo({
user: this.user.user,
title: this.todo
})
// clear todo
this.todo = "";
}
}
}
}
</script>
<style>
</style>
コンポーネントを作成する
新しいファイルを作る
TodoItem.vue
コンポーネントフォルダの下に.ファイルに次のスクリプトをコピーします.TodoItem
は親から3つのプロパティをとるTodoList
)<template>
<b-form>
<b-row>
<b-col cols="11">
<b-form-checkbox switch size="lg" :checked="completed"
@change="toggleComplete">
<label :class="{complete: completed}">{{title}}</label>
</b-form-checkbox>
</b-col>
<b-col cols="1">
<b-icon icon="trash" class="hover-trash" @click="removeTodo"></b-icon>
</b-col>
</b-row>
</b-form>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default {
name: 'TodoItem',
props: {
id: String, // The todo item key
title: String, // The title description of the todo item
completed: Boolean // indicating if the todo item has been completed
},
computed: mapGetters(['user']),
methods: {
...mapActions(['toggleCompleted', 'deleteTodo']),
toggleComplete () {
// change the status of the todo item
this.toggleCompleted({
user: this.user.user,
id: this.id,
completed: !this.completed
})
},
removeTodo () {
// delete the todo from the state collection
this.deleteTodo({
user: this.user.user,
id: this.id
});
}
}
}
</script>
<style scoped>
.complete {
text-decoration: line-through;
}
.hover-trash:hover {
color: red;
}
.row {
border-bottom: 1px solid gray;
}
</style>
コンポーネントの作成
新しいファイルを作る
TodoList.vue
コンポーネントフォルダの下に.ファイルに次のスクリプトをコピーします<template>
<b-container fluid class="ml-3">
<h1>Todo list goes here</h1>
<ul>
<li v-for="todo in allTodos" :key="todo.id">
<todo-item :title="todo.title" :completed="todo.completed" :id="todo.id" ></todo-item>
</li>
</ul>
</b-container>
</template>
<script>
import TodoItem from './TodoItem.vue'
// vuex actions and getters
import { mapGetters, mapActions } from 'vuex';
export default {
name: 'TodoList',
components: {
TodoItem
},
computed: mapGetters(['allTodos', 'user']),
methods: {
...mapActions(['fetchTodos'])
},
created() {
this.fetchTodos(this.user.user);
}
}
</script>
<style scoped>
ul li {
list-style: none;
}
</style>
コンポーネントへのコンポーネントの追加
開けるApp.vue
そして次のようにコードを更新します
<template>
<div class="mt-5">
<img alt="Vue logo" src="./assets/logo.png">
<login></login>
<div v-if="user">
<b-container>
<new-todo></new-todo>
</b-container>
<todo-list></todo-list>
</div>
</div>
</template>
<script>
import NewTodo from './components/NewTodo.vue'
import TodoList from './components/TodoList.vue'
import { mapGetters } from 'vuex'
import Login from './components/Login.vue'
export default {
name: 'App',
computed: mapGetters(['user']),
components: {
NewTodo,
TodoList,
Login
}
}
</script>
<style>
* {
margin: 0;
padding: 0;
}
img {
display: block;
margin-left: auto;
margin-right: auto;
}
</style>
ビルドと配備
今、我々はすべてのコンポーネントを完了し、ローカルアプリケーションをテストしている.ビルドとアプリケーションの配備のための時間です.
アプリケーションのビルド
npm run build
このコマンドはアプリケーションをコンパイルし、フォルダの下にあるすべてのファイルを生成しますdist
. これは、Googleクラウドのホストに展開されるフォルダです.
配備する
あなたが持っていることを確認してくださいfirebase-tools
グローバルにインストール
npm install -g firebase-tools
今ログインする必要があります
firebase login
ファイアウォールプロジェクト
firebase init
ホスティングオプションを選択します.
尋ねるpublic directory
, 種類dist
ときに1つのページのアプリを入力すると、' Y '
種類N
Github Automationビルドを要求する場合.
種類N
上書きを求められた場合index.html
. 我々は、我々のファイルを保ちたいです
次に、ホスティングプロジェクトを選択すると、既存のいずれかを選択することができます既に作成したり、新しいものを作成します.
プロジェクトの配備
firebase deploy
おめでとう!最初から最後までToDoアプリケーションを構築し、正常にアプリケーションを配備できます.
Reference
この問題について(Vue、Google firestore、およびGoogle認証とシンプルなtodoアプリ), 我々は、より多くの情報をここで見つけました
https://dev.to/thangdc1982/simple-todo-app-with-vue-google-firestore-and-google-authentication-4005
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
<template>
<div class="mt-5">
<img alt="Vue logo" src="./assets/logo.png">
<login></login>
<div v-if="user">
<b-container>
<new-todo></new-todo>
</b-container>
<todo-list></todo-list>
</div>
</div>
</template>
<script>
import NewTodo from './components/NewTodo.vue'
import TodoList from './components/TodoList.vue'
import { mapGetters } from 'vuex'
import Login from './components/Login.vue'
export default {
name: 'App',
computed: mapGetters(['user']),
components: {
NewTodo,
TodoList,
Login
}
}
</script>
<style>
* {
margin: 0;
padding: 0;
}
img {
display: block;
margin-left: auto;
margin-right: auto;
}
</style>
今、我々はすべてのコンポーネントを完了し、ローカルアプリケーションをテストしている.ビルドとアプリケーションの配備のための時間です.
アプリケーションのビルド
npm run build
このコマンドはアプリケーションをコンパイルし、フォルダの下にあるすべてのファイルを生成しますdist
. これは、Googleクラウドのホストに展開されるフォルダです.配備する
あなたが持っていることを確認してください
firebase-tools
グローバルにインストールnpm install -g firebase-tools
今ログインする必要がありますfirebase login
ファイアウォールプロジェクトfirebase init
ホスティングオプションを選択します.尋ねる
public directory
, 種類dist
ときに1つのページのアプリを入力すると、' Y '種類
N
Github Automationビルドを要求する場合.種類
N
上書きを求められた場合index.html
. 我々は、我々のファイルを保ちたいです次に、ホスティングプロジェクトを選択すると、既存のいずれかを選択することができます既に作成したり、新しいものを作成します.
プロジェクトの配備
firebase deploy
おめでとう!最初から最後までToDoアプリケーションを構築し、正常にアプリケーションを配備できます.Reference
この問題について(Vue、Google firestore、およびGoogle認証とシンプルなtodoアプリ), 我々は、より多くの情報をここで見つけました https://dev.to/thangdc1982/simple-todo-app-with-vue-google-firestore-and-google-authentication-4005テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol