Vue.jsで iframe を使ってみた

Laravel/PHP
スポンサーリンク

はじめに

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}’ ” にたどり着くまで時間がかかってしまった。
今後のために完全に備忘録です。

参考記事

コメント