VueCLIでアプリ作成(アドレス帳)⑤
データの更新
src/store/index.js
import Vue from "vue";
import Vuex from "vuex";
import firebase from "firebase";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
login_user: null,
drawer: false,
addresses: [],
},
mutations: {
setLoginUser(state, user) {
state.login_user = user;
},
deleteLoginUser(state) {
state.login_user = null;
},
toggleSideMenu(state) {
state.drawer = !state.drawer;
},
addAddress(state, { id, address }) {
address.id = id;
state.addresses.push(address);
},
updateAddress(state, { id, ddress }) {
const index = state.addresses.findIndex((address) => address.id === id);
state.addAddress[index] = address;
},
},
actions: {
setLoginUser({ commit }, user) {
commit("setLoginUser", user);
},
fetchAddresses({ getters, commit }) {
firebase
.firestore()
.collection(`users/${getters.uid}/addresses`)
.get()
.then((snapshot) => {
snapshot.forEach((doc) =>
commit("addAddress", { id: doc.id, address: doc.data() })
);
});
},
login() {
const google_auth_provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithRedirect(google_auth_provider);
},
logout() {
firebase.auth().signOut();
},
deleteLoginUser({ commit }) {
commit("deleteLoginUser");
},
toggleSideMenu({ commit }) {
commit("toggleSideMenu");
},
addAddress({ getters, commit }, address) {
if (getters.uid) {
firebase
.firestore()
.collection(`users/${getters.uid}/addresses`)
.add(address)
.then((doc) => {
commit("addAddress", { id: doc.id, address });
});
}
},
updateAddress({ getters, commit }, { id, address }) {
if (getters.uid) {
firebase
.firestore()
.collection(`users/${getters.uid}/addresses`)
.doc(id)
.update(address)
.then(() => {
commit("updateAddress", { id, address });
});
}
},
},
getters: {
userName: (state) => (state.login_user ? state.login_user.displayName : ""),
photoURL: (state) => (state.login_user ? state.login_user.photoURL : ""),
uid: (state) => (state.login_user ? state.login_user.uid : null),
getAddressById: (state) => (id) =>
state.addresses.find((address) => address.id === id),
},
});
アクションメソッド内で
updateAddress({ getters, commit }, { id, address }) {
if (getters.uid) {
firebase
.firestore()
.collection(`users/${getters.uid}/addresses`)
.doc(id)
.update(address)
.then(() => {
commit("updateAddress", { id, address });
});
}
},
次にmutations内で
updateAddress(state, { id, ddress }) {
const index = state.addresses.findIndex((address) => address.id === id);
state.addAddress[index] = address;
},
updateAddressを実装(src/views/AddressForm.vue)
<template>
<v-container text-xs-center>
<v-layout row wrap justify-center>
<v-flex xs12>
<h1>連絡先編集</h1>
</v-flex>
<v-flex xs5 mt-5>
<v-card>
<v-card-text>
<v-form>
<v-text-field v-model="address.name" label="名前"></v-text-field>
<v-text-field v-model="address.tel" label="電話番号"></v-text-field>
<v-text-field v-model="address.email" label="メールアドレス"></v-text-field>
<v-text-field v-model="address.address" label="住所"></v-text-field>
<v-btn @click="$router.push({ name: 'addresses' })">キャンセル</v-btn>
<v-btn color="info" @click="submit">保存</v-btn>
</v-form>
</v-card-text>
</v-card>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
import { mapActions } from 'vuex'
export default {
created(){
if(!this.$route.params.address_id) return
const address = this.$store.getters.getAddressById(this.$route.params.address_id)
if(address){
this.address = address
}else{
this.$router.push({name:'addresses'})
}
},
data () {
return {
address: {}
}
},
methods: {
submit () {
if(this.$route.params.address_id){
this.updateAddress({id:this.$route.params.address_id,address:this.address})
}else{
this.addAddress(this.address)
}
this.$router.push({ name: 'addresses' })
this.address = {}
},
...mapActions(['addAddress','updateAddress'])
}
}
</script>
追加したとこ①updateAddress
...mapActions(['addAddress','updateAddress'])
追加したとこ②if文
submit () {
if(this.$route.params.address_id){
this.updateAddress({id:this.$route.params.address_id,address:this.address})
}else{
this.addAddress(this.address)
}
データの削除
src/store/index/js
import Vue from "vue";
import Vuex from "vuex";
import firebase from "firebase";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
login_user: null,
drawer: false,
addresses: [],
},
mutations: {
setLoginUser(state, user) {
state.login_user = user;
},
deleteLoginUser(state) {
state.login_user = null;
},
toggleSideMenu(state) {
state.drawer = !state.drawer;
},
addAddress(state, { id, address }) {
address.id = id;
state.addresses.push(address);
},
updateAddress(state, { id, address }) {
const index = state.addresses.findIndex((address) => address.id === id);
state.addAddress[index] = address;
},
deleteAddress(state, { id }) {
const index = state.addresses.findIndex((address) => address.id === id);
state.addAddress.splice(index, 1);
},
},
actions: {
setLoginUser({ commit }, user) {
commit("setLoginUser", user);
},
fetchAddresses({ getters, commit }) {
firebase
.firestore()
.collection(`users/${getters.uid}/addresses`)
.get()
.then((snapshot) => {
snapshot.forEach((doc) =>
commit("addAddress", { id: doc.id, address: doc.data() })
);
});
},
login() {
const google_auth_provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithRedirect(google_auth_provider);
},
logout() {
firebase.auth().signOut();
},
deleteLoginUser({ commit }) {
commit("deleteLoginUser");
},
toggleSideMenu({ commit }) {
commit("toggleSideMenu");
},
addAddress({ getters, commit }, address) {
if (getters.uid) {
firebase
.firestore()
.collection(`users/${getters.uid}/addresses`)
.add(address)
.then((doc) => {
commit("addAddress", { id: doc.id, address });
});
}
},
updateAddress({ getters, commit }, { id, address }) {
if (getters.uid) {
firebase
.firestore()
.collection(`users/${getters.uid}/addresses`)
.doc(id)
.update(address)
.then(() => {
commit("updateAddress", { id, address });
});
}
},
deleteAddress({ getters, commit }, { id }) {
if (getters.uid) {
firebase
.firestore()
.collection(`users/${getters.uid}/addresses`)
.doc(id)
.delete()
.then(() => {
commit("deleteAddress", { id });
});
}
},
},
getters: {
userName: (state) => (state.login_user ? state.login_user.displayName : ""),
photoURL: (state) => (state.login_user ? state.login_user.photoURL : ""),
uid: (state) => (state.login_user ? state.login_user.uid : null),
getAddressById: (state) => (id) =>
state.addresses.find((address) => address.id === id),
},
});
追加したとこ①アクションメソッド
deleteAddress({ getters, commit }, { id }) {
if (getters.uid) {
firebase
.firestore()
.collection(`users/${getters.uid}/addresses`)
.doc(id)
.delete()
.then(() => {
commit("deleteAddress", { id });
});
}
追加したとこ②mutaition内
deleteAddress(state, { id }) {
const index = state.addresses.findIndex((address) => address.id === id);
state.addAddress.splice(index, 1);
},
Viewsに実装 src/views/Addresses.vue
①マップアクションをインポート
import {mapActions} from 'vuex'
②メソッドでマップアクションを呼び出し
methods:{
...mapActions(['deleteAddress'])
}
③メソッドで消すときに確認がでるように追加
methods:{
deleteConfirm(id){
if(confirm('削除してよろしいですか?')){
this.deleteAddress({id})
}
},
...mapActions(['deleteAddress'])
}
④テンプレートで使う
<template>
<v-container text-xs-center justify-center>
<v-layout row wrap>
<v-flex xs12>
<h1>連絡先一覧</h1>
</v-flex>
<v-flex xs12 mt-5 mr-5 text-xs-right>
<router-link :to="{ name: 'address_edit' }">
<v-btn color="info">
連絡先追加
</v-btn>
</router-link>
</v-flex>
<v-flex xs12 mt-3 justify-center>
<v-data-table :headers='headers' :items='addresses'>
<template v-slot:items="props">
<td class="text-xs-left">{{ props.item.name }}</td>
<td class="text-xs-left">{{ props.item.tel }}</td>
<td class="text-xs-left">{{ props.item.email }}</td>
<td class="text-xs-left">{{ props.item.address }}</td>
<td class="text-xs-left">
<span>
<router-link :to="{name:'address_edit',params:{address_id:props.item.id}}">
<v-icon small class="mr-2">edit</v-icon>
</router-link>
</span>
<span>
<v-icon small class="mr-2" @click="deleteConfirm(props.item.id)">delete</v-icon>
</span>
</td>
</template>
</v-data-table>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
import {mapActions} from 'vuex'
export default {
created () {
this.addresses = this.$store.state.addresses
},
data () {
return {
headers: [
{ text: '名前', value: 'name' },
{ text: '電話番号', value: 'tel' },
{ text: 'メールアドレス', value: 'email' },
{ text: '住所', value: 'address' },
{ text:'操作',sortable:false}
],
addresses: []
}
},
methods:{
deleteConfirm(id){
if(confirm('削除してよろしいですか?')){
this.deleteAddress({id})
}
},
...mapActions(['deleteAddress'])
}
}
</script>
<style scoped lang="scss">
a{
text-decoration: none;
}
</style>
デプロイ
npm install -g firebase-tools
↑これでfirebaseコマンドが使用可能に。
firebase login
firebaseログイン時のGoogleアカウント
firebase init
↑これでホスティングの設定
>( ) Hosting: Configure and deploy Firebase Hosting sites
↑ホスティングまで↓で移動して「スペース」で選択
? What do you want to use as your public directory? dist
↑公開ディレクトリを聞かれるのでdistと入力してenter
? Configure as a single-page app (rewrite all urls to /index.html)? Yes
↑シングルページアプリケーション用にするか?yを入力してenter
npm run build
↑コンパイル
firebase deploy
Hosting URLにアクセスすると表示!!!!(少しタイムラグあり)
firebase hosting:disable
↑ホスティングを閉じる!