前提・実現したいこと
html.erb内に表示させてあるvueファイルを上部に表示させたいです。
どういうことかというと
index.html.erb
1 2<script> 3var user = <%= { id: current_user.try(:id) }.to_json.html_safe %>; 4</script> 5 6<%= javascript_pack_tag 'hello_vue' %> 7 8<% provide(:title,"Home")%> 9 10<div class="suggest-coffee-title"> 11 <% case @favorite_body_id 12 when 2%> 13 浅煎りのコーヒーが好きなあなたに 14 <% when 3%> 15 中煎りのコーヒーが好きなあなたに 16 <% when 4%> 17 深煎りのコーヒーが好きなあなたに 18 <% end %> 19</div> 20<%= render 'drinks_index',drink: @drink, drinks: @drinks,title: @title%> 21 22
このように書けば、先に(上部に)app.vueの内容が表示されて、
その下に、index.html.erbの
<%= render 'drinks_index',drink: @drink, drinks: @drinks,title: @title%>
renderされたテンプレートが表示されると思ったのですが、
先にindex.html.erbのテンプレートが表示されてしまいました。
なので、index.html.erbに書いてあるとおり、
先にapp.vueを表示させて、その次に_drinks_index.html.erbを表示させたいです。
該当のソースコード
https://github.com/Harasou21/coffee_passport
teratailに文字数制限があるため、
お手数ですが、githubをご確認いただければ幸いです。
app.vue
app.vue
1 2 3<template> 4<div ref='mainJs' id="main-js"> 5 <div class="playing-button"> 6 <button class="playing-button-on" @click="pauseVideo" v-if="playing">BGMをOFF</button> 7 <button class="playing-button-off" @click="playVideo" v-else>BGMをON</button> 8 </div> 9 10 11 12 <div id="show-suggest" class="show-suggest" v-if="this.isSuggest"> 13 <button @click="showSuggest()">おすすめ商品の表示を許可</button> 14 </div> 15 <div class="show-suggest" v-else> 16 <p>thanks!!</p> 17 </div> 18 19 20 <div class='item-contents' id="item-contents"> 21 <router-view :user_id="user_id"></router-view> 22 <h2 class='title' id="title">タイムライン</h2> 23 <youtube :video-id="videoId" ref="youtube" @playerVars="playerVars" hidden/> 24 25 26 27 <ul class='item-lists' id="timeline"> 28 <li v-for="drink in drinks" :key="drink.id" class="list" > 29 <router-link to="/user" @click.native="getUserId(drink.user_id)"> 30 <div class="user-info-timeline" > 31 <div v-if="drink.user_img"> 32 <img class="user-img-timeline" v-bind:src="drink.user_img" > 33 </div> 34 <div v-else> 35 <img class="user-img-timeline" src ="https://images.unsplash.com/photo-1469334031218-e382a71b716b?ixid=MnwxMjA3fDB8MHxzZWFyY2h8NXx8YnJlYXV0aWZ1bCUyMGdpcmx8ZW58MHx8MHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=700&q=60"> 36 </div> 37 <div class="username-timeline"> 38 {{drink.nickname}} 39 </div> 40 </div> 41 </router-link> 42 43 44 <div class='item-img-content'> 45 <img class= "item-img" v-bind:src="drink.image" > 46 </div> 47 <div class='item-info'> 48 <h3 class="item-name"> 49 {{drink.name }} 50 </h3> 51 <div class='item-price'> 52 <span>{{ drink.price }}円<br>(税込み)</span> 53 </div> 54 <div class='item-explain'> 55 {{drink.explain}} 56 </div> 57 <div class='item-tag'> 58 59 </div> 60 <div class="like-and-comment"> 61 <likeButton :drinkId=drink.id></likeButton> 62 <i class="far fa-comment fa-lg"></i> 63 <button v-on:click="show(drink)">詳細を表示</button> 64 </div> 65 </div> 66 <modal v-bind:name="'display-drink-'+drink.id" 67 height="1000px" 68 styles="background-color: bisque"> 69 <drinkShow :drink=drink></drinkShow> 70 </modal> 71 <div v-if="drink.body_id === 2" class="body-light"></div> 72 <div v-else-if="drink.body_id === 3" class="body-medium"></div> 73 <div v-else-if="drink.body_id === 4" class="body-full"></div> 74 <div v-else class="body-nothing"></div> 75 76 <div v-if="drink.acidity_id === 2" class="acidity-low"></div> 77 <div v-else-if="drink.acidity_id === 3" class="acidity-medium"></div> 78 <div v-else-if="drink.acidity_id === 4" class="acidity-high"></div> 79 <div v-else class="acidity-nothing"></div> 80 </li> 81 </ul> 82 83 </div> 84 <div class="pop-up" id="pop-up" v-if="popUpTemplate"> 85 <drinkShow :drink="this.drink"></drinkShow> 86 <div class="suggest"> 87 <h1 class="suggest-text">このコーヒーを買いますか?</h1> 88 <button @click="transitionForBuy" class="suggest-btn">買う</button> 89 <button @click="hideSuggest" class="hide-suggest-btn">おすすめ商品を以後表示しない</button> 90 </div> 91 </div> 92</div> 93</template> 94 95<script> 96 97import axios from 'axios'; 98import likeButton from './packs/components/like/likeButton.vue'; 99import drinkShow from './packs/components/drinks/show.vue'; 100 101 102export default { 103 name: 'player', 104 props: { 105 src: "https://www.youtube.com/watch?v=02azSAMtZWU" 106 }, 107 components: { 108 likeButton, 109 drinkShow, 110 }, 111 data: function(){ 112 return { 113 drinks: "drinks", 114 drink: "drink", 115 popUpTemplate: false, 116 user_id: 0, 117 isSuggest: true, 118 videoId: "QN1uygzp56s", 119 playing: false, 120 playerVars: { 121 autoplay: 1 122 } 123 } 124 }, 125 created(){ 126 this.setDrink(); 127 128 }, 129 mounted: function(){ 130 // this.playVideo(); 131 this.replaceEl(); 132 window.addEventListener('scroll', this.popUp); 133 }, 134 methods: { 135 setDrink: function(){ 136 axios.get('/api/drinks') 137 .then(response =>( 138 this.drinks = response.data 139 )) 140 }, 141 replaceEl: function(){ 142 const railsEl = document.getElementById("main-wrapper") 143 const vueEl = this.$refs.mainJs 144 const parent = railsEl.parentNode 145 console.log(railsEl) 146 console.log(vueEl) 147 parent.body.insertBefore(railsEl,vueEl) 148 }, 149 show : function(drink) { 150 this.$modal.show(`display-drink-${drink.id}`); 151 }, 152 hide : function () { 153 this.$modal.hide('display-drink-show'); 154 }, 155 playVideo(){ // 再生処理 156 this.$refs.youtube.player.playVideo() 157 this.playing = true 158 }, 159 pauseVideo(){ // 停止処理 160 this.$refs.youtube.player.pauseVideo() 161 this.playing = false 162 }, 163 getUserId(user_id){ 164 this.user_id = user_id 165 document.getElementById("timeline").style.visibility ="hidden"; 166 document.getElementById("title").style.visibility ="hidden"; 167 scrollTo(0, 0); 168 }, 169 popUp(){ 170 if( localStorage.getItem('suggest') !== "false" && window.scrollY > 200 && window.scrollY < 800 ){ 171 axios.get('/api/drinks/10') 172 .then(response =>( 173 this.drink = response.data 174 )) 175 this.popUpTemplate = true 176 this.isSuggest = true 177 document.getElementById("item-contents").style.opacity = 0.1 178 179 }else if(window.scrollY> 900 || window.scrollY < 200){ 180 this.popUpTemplate = false 181 document.getElementById("item-contents").style.opacity = 1.0 182 } 183 }, 184 transitionForBuy(){ 185 document.getElementById("buy-path").click() 186 }, 187 showSuggest(){ 188 localStorage.setItem("suggest",true) 189 this.isSuggest = false 190 }, 191 hideSuggest(){ 192 this.popUpTemplate = false 193 this.isSuggest = true 194 document.getElementById("item-contents").style.opacity = 1.0 195 document.getElementById("show-suggest").style.opacity = 1.0 196 localStorage.setItem('suggest', false) 197 } 198 } 199} 200 201 202 203</script> 204 205<style scoped> 206.pop-up{ 207 position: absolute; 208 top: 500px; 209} 210 211.suggest{ 212 text-align: center; 213} 214 215.suggest-text{ 216 217} 218 219.suggest-btn{ 220 221} 222 223 224 225</style> 226
試したこと
親要素にflexをあてて、子要素にorderを指定するcssの方法も調べたらあって、
親要素にflexをあてたらレイアウトが崩れたのであまりやりたくありません。
app.vue
app.vue
1 replaceEl: function(){ 2 const railsEl = document.getElementById("main-wrapper") 3 const vueEl = this.$refs.mainJs 4 const parent = railsEl.parentNode 5 console.log(railsEl) 6 console.log(vueEl) 7 parent.body.insertBefore(railsEl,vueEl) 8 }, 9
mountedのタイミングでこのMethodを発火させたら、
vue.esm.js:648 [Vue warn]: Error in mounted hook: "TypeError: Cannot read properties of undefined (reading 'insertBefore')"
TypeError: Cannot read properties of undefined (reading 'insertBefore')
railsElとVueElは同じ階層、並びなのですがエラーがでました。
なぜこのようなエラーがでたのか分かっていません。
ほかに良い方法があれば教えてほしいです。よろしくお願いいたします。
補足情報(FW/ツールのバージョンなど)
docker,ubunts,ホストOSはmac OS,raiis 6.1.3,ruby 2.6.5,@vue/cli 4.5.13
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。