Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Rewriting vue prism component in vue 3
shubhadip
shubhadip

Posted on • Edited on

     

Rewriting vue prism component in vue 3

With Vue 3 released, there will be many libraries running into port their vue 2 projects into vue 3. Recently while working on creating a library on vue 3 I needed a syntax highlighter for demo purpose, so thought of writing one with vue 3 Setup API.

for this to work we need prismjs so let's add prismJs library;

yarn add prismjs

We would be requiring code that is supposed to be used as a highlighter and the language in which the code would be.

import * as Vue from 'vue';import Prism from 'prismjs';export default Vue.defineComponent({  props: {    code: {      type: String,    },    inline: {      type: Boolean,      default: false,    },    language: {      type: String,      default: 'markup',    },  }})
Enter fullscreen modeExit fullscreen mode

Now let's see how can we used the setup function to access props and children. Setup function provides props and setupContext as parameters, we can easily destructure setupContext to access attrs and slots.

...setup(props, { slots, attrs }: { slots: Slots; attrs: Data }) {    const { h } = Vue;    const slotsData = (slots && slots.default && slots.default()) || [];    const code = props.code || (slotsData.length > 0 ? slotsData[0].children : '');    const { inline, language } = props;    const prismLanguage = Prism.languages[language];    const className = `language-${language}`;...
Enter fullscreen modeExit fullscreen mode

The above code will be access to props and children's passed to the prismJs.Also,h which was passed to render function but now it has to be imported from vue.

With this done let's see how can we pass{{code}} as well aslanguage to prismJs so that it can return HTML back to us, that can be used in the render function.

    const d = Prism.highlight(code, prismLanguage);
Enter fullscreen modeExit fullscreen mode

with everything in place, lets add our render function with these data.

...return (): VNode =>      h('pre', { ...attrs, class: [attrs.class, className] }, [        h('code', {          class: className,          innerHTML: d,        }),      ]);...
Enter fullscreen modeExit fullscreen mode

In 3.x, the entire VNode props structure is flattened. you can read more about render functionVue 3 Render Function.

So this is how our code will look on completion.

// prismcomponent/index.tsimport * as Vue from 'vue';import Prism from 'prismjs';import { Slots, VNode } from 'vue';declare type Data = Record<string, unknown>;export default Vue.defineComponent({  props: {    code: {      type: String,    },    inline: {      type: Boolean,      default: false,    },    language: {      type: String,      default: 'markup',    },  },  setup(props, { slots, attrs }: { slots: Slots; attrs: Data }) {    const { h } = Vue;    const slotsData = (slots && slots.default && slots.default()) || [];    const code = props.code || (slotsData.length > 0 ? slotsData[0].children : '');    const { inline, language } = props;    const prismLanguage = Prism.languages[language];    const className = `language-${language}`;    if (inline) {      return (): VNode =>        h('code', { ...attrs, class: [attrs.class, className], innerHTML: Prism.highlight(code, prismLanguage) });    }    const d = Prism.highlight(code, prismLanguage);    return (): VNode =>      h('pre', { ...attrs, class: [attrs.class, className] }, [        h('code', {          class: className,          innerHTML: d,        }),      ]);  },});
Enter fullscreen modeExit fullscreen mode

So in other components, all we need to add is

<template>...<Prism language="javascript">  {{ code }}</Prism>...</template><script lang="ts">import { defineComponent } from 'vue';import Prism from '../prismcomponent';import 'prismjs';import 'prismjs/themes/prism.css';export default defineComponent({...setup() {    const code = `const c = a+b`;    return {      code,    };  },...})</script>
Enter fullscreen modeExit fullscreen mode

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

  • Location
    Mumbai, India
  • Joined

More fromshubhadip

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp