www.udemy.com
こちらのReactの講座途中まで終わって、あーVue.jsでもこうすればいいんだなぁという点があったので書く。
※書いているコードは、直接この記事で書いちゃったのでtypoミスなどなにかしらのミスがあるかもしれません。
今まで
こんなふうに、メンバー登録ができて、かつ登録済のメンバーの一覧が下部に表示されるようなページがあたっとします。
こんなページ
こんなとき、Vueで以下のような構成でつくってました。
Vueの構成
- フォームの内容を登録するコンポーネントである、CreateFormComponent
- 登録済の内容を表示する、MemberListComponent
- 上記二つを束ねる、index.js
CreateFormComponentには、こんな感じでaxiosでデータを登録する箇所を実装しています。
データを登録した際の結果として、登録済のメンバーの一覧すべてが返却されてきます。
なので、この結果をメンバーリストを表示するSearchComponentに渡したい、という要望がでてきます。
CreateFormComponent.vue
onSubmit() {
axios.post(ENTORY_POINT, {
name: name,
color: color,
})
.then((res) => {
console.log(res.data);
})
.catch((error) => console.log(error));
}
CreateFormComponentからSearchComponentに値を渡すときは、直接渡すことはできない?のでVueの親コンポーネントに情報を渡す、でおなじみのemitを使って一度親にデータを渡して、そこからSerachComponentに渡すかと思います。
CreateFormComponent.vue
onSubmit() {
axios.post(ENTORY_POINT, {
name: name,
color: color,
})
.then((res) => {
this.$emit('data', res,data);
})
.catch((error) => console.log(error));
}
こんなかんじにemit
で指定したイベント名をcreate-fom
に定義して、
index.html
<div class="app">
<create-fom @data="setData"></create-fom>
<search-form ></search-form>
</div>
<srcipt src="index.js"></script>
index.js
でデータを同期するようのメソッドsetData
を定義してあげたりしていました。
index.js
new Vue({
el:'.app',
components:{
},
data:{
members: [],
}
methods:{
setData(data) {
this.members = data;
}
}
);
最終的に、SerachFormComponentにはプロパティとして、members
を渡せばやりたいことはできますね。
index.html
<div class="app">
<create-fom @data="setData"></create-fom>
<search-form :members="members"></search-form>
</div>
<srcipt src="index.js"></script>
コンポーネント同士でデータを共有したい場合は、その値を親にまでもってくる、というところはVueだろうがReactだろうか一緒ですね。
Captcha
上記より引用
複数の子コンポーネントからデータを集めたい時や、2つの子コンポーネント同士でやりとりを行わせたい時は、状態(state)を親コンポーネントまで渡すようにします。親コンポーネントはその後、状態(state)をpropsを通して子コンポーネントに渡します。そのため子コンポーネントは常に互いに同期するようになっています。また同様に親コンポーネントとも同期するようになっています。
Reactを学習した際の気づき
気になったのは、親コンポーネントにデータをもってきたときに、そのデータの変更を行う処理も親にもってきている点です。
さきほどのコードを変更するとこんな感じになります。
まず、大本のindex.js
にmembers
更新するaxiosの処理をCreateFormComponentよりもってきて、crreateMember
という関数で作成します。
CreateFormComponent内にあるnameとcolorは、引数としてもらうようにします。
index.js
new Vue({
el:'.app',
components:{
},
data:{
members: [],
}
methods:{
createMember(props) {
axios.post(ENTORY_POINT, {
name: props.name,
color: props.color,
})
.then((res) => {
this.members = res.data;
})
.catch((error) => console.log(error));
}
}
);
そして、さきほどつくったcreateMember
関数を、CreateFormComponentにプロパティとして渡してあげます。
index.html
<div class="app">
<create-fom :handleSubmit="createMember"></create-fom>
<search-form :members="members"></search-form>
</div>
<srcipt src="index.js"></script>
最後にもともとあったボタンをおしたときの処理は、バインドしたデータを親からもらった関数に渡して実行するだけです。
CreateFormComponent.vue
props:handleSubmit
onSubmit() {
this.handleSubmit({name:this.name, color:this.color});
}
こうすることで、emitがいらなくなり、またデータ更新処理があちこちに散らばらなくなりました。