Ruby on Rails + Slim 環境で Vue.js の Slot を使う。
バージョン情報
Ruby 2.7.1
Rails 6.0.2.2
Vue 2.6.11
vue-turbolinks 2.2.2
解決したい問題
Ruby on Rails + Slim 環境で Vue の Slot を使いたい。
ネット上で情報が少なったので、記録しようと思う。
試行錯誤して、動いたものを以下記載する。
Vue公式 名前付きスロット
Slim
実装
Vue の単一ファイルコンポーネント
これは、公式にある通りに実装する。
<template>
<div>
<transition name="abc">
<slot name="sample-slot-abc"></slot>
</transition>
</div>
</template>
<script>
// 任意の処理
</script>
<style>
// 任意のstyle
</style>
Vue の単一ファイルコンポーネントを読み込むJavaScriptファイル
ここでの留意点は、コンポーネント名は、「SampleAbc」などのパスカルケースだが、コンポーネント名が、パスカルケースだと、Slim 側でレンダリングできない。
そのため、「sample-abc」などのケバブケースの名に命名しなおす。
import Vue from 'vue/dist/vue.esm'
import TurbolinksAdapter from 'vue-turbolinks'
Vue.use(TurbolinksAdapter)
import SampleAbc from '../vue-components/SampleAbc.vue'
/**
* @description Vue の単一ファイルコンポーネントのルート。
* @param {void}
* @returns {void}
*/
const sampleVueRender = () => {
const rootElement = document.getElementById('js-vue-root')
if (rootElement === null) {
return
}
Vue.component('sample-abc', SampleAbc)
new Vue({
el: rootElement
})
}
document.addEventListener('turbolinks:load', sampleVueRender)
ここでは、仮に、application.js
でグローバルに読み込むものとする。
+ require('packs/sample_vue_render')
Slim側
sample-abc
コンポーネントは、単に sample-abc
で良いようだ。
また、<template> も同様に、template
と書く。
名前付きスロットは、slot="sample-slot-abc"
で動作した。
Vue 2.6.0 で v-slot
ディレクティブが導入され、slot
属性は、非推奨のようだ。
しかし、v-slot
だと、どうしても Rails + Slim 環境で動かすことができなかった。
何かご存じの方がいらっしゃれば、コメント欄でお教えいただけるとありがたい。
#js-vue-root
sample-abc
template slot="sample-slot-abc"
// ここにSlotに入れる要素が入ります。
p
| Hello World
以上で、ブラウザには、「Hello World」と表示される。
あとは、Vue の transition でアニメーションをつけたり、クリック等のアクションで、動的に表示非表示を切り替えたり、など自由に処理を追加する。
まとめ
主なポイントは、
- コンポーネント名は、JavaScript のパスカルケースから、Slim でレンダリングできるようにケバブケースにリネームする。
- Slim 側では、
template slot="sample-slot-abc"
のように、記述する。
であると思う。
2点目は、別解があるかもしれない。
-
Slim で syntax highlight ができないため、pug で syntax highlight を入れている。 ↩︎
Discussion