🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Vuex

Vuexは、Vue.js アプリケーションのための状態管理ライブラリです。アプリケーション内で使用するコンポーネントのための集中データストアを提供。コンポーネント同士でデータをやり取りし、処理のフローを一貫させたり、データの見通しを良くすることができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

1487閲覧

vuexの監視ができているときとできていないときがある

退会済みユーザー

退会済みユーザー

総合スコア0

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Vuex

Vuexは、Vue.js アプリケーションのための状態管理ライブラリです。アプリケーション内で使用するコンポーネントのための集中データストアを提供。コンポーネント同士でデータをやり取りし、処理のフローを一貫させたり、データの見通しを良くすることができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2019/10/10 05:37

タイトルの通りなのですが、ざっくりstore関係は以下になっています。

javascript

1// index 2 3import Vue from 'vue' 4import Vuex from 'vuex' 5import getters from './modules/getters' 6import actions from './modules/actions' 7import mutations from './modules/mutations' 8 9Vue.use(Vuex) 10 11const state = { 12 items: {}, // DB取得値または格納値を格納するkey 13 status: {}, // 画面状態管理を格納するkey 14} 15export default new Vuex.Store({ 16 state, 17 getters, 18 actions, 19 mutations, 20})

javascript

1 2// mutations 3 4 /** 5 * vuex.stateへの保存実行。 6 * 7 * @param state 8 * @param payload 9 */ 10 save (state, payload) { 11 state[payload.type] = payload.values 12 }, 13 14 /** 15 * 代入先を動的にしたvuex.stateへの保存実行。 16 * 17 * @param state 18 * @param payload 19 */ 20 keySpecificationSave (state, payload) { 21 state[payload.type][payload.key] = payload.values 22 },

storeの変更を検知したいコンポーネントAのmountedで常に監視。

javascript

1 2mounted() { 3 // this.$store.dispatch('save', {type: 'items', values: {}}) 4 this.$store.watch( 5 (state, getters) => getters.items, 6 (newValue, oldValue) => { 7 console.log('storeが変更されました。') 8 console.log('prefecture changed! %s => %s', oldValue, newValue) 9 } 10 ) 11 },

上のコンポーネントAは更に複数のコンポーネントを呼び出していて、
その子コンポーネント(モーダルなのですが)では入力値が変わる度にname属性と同じ構造でstoreに同期させるようにしています。

store的には以下のような形式で配列とオブジェクトの複合構成になっています。

items.a[0].aa
items.a[0].ab
items.a[0].ac
items.a[0].ad
items.a[1].aa
items.a[1].ab
items.a[1].ac
items.a[1].ad

コンポーネントAは子コンポーネントによって作られたstoreの変更を検出したいです。
細かいレベルでの検知は気にしていなくて、items.aの配列が何個あるかを知りたいので、items.a単位で検知できれば良いです。


以下の画像は子コンポーネントで色々入力したのでdispatchでsaveとkeySpecificationSaveが動いてstoreに同期させています。
しかしこの段階ではstate.itemsは検出されていません。

確認用になにかボタンをクリックしたら動くメソッドの中で
console.log(this.$store.getters.items.a)
をしたら取得はできているようです。

イメージ説明

vue devtoolsのCommit Allをクリックすると、検知クロージャー内で仕込んでいるログが反映されていることが確認できます。

イメージ説明

vue devtoolsのCommit Allをクリックせずに、即時検出してほしいのですが、これは何かの設定で解決できるのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

検出できない要因は色々あると思いますが、シンプルなサンプルで色々検証してみました。

その中からまず1つ確実に言えること。
stateを汎用的に使おうと思っていたのが原因でした。

const state = { items: { // DB取得値または格納値を格納するkey }, status: { // 画面状態管理を格納するkey }, }

結論からいうと、watchしたいなら、最初からstateに定義してないといけないです。

まぁ、こんなことやっていました。

save (state, payload) { state.items[payload.property] = payload.values },

items配下にその画面では使わないプロパティーは持たせたくないので(不要なものは見たくない)プロパティーは動的に作るということをしていましたが、watchする分にはこれがアウトだったようです。

別にwatch使わずにstoreに突っ込んで別コンポーネントで使ったりする分には動的にプロパティー作っても取得できますが、watchを使うなら話は別、ということのようです、

システム全体ではなく、今回一部の画面でしかvue.js使っていないので、そういう考え方で見ると、画面Aではitems.aaaとbbbを使うけど、画面Bではitems.cccとdddを使うんだよね。
だから(不要なものは見たくない)、itemsに最初で定義したくないんだよねっていうのが発端です。

items: { // DB取得値または格納値を格納するkey aaa: null, bbb: null, ccc: null, ddd: null, },

完全にSPAならむしろ、不要なものは見たくないとかそんなこと言ってたらページ間で状態管理できなくなるのでダメですが、今回のようなケースには注意が必要かもです。

vuexが何を解決する為に生まれたのか考えたら、納得です。

投稿2019/10/11 03:57

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

watch対象がgetterじゃなくてstateじゃないすかね?

javascript

1this.$store.watch( 2// (state, getters) => getters.items, 3 (state, getters) => state.items, 4 (newValue, oldValue) => { 5 console.log('storeが変更されました。') 6 console.log('prefecture changed! %s => %s', oldValue, newValue) 7 } 8 )

投稿2019/10/10 06:44

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/10/11 03:14

回答ありがとうございます。別サンプルで2通り試しましたが、監視対象がgetterでもstateでも、検出できますので、まさしく監視したいデータを渡してやればいいだけのようです。 個人解決しました。
退会済みユーザー

退会済みユーザー

2019/10/11 04:04

なるほど、Vueがプロパティをたどってgetter/setterをHuckするが、プロパティにキー指定でオブジェクトつっこんだからHuckできずリッスンできなくなっていた、ちゅーことっすね。 Arrayの変更もconcatとか使わないとダメなので、同じ原因っすね。勉強になりました。
退会済みユーザー

退会済みユーザー

2019/10/11 05:27

ちなみに、items.aaaの変更を検知したいけど、items配下で監視できればいいやなんてこともできなかったです。 NG例 ``` this.$store.watch( (state) => state.items, (newValue, oldValue) => { console.log(oldValue) console.log(newValue) } ) ``` ちゃんと左辺の最下層のプロパティーまで指定しないと検知できなかったです。 ``` save (state, payload) { state.items[payload.property] = payload.values //aaaに入れているとする。 }, ``` ``` this.$store.watch( (state) => state.items.aaa, (newValue, oldValue) => { console.log(oldValue) console.log(newValue) } ) ```
退会済みユーザー

退会済みユーザー

2019/10/11 06:40

なるほど、ありがとう。 最初はaaaがundefinedだけどってときは別のやりかた必須ですな。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問