Nuxtでamp-imgのsrcを動的に変更する
エンジニア向けの記事です。めちゃくちゃニッチな内容です。amp-imgをlayoutsで使った時に画像が切り替わらないのを直すという内容です。
対象の事象
layoutsでamp-imgを使ってるけど、ページ遷移しても画像が切り替わらない
結論
画像のkeyにランダムな値を挿入して強制的に再描写させます。
※pageはpagesからアップするstateです。titleとかを上げる想定です。
layouts/任意のファイル.vue
<template>
<div>
<amp-img
:key="randomKey"
width="1.3"
height="1"
:src="page.src"
alt="header"
/>
</div>
</template>
<script>
export default {
name: 'PageHeader',
data() {
return {
randomKey: ''
}
},
computed: {
page() {
return this.$store.state.page
}
},
watch: {
page() {
this.randomKey = Math.random()
}
}
}
</script>
今回はページごとに全て違う画像を表示させる前提ですが、そうでない(同じ画像のページが複数ある)場合はpage.srcでの照合をかけてからrandomKeyを再計算させるといいでしょう。
原因
amp-imgはamp-imgに指定されたsrcを元にampがimgタグを作成します。
この動作はページ読み込み時にされるので、spaには対応しておらず、amp-imgのsrcは変わるのにimgのsrcは変わらず画像がそのままになっていました。
1. ページ読み込み時にamp-imgにsrc注入
2. amp scriptがamp-imgのsrcを元にimgタグ作成
3. ページ遷移時にamp-imgのsrc変更
4. srcが書き換わっただけなのでamp-imgは感知せず
5. imgタグは変わらないので画像は何も変わらない
という感じです。
参考までに、amp-imgのamp script作動前後のhtmlを書いておきます。
作動前
<amp-img alt="header" src="hoge" width="1.3" height="1" layout="responsive" data-amp-auto-lightbox-disable=""></amp-img>
作動後
<amp-img alt="header" src="hoge" width="1.3" height="1" layout="responsive" data-amp-auto-lightbox-disable="" class="i-amphtml-element i-amphtml-layout-responsive i-amphtml-layout-size-defined i-amphtml-layout" i-amphtml-layout="responsive" style="--loader-delay-offset:147ms !important;">
<i-amphtml-sizer slot="i-amphtml-svc" style="padding-top: 50%;"></i-amphtml-sizer>
<img decoding="async" alt="header" src="hoge" data-amp-auto-lightbox-disable="" class="i-amphtml-fill-content i-amphtml-replaced-content">
</amp-img>