はじめに
Laravel Mixで開発中に、Vueで<iframe>を使いたく試行錯誤し実装できたが、時間を要したので備忘録として記載しています。
開発状況(Version)
macOS Big Sur
Laravel Mix 6.0
Laravel 8.83.13
PHP 7.3.29
node.js 16.13.2
Vue.js 2.6.14
※ココから先のシェル名の「Bash」となっている箇所は全て「zsh」です。
「JavaScript」となっている箇所は全て「Vue.js」です。
ブログのコードエディターの言語設定に「zsh」、「Vue.js」がないため、「Bash」、「JavaScript」にしています。
結論
フォルダ構成
フォルダ構成は下記となっています。
src
|_resources
|_views
| |_list
| |_index.blade.php
|_js
|_components
|_VideoCard.vue
各フォルダに下記のように書けば、使用できます。
index.blade.php
----- 抜粋 -----
<div>
<video-card
:url='@json($video['url'])'
>
</video-card>
</div>
@section('script')
<script>
import VideoCard from "../../js/components/VideoCard";
export default {
components: {
VideoCard,
}
};
</script>
@endsection
※$video[‘url’]の中身は、「url」が入っています。
VideoCard.vue
<template>
<v-card
class="mx-auto"
max-width="344"
>
<iframe
width="290"
height="163.125"
:src="`https://www.youtube.com/embed/${url}`"
frameborder="0"
allow="accelerometer;
autoplay;
clipboard-write;
encrypted-media;
gyroscope;
picture-in-picture"
allowfullscreen
>
</iframe>
</v-card>
</template>
<script>
export default {
name: "VideoCard",
data() {
return {
url: this.url,
}
},
props: {
url: {
type: String,
}
},
}
</script>
<style scoped>
</style>
結論に辿り着くまでの流れ
元々、LaravelのBladeファイルに下記のように実装していたものを、Laravel Mixを使用して、Vue.jsにリファクタリングしています。
元々のフォルダ構成
src
|_resources
|_views
|_list
|_index.blade.php
元々のindex.blade.php
----- 抜粋 -----
<div>
@if($video)
<iframe
width="290"
height="163.125"
src="{{ 'https://www.youtube.com/embed/'.$video->url }}"
frameborder="0"
allow="accelerometer;
autoplay;
clipboard-write;
encrypted-media;
gyroscope;
picture-in-picture"
allowfullscreen
>
</iframe>
</div>
----- 抜粋 -----
単純に、元々のindex.blade.phpに書いていたコードを、そのままVideoCard.vueに移すと、こうなるが、
<template>
<v-card
class="mx-auto"
max-width="344"
>
<iframe
width="290"
height="163.125"
src="{{ 'https://www.youtube.com/embed/'.{{ url }} }}"
frameborder="0"
allow="accelerometer;
autoplay;
clipboard-write;
encrypted-media;
gyroscope;
picture-in-picture"
allowfullscreen
>
</iframe>
</v-card>
</template>
<script>
export default {
name: "VideoCard",
data() {
return {
url: this.url,
}
},
props: {
url: {
type: String,
}
},
}
</script>
<style scoped>
</style>
上記のように書いてもエラー(警告)が表示されます。
Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead. For example, instead of <div id="{{ val }}">, use <div :id="val">.
エラー内容は、そのままの通り、
昔は、<div id=”{{ val }}”>の書き方で良かったけど、今は<div :id=”val”>と書いてね。
という感じの意味。
エラー(警告)から読み解くに、こう書けば。。。
<template>
<v-card
class="mx-auto"
max-width="344"
>
<iframe
width="290"
height="163.125"
:src="'https://www.youtube.com/embed/'.{{ url }}"
frameborder="0"
allow="accelerometer;
autoplay;
clipboard-write;
encrypted-media;
gyroscope;
picture-in-picture"
allowfullscreen
>
</iframe>
</v-card>
</template>
<script>
export default {
name: "VideoCard",
data() {
return {
url: this.url,
}
},
props: {
url: {
type: String,
}
},
}
</script>
<style scoped>
</style>
これではうまくいかず、
というか、<iframe>内で、{{ url }}は使えない。
index.blade.phpから「$video[‘url’]」の中に格納されている「url」が欲しいので、考えた結果、
:src="`https://www.youtube.com/embed/${url}`"
にたどり着く。
これだと、` `で囲んでいるhttp:~は文字として認識される!
‘ ‘ (シングルコーテーション)ではなく、
` `なのでご注意を!
最後に
index.blade.phpにある変数を、Vue.jsで使用するため(渡すため)にv-bindを使用ということまでは、すぐにたどり着けだが、” ‘${url}’ ” にたどり着くまで時間がかかってしまった。
今後のために完全に備忘録です。
コメント