- 03-5820-1777平日10:00〜18:00
- お問い合わせ
Vue3でVuexのsubscribe機能を使用する例の紹介としてアプリケーションを作成してみました。
この機能を使用するとmutations処理の終了を感知し、追加処理をする事が出来ます。
このアプリケーションの要点は、本登録ボタン押下時にサーバに登録処理をかけます、登録処理終了後にVuexに保管している、新規登録商品に値をセットするので、そのタイミングで商品一覧のsubscribeメソッドが呼ばれ新規登録した商品を商品一覧に追加するというリアルタイムに商品一覧を更新できるという点です。
商品一覧、商品登録RestAPIを提供するSpringBootサーバを用意する。
商品情報はメモリ上で管理する。
GoodsList.vue
<template>
登録状況:{{ store.getters.getRegistStatus }}<br/><br/>
<button v-on:click="moveRegistGoods">商品登録</button><button v-on:click="getGoods">表示更新</button>
<br/><br/>
<center>
<div class="th-sticky_wrap">
<table class="st-tbl1">
<thead>
<tr>
<th>コード</th>
<th>名称</th>
<th>カテゴリ</th>
</tr>
</thead>
<tbody>
<tr v-for="(goods) in goodsList" v-bind:key="goods.code">
<td>{{ goods.code}}</td>
<td>{{ goods.name }}</td>
<td>{{ goods.category }}</td>
</tr>
</tbody>
</table>
</div>
</center>
</template>
<script>
import axios from 'axios'
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
export default {
name: 'GoodsList',
setup(){
const router = useRouter()
const store = useStore()
const goodsList = ref(null)
onMounted(() => {
getGoods()
//subscribeイベントが発火した際の処理を記述する。
//商品一覧に新規登録商品を追加する
store.subscribe((mutation, state) => {
if (mutation.type === 'setregistedGoodsList') {
state.registedGoodsList.forEach(element => goodsList.value.push( element ) );
}
})
})
const moveRegistGoods = () =>{
router.push( "/regist" )
}
//商品をサーバから取得するメソッド
const getGoods = () =>{
axios.get('http://localhost:8080/goods/list')
.then(response => {
goodsList.value = response.data
console.log( response.data );
})
}
return{
moveRegistGoods,
getGoods,
goodsList,
store
}
}
}
</script>
RegistGoods.vue
<template>
<center>
<div class="view-div">
<h2>仮商品仮登録</h2>
<center>
<table>
<tr>
<td>商品コード</td>
<td><input type="text" v-model="goods.code"></td>
</tr>
<tr>
<td>商品名</td>
<td><input type="text" v-model="goods.name"></td>
</tr>
<tr>
<td>商品カテゴリ</td>
<td><input type="text" v-model="goods.category"></td>
</tr>
</table>
</center><br/>
<button v-on:click="kariRegist">仮登録</button><button v-on:click="prev">戻る</button><br/><br/>
</div>
<div class="view-div">
<h2>仮商品登録リスト</h2>
<div class="th-sticky_wrap">
<center>
<table class="st-tbl1">
<thead>
<tr>
<th>コード</th>
<th>名称</th>
<th>カテゴリ</th>
</tr>
</thead>
<tbody>
<tr v-for="(goods) in store.getters.getGoodsList" v-bind:key="goods.code">
<td>{{ goods.code}}</td>
<td>{{ goods.name }}</td>
<td>{{ goods.category }}</td>
</tr>
</tbody>
</table>
</center><br/>
<button v-on:click="regist">本登録</button><br/><br/>
</div>
</div>
</center>
</template>
<script>
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
import { ref } from 'vue'
export default {
name: 'RegistGoods',
setup(){
const router = useRouter()
const store = useStore()
const goods = ref({code:'',name:'',category:''})
//仮登録メソッド、VuexのkariRegistGoodsメソッドを呼ぶ。
const kariRegist = ()=>{
store.dispatch('kariRegistGoods', goods.value)
}
//本登録メソッド、VuexのregistGoodsメソッドを呼ぶ。
//registGoods内ではサーバに対して登録処理を行う。
const regist =()=>{
store.dispatch('registGoods')
router.push( "/" )
}
const prev = ()=>{
router.push( "/" )
}
return{
kariRegist,
regist,
prev,
store,
goods
}
}
}
</script>
index.js
import { createStore } from 'vuex'
import axios from 'axios'
export default createStore({
state: {
registStatus:'', //登録状況
goodsList:[], //仮登録商品
registedGoodsList:[] //新規登録商品
},
mutations: {
//仮登録商品設定
kariRegistGoods: function(state, value){
let goods = {'code':value.code, 'name':value.name, 'category':value.category}
state.goodsList.push( goods )
},
//仮登録商品クリア
clearKariRegistGoods: function(state){
state.goodsList = []
},
//登録状況設定
setRegistStatus: function(state, value) {
state.registStatus = value
},
//新規登録商品設定
setRegistedGoodsList: function(state, value) {
state.registedGoodsList = value
},
},
actions: {
//商品仮登録、stateのgoodsListに設定
kariRegistGoods: function( { commit }, goods ){
commit( "kariRegistGoods", goods );
},
//商品本登録、サーバに登録処理を依頼し返ってきた商品情報を新規登録商品として
//stateのregistedGoodsListに設定
registGoods: function({ commit }){
commit('setRegistStatus', "処理中")
axios.post('http://localhost:8080/goods/regist', this.state.goodsList)
.then(response => {
if( response.status == 200 ){
commit('clearKariRegistGoods')
commit('setRegistedGoodsList', response.data)
commit('setRegistStatus', "登録完了")
}else{
commit('setRegistStatus', "登録エラー")
}
})
}
},
modules: {
},
getters:{
getGoodsList( state ){ return state.goodsList; },
getRegistStatus( state ){ return state.registStatus; }
}
})
index.js
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{
path: '/',
name: 'GoodsList',
component: () => import('../views/GoodsList.vue')
},
{
path: '/regist',
name: 'RegistGoods',
component: () => import('../views/RegistGoods.vue')
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
GoodsController.java
package com.example.vuexmulti.ac;
import java.lang.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.PostMapping;
import com.example.vuexmulti.service.GoodsService;
import com.example.vuexmulti.service.Goods;
@CrossOrigin
@RestController
@RequestMapping("/goods")
public class GoodsController {
@Autowired
private GoodsService goodsService;
/**
* 商品情報リストを取得
* @return
*/
@RequestMapping(value = "/list", method = RequestMethod.GET)
public Goods[] getGoodsList() {
return goodsService.getGoods();
}
/**
* 商品情報登録
* @return 結果
*/
@RequestMapping(value = "/regist", method = RequestMethod.POST)
public Goods[] regist( @RequestBody Goods[] goodsList ){
//subscribeイベントの通知が分かりやすいように5秒間待機
try{
Thread.sleep(5000);
}catch(Exception e){}
for( Goods goods : goodsList ){
System.out.println( goods.getCode() );
System.out.println( goods.getName() );
System.out.println( goods.getCategory() );
goodsService.registGoods( goods );
}
return goodsList;
}
}
Goods.java
package com.example.vuexmulti.service;
/**
* 商品情報クラス
*/
public class Goods{
private String code;
private String name;
private String category;
public Goods(){
}
public Goods( String code, String name, String category){
this.code = code;
this.name = name;
this.category = category;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
GoodsService.java
登録した商品はgoodsListに格納する。今回は管理アプリケーションなのでDBは使用しない。
package com.example.vuexmulti.service;
import java.util.*;
import org.springframework.context.annotation.Scope;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import javax.annotation.*;
/**
* 商品の取得、追加を行うサービス
**/
@Scope("singleton")
@Service
public class GoodsService {
private List<Goods> goodsList = new ArrayList<Goods>();
/**
* 商品情報を取得するメソッド
**/
public Goods[] getGoods(){
return goodsList.toArray( new Goods[]{} );
}
/**
* 商品情報を登録するメソッド
**/
public void registGoods( Goods goods ){
goodsList.add( goods );
}
}
以上、Vuexの値更新時に発火するイベントのsubscribe機能を使用してみました。
このような使い方をすると、登録処理終了後に再度ボタンを検索ボタンを押下しなくても、リストにデータが反映されよりリアルタイムにデータを見る事が出来るので便利だと思います。
他にも色々使用できる所はあるので、実践で使用していき機会があればまた紹介したいと思います。
今回使用したコードは此方から閲覧できます。