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

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

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

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

JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

2回答

612閲覧

v-for propでデータが渡ってくるたびに呼べるメソッド

退会済みユーザー

退会済みユーザー

総合スコア0

Vue.js

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

JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

0グッド

0クリップ

投稿2018/06/22 11:15

編集2018/06/22 11:31

typescript

1//parent.vue 2 3<template> 4 <div class="parent"> 5 <Child v-for="value in getList" v-bind:value="value"/> 6 </div> 7</template> 8 9<script lang="ts"> 10import { Component, Prop, Vue } from 'vue-property-decorator'; 11 12//コンポーネント 13import Child from './components/child.vue'; 14 15@Component({ 16 components: { 17 Child, 18 }, 19}) 20export default class Parent extends Vue { 21 22 get getList(){ 23 return this.$store.getters["parentModule/GET_LIST"] 24 } 25} 26 27</script> 28 29

typescript

1//child.vue 2 3<template> 4 5 <div class="child"> 6 7 <div class="name">{{ getValueName }}</div> 8 <img :src="getValueImage" class="image"/> 9 10 </div> 11 12</template> 13 14<script lang="ts"> 15import { Component, Prop, Vue } from 'vue-property-decorator'; 16 17@Component({ 18 props: { 19 } 20}) 21 22export default class Child extends Vue { 23 24 @Prop() private value!: any; 25 26 get getValueName(){ 27 this.$store.dispatch("parentModule/childModule/SET_VALUE", this.value.id) 28 return this.$store.getters["parentModule/childModule/GET_NAME"] 29 } 30 31 get getValueImage(){ 32 this.$store.dispatch("parentModule/childModule/SET_VALUE", this.value.id) 33 return this.$store.getters["parentModule/childModule/GET_IMAGE"] 34 } 35 36} 37 38</script> 39 40<style lang="scss"> 41 42</style>

typescript

1 2//childModule for vuex 3 4import Value from "value" 5 6import List from "list" 7var list = new List() 8 9export const childModule = { 10 namespaced: true, 11 state: { 12 value : Value 13 }, 14 mutations: { 15 "SET_VALUE"(state : any, valueId : number){ 16 state.value = list.getValue(valueId) //ここで指定されたvalue(nameとimageを持ってる)が得られる 17 } 18 }, 19 actions: { 20 "SET_VALUE"({ commit } , valueId : number){ 21 commit("SET_VALUE", valueId) 22 } 23 }, 24 getters:{ 25 "GET_VALUE_NAME" : state => { return state.value.name }, 26 "GET_VALUE_IMAGE" : state => { return state.value.image }, 27 "GET_VALUE" : state => { return state.value } 28 } 29}

リストを表示しています
リストを検索した時、

this.$store.getters["parentModule/GET_LIST"]

の内容が検索され絞られたリストに変わります
getListはcomputedになっており、検索結果を子コンポーネントに渡します

子コンポーネントは変化したidを元に

get getValueName(){
this.$store.dispatch("parentModule/childModule/SET_VALUE", this.value.id)
return this.$store.getters["parentModule/childModule/GET_VALUE_NAME"]
}

get getValueImage(){
this.$store.dispatch("parentModule/childModule/SET_VALUE", this.value.id)
return this.$store.getters["parentModule/childModule/GET_VALUE_IMAGE"]
}

値を出力しています

ここで、上記2つのメソッドでそれぞれ

this.$store.dispatch("parentModule/childModule/SET_VALUE", this.value.id)

としているところを1つにしたいです
つまり、propされた時?に

this.$store.dispatch("parentModule/childModule/SET_VALUE", this.value.id)

この処理をしたいです...

どのように書けばよろしいでしょうか

普通に片方に書くだけで解決するのですが、なんだか気持ち悪いです

そしてchild.vueで

typescript

1 2<template> 3 4 <div class="child"> 5 6 <div class="name">{{ getValue.name }}</div> 7 <img :src="getValue.image" class="image"/> 8 9 </div> 10 11</template> 12 13get getValue(){ 14 this.$store.dispatch("parentModule/childModule/SET_VALUE", this.value.id) 15 return this.$store.getters["parentModule/childModule/GET_VALUE"] 16}

このようにすると、valueが全て最後のvalueに上書きされて、最後のvalueのリストだけになってしまいます

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

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

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

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

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

guest

回答2

0

ベストアンサー

上のようなことをする必要は全くなかったです。

まずchildのコンポーネントにcomputedのgetのメソッドを書いて、しかもその中に
dispatchを書くなんてすごい変なことをしてました。
変化した配列の結果を取得するためにやっていたことですが、propのたびに呼ばれるメソッドとかそのようなことを考える必要は一切なく、

get getList(){
return this.$store.getters["parentModule/GET_LIST"]
}

ここの値が変われば自動的に子コンポーネントへ渡される値も変わります。

typescript

1//child.vue 2 3<template> 4 5 <div class="child"> 6 7 <div class="name">{{ value.name }}</div> 8 <img :src="value.image" class="image"/> 9 10 </div> 11 12</template> 13 14<script lang="ts"> 15import { Component, Prop, Vue } from 'vue-property-decorator'; 16 17@Component({ 18 props: { 19 } 20}) 21 22export default class Child extends Vue { 23 24 @Prop() private value!: any; 25 26} 27 28</script> 29 30<style lang="scss"> 31 32</style>

本来これだけで良かったです。
しかし、当時は、元の配列が変わると、observerがオブジェクトから消えてしまい、自動的にchild.vue達に反映させるということができてませんでした。
その理由はvuexのstateとしていたモデルに初期値を入れてなかったからです。

例えば、

typescript

1 2class Model{ 3 member : Person[] 4 5 constructor(responseStart){ 6 7 //↓仮にこのような値が来たとする 8 responseStart = [ 9 { id: 1 , name : "山田" }, 10 { id: 2 , name : "田中" } 11 ] 12 this.member = responseStart 13 } 14 15} 16 17class Person{ 18 id : number 19 name : string 20} 21 22

このような書き方だとうまくいきません

typescript

1 2class Model{ 3 member : Person[] = [] 4 5 constructor(responseStart){ 6 7 //↓仮にこのような値が来たとする 8 responseStart = [ 9 { id: 1 , name : "山田" }, 10 { id: 2 , name : "田中" } 11 ] 12 this.member = responseStart 13 } 14 15} 16 17class Person{ 18 id : number 19 name : string 20} 21 22

みたいにするか

typescript

1 2class Model{ 3 member : Person[] 4 5 constructor(responseStart){ 6 7 this.member = [] 8 9 //↓仮にこのような値が来たとする 10 responseStart = [ 11 { id: 1 , name : "山田" }, 12 { id: 2 , name : "田中" } 13 ] 14 this.member = responseStart 15 } 16 17} 18 19class Person{ 20 id : number 21 name : string 22} 23 24

このようにコンストラクターの最初にやるのでも大丈夫です。
昔のことだったので少しあやふやですが、確かこのような問題だった気がします。
回答遅れました。

投稿2018/08/17 09:10

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

TypeScript 不明なため適切な答えになっているかわかりませんが、子のコンポーネントで props が渡されたとき、propsの値の変化は watchを使って監視することができます。

投稿2018/06/22 11:55

euledge

総合スコア2404

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

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

退会済みユーザー

退会済みユーザー

2018/06/23 06:43 編集

回答ありがとうございます! なるほどです、たしかにその手がありましたね 月曜日会社で試してみます
退会済みユーザー

退会済みユーザー

2018/06/26 07:30

毎回child.vueコンポーネントは初期化されるので、watchでは違いを察知してくれないみたいです... 前の状態と今の状態から違いを得ようとしてもそもそも前の状態がない、みたいな現象になっちゃってます ちょっと考え直してみます、回答どうもありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問