7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

VueJSでcode-prettifyを使ってページにソースコードを表示する

Last updated at Posted at 2018-06-14

公式には、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

サンプルのソースコード

main.js
// 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,
});
App.vue
<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>

sample.vue
<template>
  <pre class="prettyprint lang-html linenums">
    <div>hoge</div>
  </pre>
</template>

<script>
export default {
  mounted () {
    this.$nextTick(() => {
      PR.prettyPrint();
    })
  },
};
</script>

さらにmixinでモジュール化すると使い回しがききます

mixin.js
module.exports = {
  mounted () {
    this.$nextTick(() => {
      PR.prettyPrint();
    })
  },
};
sample.vue
<template>
  <pre class="prettyprint lang-html linenums">
    <div>hoge</div>
  </pre>
</template>

<script>
import mixin from '../../mixin';

export default {
  mixins: [mixin]
};
</script>
7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?