WordPressのフロントエンドにVuejsを利用するに当たって、読み込んだPOSTにあとからスクリプトを適用することを試みました。
コードの部分について、WordPressからは、classによるlanguage設定がないすっぴんの状態(<code><pre>hogehoge</code></pre>
)で出力されるようにしています。
Twitter Widgetのスクリプトは読み込み済みである前提です
コンポーネント内
<script setup lang="ts">
// APIのURLを定義したファイル(/src/config.ts)をインポート
import { API_URL } from "@/config";
// highlight.jsをインポート
import hljs from "highlight.js";
import "highlight.js/styles/github.css";
// ルーティング
import { useRoute } from "vue-router";
import { ref, watch, nextTick } from "vue";
// 要素を参照
const htmlRef = ref<HTMLElement | null>(null);
// ポストをREST APIから読み込む
onMounted(async () => {
const slug = route.params.postSlug;
try {
const res = await fetch(`${API_URL}posts?slug=${slug}`);
if (!res.ok) {
error.value = `ステータスエラー: ${res.status} ${res.statusText}`;
return;
}
const data = await res.json();
if (data.length === 0) {
error.value = "該当する記事が見つかりません";
} else {
post.value = data[0];
}
} catch (e) {
error.value = `通信エラー: ${e.message}`;
console.error("Fetch error:", e);
}
});
watch(
() => htmlRef.value,
() => {
if (htmlRef.value) {
// Highlight.js
hljs.highlightAll();
console.log("Highlight.js 適用");
// twitter widgets
window.twttr.widgets.load();
console.log("Twitter widgets 適用");
}
},
{ immediate: true },
);
</script>
<template>
<main class="container mx-auto max-w-6xl px-4">
<div v-if="post">
<h1 v-html="post.title.rendered" class="mb-4 text-2xl font-bold" />
<div
v-html="post.content.rendered"
ref="htmlRef"
class="wp-post-content"
/>
</div>
<div v-else-if="error" class="text-red-600">{{ error }}</div>
<div v-else>読み込み中...</div>
</main>
</template>
/src/types/twitter.d.ts
export {};
declare global {
interface Window {
twttr?: {
widgets: {
load: (el?: Element) => void;
};
};
}
}