https://qiita.com/divclass123/items/71465f7a6c313a533eeb
前回の続き。
前回投稿一覧をVue.jsで記述したので、投稿一覧でなにかしらボタンを押したら、
投稿詳細ページが出てくるてきなやつをやってみたい!
動的なページがしっかりと動くのか不安。
https://github.com/euvl/vue-js-modal?ref=kabanoki.net
v-modalで簡単に実装できるからやってみよ。
フロントにvue-jsを使うといろんなライブラリで色々できるからいいね。
https://www.kabanoki.net/3144/
参考記事
下準備
npm install vue-js-modal --save
<div id="app">
<button v-on:click="show" class="button">show!</button>
<modal name="hello-world" :draggable="true" :resizable="true">
<div class="modal-header">
<h2>Modal title</h2>
</div>
<div class="modal-body">
<p>you're reading this text in a modal!</p>
<button v-on:click="hide">閉じる</button>
</div>
</modal>
</div>
Vue.use(window["vue-js-modal"].default);
var app = new Vue({
el: '#app',
methods: {
show : function() {
this.$modal.show('hello-world');
},
hide : function () {
this.$modal.hide('hello-world');
},
}
})
まぁなんとなく雰囲気は掴んだ。
<modal>
<drinkShow></drinkShow>
</modal>
import drinkShow from './packs/components/drinks/show.vue'
としたら、
app.vue:69 Uncaught Error: Cannot find module './packs/components/like/likeButton.vue'
と、前まで上手くいってた
コンポーネントの読み込みができなくなってる。
show.vueを読み込んだことにより、show.vueのほうでエラーが起きてた。
エラーメッセージが分かりづらい。。。
モーダルウィンドウは実装できたが、、、
import Vue from 'vue'
import VModal from 'vue-js-modal'
Vue.use(VModal)
と記載することでできた。
が、モーダルウィンドウの表示がいかんせんおかしい。
この白の部分がモーダルウィンドウ。
んーー。
https://naito-coding0322.hatenablog.com/entry/2018/12/31/002712
まず考えられるのが、
show.vue
で{{drink.name}}
とかやってるが、そのデータの参照先が前までapi::controllerからjbuilderでjson形式でデータを送信したものを参照してたので、{{drink.name}}が効かなくなってる。
ってことで、親コンポーネントから子コンポーネントにデータを渡す。
ただ、それだったらHTML/CSSくらいは、機能しても良い気がする。
そこに関してはvue-js-modalの問題なのか。
<modal name="display-drink-show" :drink="drink">
こんなかんじでコンポーネントを利用した場合に変数を渡して動的なページをモーダルウィンドウ化させることができるらしい。
<modal name="display-drink-show" >
<drinkShow :drink=drink></drinkShow>
</modal>
export default {
props: ['drink']
コンナ感じで親から子にデータを受け渡して、たぶんできた。
だがしかし、表示がおかしい。CSSの問題なのであとで直せる。
それよりクリティカルな問題なのが
<li v-for="drink in drinks" :key="drink.id" class="list" >
<modal name="display-drink-show" >
<drinkShow :drink=drink></drinkShow>
</modal>
</li>
こんな感じで書いてるので、drinksの配列の文だけモーダルウィンドウが繰り返し表示される。
かといって、
<li v-for="drink in drinks" :key="drink.id" class="list" >
</li>
<modal name="display-drink-show" >
<drinkShow :drink=drink></drinkShow>
</modal>
これだと、drinkが定義されていないので、エラーになる。
原因はshow()が繰り返されてモーダルウィンドウが繰り返し、配列分表示されてしまうので、
<li v-for="drink in drinks" :key="drink.id" class="list" >
<modal name="display-drink-{{drink.id}}" >
<drinkShow :drink=drink></drinkShow>
</modal>
<button v-on:click="show">詳細を表示</button>
</li>
<script>
show : function() {
this.$modal.show('display-drink-{{drink.id}}');
},
</script>
とかやれば(変数展開の文法が正しいかは置いといて)、drink.idはかぶらないので、繰り返し表示されないとおもったが
drinkはv-forの中のローカル変数なので、show()でdrinkを持ってくることができない。。。
show : function() {
this.drinks.forEach(drink => {
this.$modal.show(`display-drink-${drink.id}`);
});
},
試しにこんな感じで書いてみた。うーーんどうだろう。
<li v-for="drink in drinks" :key="drink.id" class="list" >
<modal name="display-drink-7" >
<drinkShow :drink=drink></drinkShow>
</modal>
<button v-on:click="show">詳細を表示</button>
</li>
show : function() {
this.drinks.forEach(drink => {
this.$modal.show(`display-drink-${drink.id}`);
console.log(`display-drink-${drink.id}`)
});
},
こう書いても、配列分繰り返してモーダルウィンドウが表示されてしまった。
んー、、、。
display-drink-11
display-drink-10
display-drink-9
display-drink-8
display-drink-7
かぶらないようなmodalのnameオプションに指定するものができたが、
<modal name="display-drink-7" >
<drinkShow :drink=drink></drinkShow>
</modal>
<button v-on:click="show">詳細を表示</button>
自分の予想では一回しか表示されないはずだが、、、なぜが配列分モーダルウィンドウが表示されている、。。。
テンプレート部分からスクリプト部分にデータを渡すことができれば、、、、。んーー。どうだろう。
自分の予想では一回しか表示されないはずだが、、、なぜが配列分モーダルウィンドウが表示されている、。。。
ってことは、modal部分が繰り返し処理の中にあると、modalのnameがたとえ一意性があっても、
繰り返し処理される。ってことだから、
<li v-for="drink in drinks" :key="drink.id" class="list" >
<button v-on:click="show">詳細を表示</button>
</li>
<modal name="display-drink-7" >
<drinkShow :drink=drink></drinkShow>
</modal>
modal部分をv-forの外に記述するが、
さっきもいったが、drinkはv-forの中でしか使えない。
にっちもさっちもいかない状態である。。。。
drinksのshowにどうやってデータを渡すかが鍵になってくる。。。。
https://shimablogs.com/vue-modal
俺のやりたいことがあった。
「メソッドを引数として」
といった記述があったので、それをヒントに。
<button v-on:click="show(drink)">詳細を表示</button>
show : function(drink) {
this.$modal.show(`display-drink-${drink.id}`);
},
<modal name="display-drink-7" >
<drinkShow :drink=drink></drinkShow>
</modal>
やってることはさっきと変わらないきがするが、どうなんだ。
drink.idが7のやつだけ反応してモーダルが表示されたが、
表示されるときにやはり、たくさん表示されてしまう。
てか、hideメソッド定義してないからじゃね。って思ったので、
一旦やってみるか。
<button v-on:click="hide()">戻る</button>
methods: {
hide : function () {
this.$modal.hide('display-drink-7');
}
}
とやったらいけたので、
<modal name="display-drink-${drink.id}" >
<drinkShow :drink=drink></drinkShow
</modal>
みたいなことをしたいわけだが、そうは問屋がおろさない。
v-bindとは?属性を動的に設定できる機能
がvue.jsにあるっぽいので、それをやるしかない
<modal v-bind:name="'display-drink-'+drink.id" >
<drinkShow :drink=drink></drinkShow>
</modal>
とやってみた。
したらいけた!!やったぜ!!!!
いやー、ガチで天才すぎるわ。俺。
属性を動的に変えたいと思ってそこからぐぐったらv-bind出てきて、リファレンス見てできちゃった。
しかも配列分モーダルが表示される問題があったが、それもなく。戻るボタン押さずにそれ以外の部分押しても
しっかりと投稿一覧に戻ってくれる。
あとは、見た目が。。。
恐らく、最大の問題はmodal部分のheightが足りていない。。。。
#モーダルウィンドウの見た目を整える
モーダルウィンドウを開いたときに検証ツールで見てみたら、
#modals-containerみたいなのあったので、
<style scoped lang="scss">
#modals-container{
height: 400px;
}
</style>
としてみる。
効かない
これも効かない
<modal v-bind:name="'display-drink-'+drink.id"
height="1000px"
styles="background-color: bisque">
<drinkShow :drink=drink></drinkShow>
</modal>
これでできるっぽい。。。
んーーー。。やったぜ!!??
でもそうじゃないというのが本音。
まぁ、scriptの方にstyleを定義したやつをまとめるほうが良い気がするがまあいいだろう。。
このように表示できた。
一旦成功のように見えるが、実はいいねボタンを押しても機能はしてるが、
モーダルウィンドウを表示していいねを押して、戻ったときに
いいねが押されてない。ことになっている。リロードすると
元の投稿にいいねがつくようになってる。
子コンポーネントの動作と、親コンポーネントの動作が微妙に一致してないので、
次回はそこを修正