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();
},
我需要源代码高亮显示。我正在使用 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();
},