質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.51%
Vue.js

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

Vuex

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

Vue CLI

Vue CLIは、Vue.jsでアプリケーション開発を行うためのコマンドラインインタフェース(CLI)に基づいた開発ツールです。インタラクティブなプロジェクトの雛形や設定なしで使用できるプロトタイプの作成など、さまざまな機能が用意されています。

JavaScript

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

Q&A

解決済

1回答

1116閲覧

vueのコンポーネントで、ストア情報をpropsで渡したい

nutti

総合スコア7

Vue.js

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

Vuex

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

Vue CLI

Vue CLIは、Vue.jsでアプリケーション開発を行うためのコマンドラインインタフェース(CLI)に基づいた開発ツールです。インタラクティブなプロジェクトの雛形や設定なしで使用できるプロトタイプの作成など、さまざまな機能が用意されています。

JavaScript

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

0グッド

1クリップ

投稿2021/04/30 06:18

前提・実現したいこと

子のコンポーネントにストア情報をpropsで渡して、指定されたストアの場所へデータを保存したいです。
現状は、ストアの数だけ(保存先の数だけ)子のコンポーネントがあり、これを解消したいです。
https://user-first.ikyu.co.jp/entry/design-of-vue-and-vuex
こちらのサイトを参考に色々作成していたのですが、
ページ下部にあるVuexのバッドプラクティスという項目をみて、これをやろうと考えました。

発生している問題・エラーメッセージ

そもそも、どういう構造にしていいのかがわかりませんでした。
というのが、既存のコードではmapGettersや`mapActionsPで呼び出しを行なっているのですが、
これを、親からもらったストア情報から呼び出すという構造がどうやったら実現できるのかがわかりませんでした。

既存の子コンポーネントコード

vue

1<template> 2 <div> 3 <input vmodel="text"> 4 </div> 5</template> 6 7<script> 8import { mapGetters, mapActions } from "vuex" 9 10export default { 11 name: 'Child', 12 data: () => { 13 return { 14 text: "", 15 } 16 }, 17 computed: { 18 ...mapGetters('storeA', [ 19 'getItemData', 20 ]), 21 }, 22 watch: { 23 state: function(nv, ov) { 24 let param = { 25 text: this.text 26 } 27 this.setItemByID(param) 28 } 29 }, 30 methods: { 31 ...mapActions('storeA', [ 32 'setItemByID', 33 ]), 34 }, 35} 36</script> 37

親のコンポーネント

vue

1<template> 2 <div> 3 <Child /> 4 <Child /> 5 <Child /> 6 </div> 7</template> 8<script> 9export default { 10 ...vueの諸々の処理 省略 11} 12</script>

ストアのディレクトリ構造

Javascript

1import Vue from 'vue' 2import Vuex from 'vuex' 3import storeA from './storeA' 4import storeB from './storeB' 5import storeC from './storeC' 6 7Vue.use(Vuex) 8export default new Vuex.Store({ 9 state: {}, 10 mutations: { 11 }, 12 actions: { 13 }, 14 modules: { 15 storeA: storeA, 16 storeB: storeB, 17 storeC: storeC, 18 }, 19})

上記のコードで、
子コンポーネントで行なっているmaoGettesmapActionsは、
現在はstoreAの固定になっていますが、
storeA, storeB, storeCのように、親のコンポーネントの方で
propsで渡せればと考えているのですが、

<Child :storeData="$store.storeA">

みたいなことをするのかなとは思うのですが、
受け取ったあと、mapGettersをするのか?
と思い色々やってみたのですがわかりませんでした。

わかる方教えていただければ幸いです。
よろしくお願いいたします、

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

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

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

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

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

guest

回答1

0

ベストアンサー

現状はStoreAとデータをやり取りするInputコンポーネント、StoreBとデータをやり取りするInputコンポーネント, ...等が存在し、これらを一つにまとめたいということで合っていますでしょうか?

こういう場合、例えば最近主流のAtomic Designでは以下のようにします。

  1. 子コンポーネントには必要な情報だけをpropsで渡すようにする(つまりgetItemDataは親でmapし子に渡す形にする)
  2. 子コンポーネントは直接ストアに保存する処理をせず、ユーザ入力値をemitするだけにする(親がそのemitされた値をストアに渡す)

子コンポーネント

vue

1<template> 2 <div> 3 <input :value="text" @change="onChange"> 4 </div> 5</template> 6 7<script> 8export default { 9 name: 'Child', 10 // textはpropsで受け取る 11 props: { 12 text: { 13 type: String, 14 default: '' 15 } 16 }, 17 methods: { 18 onChange (value) { 19 // 親コンポーネントに入力値を渡す 20 this.$emit('change', value) 21 } 22 }, 23} 24</script> 25

子はデータを持たず、親から受け取ったpropsを処理して親に返すだけにします。こうすることで、子が色々な場面で使えるようになる(汎用性が上がる)効果があります。

こういう再利用ができそうな小さいコンポーネントではアプリケーションの具体的な処理は行わず、親に処理を移譲するのが常套手段です。

親コンポーネント

vue

1<template> 2 <div> 3 <Child :text="getItemData" @change="onChange"/> 4 <Child :text="getItemData" @change="onChange"/> 5 <Child :text="getItemData" @change="onChange"/> 6 </div> 7</template> 8<script> 9export default { 10 ...vueの諸々の処理 省略 11 12 computed: { 13 ...mapGetters('storeA', [ 14 'getItemData', 15 ]), 16 }, 17 methods: { 18 ...mapActions('storeA', [ 19 'setItemByID', 20 ]), 21 onChange (value) { 22 let param = { 23 text: value 24 } 25 this.setItemByID(param) 26 } 27 } 28} 29</script>

※ ご質問ではgetItemDataがどこにも使われておらず用途が不明でしたが、inputに入れるテキストが入っているという想定で上記のコードを書いています。
※ また、親は再利用性の低いコンポーネントという想定です(そうでなければ処理を更に上に移譲します)。

親がストアとやりとりするようにしたため、子はストアと関連を持っておらず、例えばstoreBと関連した親コンポーネントの中でも再利用することができます。

以上不明点があれば追記をしてください。

投稿2021/05/01 04:43

編集2021/05/01 04:56
Masa-Shin

総合スコア269

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

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

nutti

2021/05/13 00:58 編集

ご返信が遅くなりすいません。 なるほど、汎用性を考えて親に譲渡するべきだったのですね! なにより「Atomic Design」というワードしらべてみてとても勉強になりました! ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問