[Nuxt.js/TS] Store

Vuex

https://vuex.vuejs.org/ja/guide/actions.html

Storeフォルダにデータ管理機能を作る

 

state

mutation

action

module(別記事)

 

<template>
<div>
  <p >{{$store.state.counter}}</p>
  <p @click="clicked_inc">increment: {{cnt}}</p>
  <p @click="clicked_inc_n(2)">increment_n: {{cnt}}</p>
  <p @click="clicked_inc_payload">increment_payload: {{cnt}}</p>  
  <p @click="clicked_inc_obj">increment_obj: {{cnt}}</p>  
  <p @click="inc_method">inc_method: {{cnt}}</p>

  <p @click="clicked_inc_action">increment action: {{cnt}}</p>  
  <p @click="clicked_inc_action_async">increment action Async: {{cnt}}</p>  

  <p @click="clicked_inc_action">action_inc_method: {{cnt}}</p>
  <p @click="clicked_inc_action_async">action_inc_async_method: {{cnt}}</p>
  <p @click="inc_action_async_method">action_inc_async_method: {{cnt}}</p>
  <p @click="action_inc_payload(5)">inc_action_payload: {{cnt}}</p>
  <p @click="clicked_actionA_async">clicked_actionA_async: {{cnt}}</p>

  <ul>
    <!-- <li v-for="t in $store.state.Book.books"> -->
    <li v-for="t in books">
      <span>{{ t.title }}</span>
    </li>
  </ul>
  <button @click="add_book">ADD</button>
  <!--
  <ul>
    <li v-for="todo in todos">
      <input type="checkbox" :checked="todo.done" @change="toggle(todo)">
      <span :class="{ done: todo.done }">{{ todo.text }}</span>
    </li>
    <li><input placeholder="What needs to be done?" @keyup.enter="addTodo"></li>
  </ul>
  -->

 </div> 
</template>

<!-- JS VERSION
<script>
  import { mapMutations } from 'vuex'

  export default {
    computed: {
      todos () {
        return this.$store.state.todos.list
      }
    },
    methods: {
      addTodo (e) {
        this.$store.commit('todos/add', e.target.value)
        e.target.value = ''
      },
      ...mapMutations({
        toggle: 'todos/toggle'
      })
    }
  }
</script>
-->

<script lang="ts">

// TS VER.
  import { Component, Vue, namespace } from 'nuxt-property-decorator'
//  import { Vue, Component, namespace } from 'vue-property-decorator'
  import { mapMutations, mapActions  } from 'vuex'

  const StoreBook = namespace('Book')

  @Component({
    methods: {
      ...mapMutations({ toggle: 'toggle' }),
      ...mapMutations({ inc_method: 'increment' }),

      ...mapActions( {inc_action_async_method: 'action_inc_async'} ), // `this.add()` を `this.$store.dispatch('increment')` にマッピングする]
      ...mapActions( ['action_inc_payload', ]), // `this.add()` を `this.$store.dispatch('increment')` にマッピングする]
    }
  })

  export default class extends Vue {

    @StoreBook.Mutation add
    @StoreBook.Mutation all

    //------------------------------------------
    // getter
    //------------------------------------------
    private get cnt(): number {
      return this.$store.state.counter
    }

    private get books():[] {
      return this.$store.state.Book.books
    }

    //------------------------------------------
    // mutation
    //------------------------------------------
    clicked_inc(): void{
      this.$store.commit('increment')
    }

    clicked_inc_n(n): void{
      this.$store.commit('increment_n', n)
    }

    clicked_inc_payload(): void{
      this.$store.commit('increment_payload', {amount: 3} )
    }

    clicked_inc_obj(): void{
      this.$store.commit( {type:'increment_payload', amount: 4} )
    }
    //------------------------------------------
    // action
    //------------------------------------------
    clicked_inc_action(): void{
      this.$store.dispatch('action_inc')
    }
    clicked_inc_action_async(): void{
      this.$store.dispatch('action_inc_async')
    }

    //非同期処理ー成功処理実装
    //clicked_actionA_async(): void{
      // this.$store.dispatch('actionA').then(()=>{
      //   console.log("finished")
      // })
    //}

    // 非同期処理ー成功、失敗処理実装
    // clicked_actionA_async(): void{
    //   this.$store.dispatch('actionA').then(()=>{
    //     console.log("success")
    //   },
    //   ()=>{
    //     console.log("error")
    //   })
    // }

    // 非同期処理ーCallback分けた場合
    successCallback(): void {
      console.log("It succeeded with " )
    }

    failureCallback(): void {
      console.log("It failed with " )
    }
    clicked_actionA_async(): void{
      this.$store.dispatch('actionA').then(
        this.successCallback,
        this.failureCallback)
    }

    // private get todos(): Object {
    //   return this.$store.state.todos.list
    // }

    get_books():Object[]{
      console.log("get_books" )
      return this.all();
    }
    add_book(el): void{
      var b = { title:"title1",text:"abc" }
      this.add(b)
    }

    addTodo(e): void {
      this.$store.commit('add', e.target.value)
      e.target.value = ''
    }
  }
</script>

<style>
.done {
  text-decoration: line-through;
}


</style>

 

store/index.ts

export const state = () => ({
  counter: 0
})

export const mutations = {
  increment (state) {
    state.counter++
  },
  increment_n (state, n) {
    state.counter += n
  },
  increment_payload (state, payload) {
    state.counter += payload.amount
  }
}

export const actions = {

  // action_inc (context) {
  //   context.commit('increment')
  // }
  // 上に同じ
  // action_inc ( {commit} ) {
  //   commit('increment')
  // },  

  action_inc ( {commit} ) {
    commit('increment')
  },  
  action_inc_payload ( {commit} ,payload) {
    commit('increment_n',payload)
  },  
  async action_inc_async( {commit} ) {
    setTimeout(() => {
      commit('increment')
    }, 2000)
  },
  actionA( {commit} ){

    //Promiseを戻せる。
    return new Promise((resolve,reject)=>{
      setTimeout(() => {
        commit('increment')

        // 成功
        resolve()

        // 失敗
        // reject()
      }, 2000)
    });
  },

}

store/Book/index.ts

 

Leave a Reply