【Vue3】v-htmlとは?使い方を紹介する
v-htmlとは
v-htmlとは、htmlを値に指定することで、そのままhtmlとして出力してくれるディレクティブ(vue独自の属性)です。Vue3で動きます。
v-htmlは非常に自由に使える反面、セキュリティに注意が必要なディレクティブです。
この記事を書いた人
@takasqr アプリケーション開発が大好きなエンジニア。Vue、Swift、Electrom などでアプリを作って公開している。AWS や Firebase などのクラウドサービスも好き。
v-htmlの使い方
data
に指定しているhtmlがそのまま、描画されます。
<script setup>
let html = '<h1>Page title</h1>'
</script>
<template>
<div v-html="html" />
</template>
v-htmlはxssに注意
v-html非常に自由に使える反面、セキュリティに注意が必要なディレクティブです。
特にユーザーが入力した値をそのままv-html
で使うのは絶対にやめましょう。
悪意のあるユーザーに悪用される恐れがあります。
<script>
import { ref } from 'vue'
export default {
setup() {
let html = ref('<h1>Page title</h1>')
return {
html
}
}
}
</script>
<template>
<input v-model="html" />
<div v-html="html" />
</template>
上の例だと、inputに入力した値がそのままhtmlとして描画されてしまいます。
上の例にはv-model
が登場します。詳しくはこちら。
v-htmlで出力したhtmlにCSSをあてる
v-htmlで出力したhtmlには単一ファイルコンポーネントのscoped
で設定したstyleが当たりません。v-htmlのhtmlにCSSを当てたい場合はディープセレクタというものを使う必要があります。
Deep Selectors | Scoped CSS | Vue Loader
これはうまくいかない。
<script>
import { ref } from 'vue'
export default {
setup() {
let html = ref('<h1>Page title</h1>')
return {
html
}
}
}
</script>
<template>
<div>
<input v-model="html" />
<div v-html="html" />
<h1>Page title</h1>
</div>
</template>
<style scoped>
h1 {
color: red
}
</style>
これだとうまくいく。
<script>
import { ref } from 'vue'
export default {
setup() {
let html = ref('<h1>Page title</h1>')
return {
html
}
}
}
</script>
<template>
<div class="title">
<input v-model="html" />
<div v-html="html" />
<h1>Page title</h1>
</div>
</template>
<style scoped>
.title >>> h1 {
color: red
}
</style>
さらにscss
を使っている場合は>>>
だとうまくいかないので、/deep/
か::v-deep
と書くといいようです。