Closed Sjoerd closed 7 years ago
You can use the API! http://prismjs.com/extending.html#api
That doesn't work :/ (https://gyazo.com/b56294adf1375aed6156ee056da3ad21)
Hello,
someone had a similar issue, using highlightjs which does a similar job as Prism (check the lastest answer from LinusBorg).
I don't know if it's your case, but I guess you are updating your model (paste.content) from your Vue / Component instance and you are expecting the DOM to be updated and highlighted in the same time.
The problem is that Prism will update your model rendered value (raw string), then apply a lot of HTML transformations. Then VueJS won't be able to update the DOM. This is well described in the link I mentionned above :
- Either it's real HTML DOM elements, and Vue handles them (then {{content}} works),
- or it's supposed to be highlighted HTML markup, and highlightjs handles them underlying DOM elements that it needs to print it's highlighted text (then {{content}} won't work because highlightJS controls that DOM, not Vue).
One possible dirty solution is to update manually the DOM :
EDIT:
An exemple of code is :
watch: {
// Note : paste.content is declared as string and assume paste is defined in Vue data
'paste.content': function(value) {
let editor = document.querySelector('#editor code');
editor.innerHTML = value;
this.$nextTick(()=> Prism.highlightElement(editor));
}
}
One other option is to watch the paste object using the deep option which will help you to observe inner property change:
watch: {
// Observe paste instance defined in Vue data using the deep option
paste: {
handler(value) {
let editor = document.querySelector('#editor code');
editor.innerHTML = value;
this.$nextTick(()=> Prism.highlightElement(editor));
},
deep: true
}
}
Hope it will help you
It doesn't work for me, the [dot] between paste and content (paste.content) is unexpected.
Sorry, I bring some corrections. To watch paste inner property, the syntax should be 'paste.content': function(value)
Please check the previous edited answer.
@haryratsimba thank You so much! It works :)
I wonder if something like this would help, but where the mutation observer tracks the content of the <code>
elements, not just new ones. Then every time Vue updates the <code>
element, Prism automatically highlights it.
Solved using updated property on component:
var Post = {
data: function() {
var postData = {
post: ''
};
var articleTitle = this.$route.path.replace('/', '');
fetch(getPostUrl + articleTitle, {method: "GET", cache: "default"}).then(
function(response) {
if (!response.ok) {
console.log("bad response from server");
}
return response.json()
}).then(
function(responseData) {
postData.post = responseData;
}).catch(function(err) {
console.log(err);
});
return postData
},
template: `
<div class="uk-card uk-card-body uk-card-default">
<article class="uk-article">
<h1 class="uk-article-title uk-text-center uk-text-uppercase">{{post.title}}</h1>
<p class="uk-article-metadata uk-text-center" v-show="post.author">Written by {{post.author}} on {{post.timestamp}}</p>
<hr class="uk-divider-icon" v-show="post.author">
<p v-html="post.content"></p>
<div class="uk-text-center">
<div uk-spinner="ratio: 5" v-show="!post.author"></div>
</div>
</article>
</div>
`,
updated: function() {
Prism.highlightAll();
}
};
@morissette I had the same problem. Do you know why it is ok to use updated property, but watch property isn't?
Solved using updated property on component:
var Post = { data: function() { var postData = { post: '' }; var articleTitle = this.$route.path.replace('/', ''); fetch(getPostUrl + articleTitle, {method: "GET", cache: "default"}).then( function(response) { if (!response.ok) { console.log("bad response from server"); } return response.json() }).then( function(responseData) { postData.post = responseData; }).catch(function(err) { console.log(err); }); return postData }, template: ` <div class="uk-card uk-card-body uk-card-default"> <article class="uk-article"> <h1 class="uk-article-title uk-text-center uk-text-uppercase">{{post.title}}</h1> <p class="uk-article-metadata uk-text-center" v-show="post.author">Written by {{post.author}} on {{post.timestamp}}</p> <hr class="uk-divider-icon" v-show="post.author"> <p v-html="post.content"></p> <div class="uk-text-center"> <div uk-spinner="ratio: 5" v-show="!post.author"></div> </div> </article> </div> `, updated: function() { Prism.highlightAll(); } };
thank mr. i try like this :
import prism from "prismjs/prism";
computed: {
highlightedCode() {
return this.dataArtikel;
},
},
updated: function () {
prism.highlightAll();
},
and my template :
<span v-html="highlightedCode"> </span>
sucsess, highlight code in v-html..
Sorry I don't read PrismJS src, but I have some experience.
I think {{content}}
is damaged when PrismJS handle this line code, which causes vue can't update data.
<pre><code>{{content}}</code></pre>
This is a solution, Vuejs can get <code>
all along:
<pre><code class="language-html" v-text="content"></code></pre>
export default {
computed: {
content() {
this.$nextTick( function() { Prism.highlightAll () } )
// this is async or mutable
return `<script>console.log('Hey!')<\/script>`
},
},
}
The quickest and the easiest way is to force refresh the prism component, and one of the easiest way to force refresh a component is providing a unique :key
attribute to it.
<pre id="editor" :key="paste.content">
<code class="language-css">{{ paste.content }}</code>
</pre>
Hi, prism does not work when the content is loading async. (As with VueJS)