公式には、CDNとaddEventListener(Load)による実装方法の記載しか無かったので、
VueJSでの実装方法を簡単に記しておきます。
実装方法
code-prettifyはファイルを読み込んで実行するため、ページが再レンダリングされたときに再実行されず、機能しなくなります。
ページがレンダリングされる度に実行するために、mountedと[nextTick()] (https://jp.vuejs.org/v2/api/index.html#Vue-nextTick)を使用して実装する必要があります。
mountedとは
mountedとは、Vueインスタンスが生成時に行う一連の初期化をする過程の中で、インスタンスがマウントされた後に呼ばれる、DOM要素にアクセスすることができるライフサイクルフックです。
公式ドキュメントの[ライフサイクルダイアグラム] (https://jp.vuejs.org/v2/guide/instance.html#%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B5%E3%82%A4%E3%82%AF%E3%83%AB%E3%83%80%E3%82%A4%E3%82%A2%E3%82%B0%E3%83%A9%E3%83%A0)を一読し、初期化の過程を理解しておきましょう。
nextTick()とは
Vueはdataの変更に基づいてDOMを更新しますが、dataを変更しただけではレンダリングに反映されません。
nextTick()を使用することで、DOMの更新後にレンダリングに反映させることができます。
これは、Vueのdataが変更された後でページがレンダリングされる前に実行されるためです。
実際にはnextTick()に登録したコードがDOMの更新後に(コールバックで)呼び出されてます。
公式ドキュメントの[非同期更新の理解] (https://012-jp.vuejs.org/guide/best-practices.html#%E9%9D%9E%E5%90%8C%E6%9C%9F%E6%9B%B4%E6%96%B0%E3%81%AE%E7%90%86%E8%A7%A3)で、仕組みについて見ておくと、イメージしやすいかと思います。
mountedとnextTick()の組み合わせ
mountedとnextTick()を組み合わせることで、DOM要素にアクセスできるようになったタイミングで、ページがレンダリングされる度にコードを実行することができます。
mounted: function () {
this.$nextTick(function () {
// レンダリングする度に実行
})
}
サンプルの実装前の準備
まずはcode-prettifyをダウンロード
https://github.com/google/code-prettify/tree/master/distrib
サンプルで使用したバージョンはこちら
"vue": "^2.5.11"
ディレクトリ構造はこちら
/root/
├ App.vue
├ main.js
├ mixin.js
├ /vendors/
├ /google-code-prettify/ (ダウンロードしたファイル)
├ /components/
├ sample.vue
サンプルのソースコード
// VueとVueRouterを読み込む
import Vue from 'vue'
import VueRouter from 'vue-router'
// code-prettifyを読み込む
import './vendors/google-code-prettify/prettify';
// コンポーネントを読み込む
import App from './App'
import Sample from './components/sample'
// ルーターのインストール
Vue.use(VueRouter);
// ルート設定
const routes = [
{
path: '/',
component: App,
path: '/sample',
component: Sample,
}
];
// ルーターインスタンス作成
const router = new VueRouter({
routes: routes
});
// Vueインスタンス作成
const app = new Vue({
el: '#app',
router: router,
});
<template>
<div id="app">
<ul>
<router-link tag="li" to="/">Home</router-link>
<router-link tag="li" to="/sample">Sample</router-link>
</ul>
</div>
</template>
<style>
/* code-prettifyのスタイルを読み込む */
@import './vendors/google-code-prettify/prettify.css';
@import './vendors/google-code-prettify/skins/sons-of-obsidian.css';
</style>
<template>
<pre class="prettyprint lang-html linenums">
<div>hoge</div>
</pre>
</template>
<script>
export default {
mounted () {
this.$nextTick(() => {
PR.prettyPrint();
})
},
};
</script>
さらにmixinでモジュール化すると使い回しがききます
module.exports = {
mounted () {
this.$nextTick(() => {
PR.prettyPrint();
})
},
};
<template>
<pre class="prettyprint lang-html linenums">
<div>hoge</div>
</pre>
</template>
<script>
import mixin from '../../mixin';
export default {
mixins: [mixin]
};
</script>