Prism 在 Vue 组件中不起作用

Prism not working inside Vue component

我需要源代码高亮显示。我正在使用 Prism.

我尝试将此代码粘贴到 app 的根目录中,它被成功突出显示:

<div id="app">
  <div class="MainContainer">
    <div class="Header">
      <a href="#">past-code</a>
    </div>
    <component v-bind:is="currentView"></component>
    <code class="language-dart">void main() { } class MyClass {} </code>
    <div class="Footer">
      footer
    </div>
  </div>
</div>

但是当我在一个组件中放置相同的代码时,突出显示停止工作:

Vue.component('view-form', {
  template: `
    <div class="ViewCodeContainer">
    <div class="ViewCode">my code here</div>
    <code class="language-dart">void main() { } class MyClass  </code>
    <div class="ViewCodeMenu">my menu here</div>
    </div>`
})

var app = new Vue({
  el: '#app',
  data: {
    currentView: 'view-form',
    mycode: ''
  }
})

这是它在浏览器中的样子:

看起来 Prism 在 Vue 组件中不起作用。有什么办法可以在不使用 npm 的情况下强制它工作吗?

新答案:

现在有一个专用于 Prism.js 与 Vue 一起使用的库,查看它:https://github.com/egoist/vue-prism-component

<template>
  <prism language="javascript">{{ code }}</prism>
</template>

<script>
import Prism from 'vue-prism-component'

export default {
  data() {
    return {
      code: 'const a = b'
    }
  },
  components: {
    Prism
  }
}
</script>

旧答案:

它确实有效,参见 fiddle: https://jsfiddle.net/x2ax7b2d/

请确保您在此处选择的构建中包含了您正在使用的语言(此处为 dart):http://prismjs.com/download.html

但是,Prism 正在以不符合 vue 的方式修改 DOM。更准确地说,它将您的 <code> 元素转换为 vue 无法控制的多个元素。

所以在某些情况下你可能会遇到问题。特别是,虽然您可以在第一次渲染时集成一些模板值,请参阅: https://jsfiddle.net/Lvn7e3n2/

...您绝对无法刷新该值,至少不能轻易刷新,一旦它被 Prism 渲染,请参见: https://jsfiddle.net/svzvdo1n/

此外,如果由于某些执行顺序原因它不起作用,您仍然可以使 Prism 重新渲染,使用(可能在组件的 mounted 事件中)Prism.highlightAll 或 Prism.highlightElement,请参阅 API 文档:http://prismjs.com/extending.html#api

我认为将原始 Prism.highlight() 与 v-html 结合用于高级用例可能会非常有趣。

编辑:我试过了,效果很好。乐趣。这很可能是结合 Vue 和 Prism 的最佳方式。

Vue.component('view-form', {
  template: `
    <div class="ViewCodeContainer">
    <div class="ViewCode">my code here</div>
    <div v-html="highlightedCode">
    </div>
    <textarea v-model="code"></textarea>
    <div class="ViewCodeMenu">my menu here</div>
    </div>`,
    data() {
        return {
        code: 'void main() { } class MyClass'
      }
    },
    computed: {
        highlightedCode() {
        return Prism.highlight(this.code, Prism.languages.dart);
      }
    }
})

查看完整代码: https://jsfiddle.net/e87Lnvn8/

如果您不想包含额外的库,也可以只添加这样的过滤器:

import Vue from 'vue'
import Prism from 'prismjs'

// Highlight some code
Vue.filter('highlight', (code, lang = 'javascript') => {
  return Prism.highlight(code, Prism.languages[lang], lang)
})

然后在您的组件模板中像这样使用它:

<pre>
  <code class="language-javascript" v-html="$options.filters.highlight(code)">
  </code>
</pre>

class="language-css"$options.filters.highlight(code, 'css')用于css等,此处默认为javascript。

code 变量是在某处定义的字符串,通常在组件的数据部分:

data () {
  return {
    code: 'const world = "flat"'
  }
}

要使 Prism CSS 主题正常工作,请在 main.js 中执行 require('../node_modules/prismjs/themes/prism.css')。将 prism.css 换成 prism-tomorrow.css 以更改您的主题。主题列表可在 node_modules/prismjs/themes 目录中找到。

对我来说,问题是我需要打电话给:

mounted() {
     Prism.highlightAll();
},