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

↑ホスティングを閉じる!


この記事が気に入ったらサポートをしてみませんか?