2019.11.21
Vueでカクテルデータベースをリファインする話#24【syncと3世代双方向バインディング】
まためんどくさいことしてるので書きます。
この前親子間のイベントの同期を取ろうと思って、.syncを習得したわけですが、じゃあ3世代間だとどうなるんだ、って話ですね。
で、ゴリゴリ実装してたらとくに記事にする必要性すら感じないコードができあがりました。
じゃん。(twitterから拝借)
僕の場合、こうせざるを得ませんでした。後で説明しますが、自分自身と同一のコンポーネントを再帰的に呼び出すような構造のせいで名前がダブっちゃう構造なので・・・・・・
とりあえず本来.syncで受け取るv-on=update:なんたらのところに、親に発行したいイベントをそのまま、受け取った値と共に放り投げれば親に値が行きます。
ここで僕がやりたかったのはnameというプロパティをbrand_nameに変えて渡す、ってのがやりたかったんですけど、まぁこれが限度でしたとさ。
んで、いま僕が何を作ってるかって話ですね。
しょせん自分しか使わない管理画面なのでデザインはめっちゃテキトーなんですが、ミドルカテゴリの新規登録画面ですね。正直これができたらメインカテゴリの新規登録とかは9割がたコンポーネントを再利用するだけで終わる計画です。言ってしまえばカクテルの場合も使いまわしができると思います。
で、問題となってるのはこの「新しく作成する」って部分ですね。その下に表示されてるのが、コンポーネントの再利用によりほぼ同じ構造になっているフォームなんですが、ここに新しく登録する銘柄の情報を書けるようにしたいわけですね。
んで、いまからこのフォームのバリデーションを定義したい・・・・・・ってなったんですけど、いま冷静に考えてみたら
このフォームのバリデーション定義自体はコンポーネント内に埋め込んで使いまわししたいな???って思ったわけです。
じゃあ、また$emitで引きずり回すの???って話なんですが、バリデーション自体はvalidatorjsを使ったオブジェクトです。しかもその挙動は子コンポーネントの値に依存してます。深く考えてませんけど、とりあえず
オブジェクトをemitで引きずり回すのは厳しいんじゃないか・・・・・・?と思います。理由はオブジェクトの中身のプロパティの変更をVueが感知できないからです。
ただ、このバリデーションに関しては
リアクティブであることは要求されてないんですよね。今回の場合。送信する時だけチェックできれば充分なので。
だったら
直接子コンポーネントのオブジェクトを見に行った方がはやくね???って思うわけです。まぁリアクティブな挙動が要求されたとしても、それは子コンポーネント内で閉じた挙動にできると思いますしあんま関係ないか・・・・・・
リアクティブにはできません、って言ってますね。やはり変更は感知できないみたい。
データフローに関してはpropsとemitでやりとりしましたが、データに手を加えるわけではなく直接データを読み込む・・・・・・っていうのは
$refってのを使うみたいです。
では、今回みたいに孫コンポーネントのバリデーションオブジェクトにアクセスするには・・・・・・???
ただ、今回の場合は孫コンポーネントということで、$refを引きずり回してアクセスするより、親要素の方に状態をもたせるようにして、子コンポーネントから更新させる、って感じにした方がいいような気がしてきました。
そうすることのメリットとしては、provideは子要素どころか孫要素にまで効果が波及するので、階層のことを考えなくてもよいわけですね。
・・・・・・って思ったのですが、全く同一のコンポーネントが子要素にも孫要素にもあると名前が衝突しますね。おとなしくリファレンスを引きずり回す方針に戻します(笑)
まぁこういうのは知識として持っておくと将来役に立つと思うんですよ、はい。
ってことで、噂の$refです。このような機構ですね。