2

This is my first time making an npm package, I'm making the package's demo, and I wanna put an example of the component usage.

when I put the component usage inside pre and code tag like this

it shows this error

Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <style>, as they will not be parsed.

this is my code (App.vue):

<template>
<pre>
    <code>
        <template>
            <vlider
            :id="'first'"
            :vlider-data="slider"
            :theme="'theme-dark'"
            v-model="inputRange"
            @click="vliderClick()"
            >
                <template> slot="bullet" slot-scope="bullet"
                    <label>{{ bullet.data.label }}</label>
                    <i
                    class="em"
                    :class="[`em-${bullet.data.extras.icon}`]"
                    ></i> 
                    <a target="_blank" :href="bullet.data.extras.learnMore">Learn more ?</a>
                </template>
            </vlider>
        </template>
        <script>
            import Vlider from "vlider";

            export default {
                name: "app",
                components: {
                    Vlider
                },
                data() {
                    return {
                        inputRange: null,
                        slider: [
                            {label: "Angry", color: "#ffc300", extras: { icon: 'angry', learnMore: 'http://localhost/'}},
                            {label: "Expressionless", color: "#ffb0fe", extras: { icon: 'expressionless', learnMore: 'http://localhost/'}},
                            {label: "Astonished", color: "#ff6bd6", extras: { icon: 'astonished', learnMore: 'http://localhost/'}},
                            {label: "Confounded", color: "#ff9d76", extras: { icon: 'confounded', learnMore: 'http://localhost/'}},
                            {label: "Okay?", color: "#51eaea", extras: { icon: 'face_with_raised_eyebrow', learnMore: 'http://localhost/'}},
                            {label: "Blush", color: "#fb3569", extras: { icon: 'blush', learnMore: 'http://localhost/'}}
                        ]
                    };
                },
                watch: {
                    inputRange() {
                        console.log(this.inputRange)
                    }
                },
                methods: {
                    vliderClick() {
                        console.log(`clicked`)
                    }
                }
            };
        </script>
        <style>
            import "vlider/src/sass/vlider.scss"
        </style>
    </code>
</pre>
</template>

<script>
import Vlider from "vlider";
...
</script>

I expect it to work like how normal tag in HTML works. I've tried downloading some code blocks npm packages, it still doesn't work, i need you guys helps and suggestions with this, thanks for your help

4 Answers 4

5

The v-pre directive is supposed to tell Vue to not compile that portion of the template, but Vue appears to still throw the same warnings if its contents include (for example) a <script> tag. In any case it doesn't show its as contents as raw HTML. You'll want to pull that out into a data variable, and not use v-html here (which does the opposite of what you want):

new Vue({
  el: '#app',
  data() {
    return {
      codeSample: `
<template>
    <vlider
    :id="'first'"
    :vlider-data="slider"
    :theme="'theme-dark'"
    v-model="inputRange"
    @click="vliderClick()"
    >
        <template> slot="bullet" slot-scope="bullet"
            <label>{{ bullet.data.label }}</label>
            <i
            class="em"
            :class="['em-\${bullet.data.extras.icon}']"
            ></i> 
            <a target="_blank" :href="bullet.data.extras.learnMore">Learn more ?</a>
        </template>
    </vlider>
</template>
<script>
    import Vlider from "vlider";
    export default {
        name: "app",
        components: {
            Vlider
        },
        data() {
            return {
                inputRange: null,
                slider: [
                    {label: "Angry", color: "#ffc300", extras: { icon: 'angry', learnMore: 'http://localhost/'}},
                    {label: "Expressionless", color: "#ffb0fe", extras: { icon: 'expressionless', learnMore: 'http://localhost/'}},
                    {label: "Astonished", color: "#ff6bd6", extras: { icon: 'astonished', learnMore: 'http://localhost/'}},
                    {label: "Confounded", color: "#ff9d76", extras: { icon: 'confounded', learnMore: 'http://localhost/'}},
                    {label: "Okay?", color: "#51eaea", extras: { icon: 'face_with_raised_eyebrow', learnMore: 'http://localhost/'}},
                    {label: "Blush", color: "#fb3569", extras: { icon: 'blush', learnMore: 'http://localhost/'}}
                ]
            };
        },
        watch: {
            inputRange() {
                console.log(this.inputRange)
            }
        },
        methods: {
            vliderClick() {
                console.log('clicked')
            }
        }
    };
</\script>
<style>
    import "vlider/src/sass/vlider.scss"
</style>
        `
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <pre><code>{{codeSample}}</code></pre>
</div>

Embedding large chunks of HTML inside a data variable is a little clumsy, of course, and requires some escaping of various bits and pieces (such as the included ${...} and the </script> tag in your example). It may be easier to maintain if you import that HTML string via ajax or as a webpack import rather than directly embedding it inside data() as I've done here.

(You also may want to look at vue-highlightjs if you want syntax coloring of your code samples; it, too, depends on having the source code in a component data variable rather than inline inside the template.)

Or the easy way

If you're willing to escape the html ahead of time, you can plonk that straight into the template, and use v-pre to tell Vue to ignore any mustache symbols in the embedded html:

new Vue({
  el: '#app'
});
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">

  <pre><code v-pre>&lt;script&gt;... {{foo}} &lt;/script&gt;</code></pre>

</div>

Sign up to request clarification or add additional context in comments.

2 Comments

i tried the mustage style, its says that it doesnt recognize import method, which means it renders the <style> tag for some reason, im really confuse on how to treat this snippet of code as a string
importing html as a string may take some fiddling with webpack; see stackoverflow.com/questions/37818401/…
1

user v-html [docs][1] and don't forget to use \ after every line break to continue the string and ignoring '' as text context by \'

so it shall be :

    <div v-html="example">
     <pre>
      ...
     </pre>    
    </div>

or

<div>
  {{example}}
</div>

and example you define it inside data() [1]: https://v2.vuejs.org/v2/guide/syntax.html?#Raw-HTML

4 Comments

it doesn't work, it gives me another error because apparently v-html renders the html inside it which will cause another error
try to use mustage style {{}}
i tried the mustage style, its says that it doesnt recognize import method, which means it renders the <style> tag for some reason, im really confuse on how to treat this snippet of code as a string
i tried it again using v-html, this time i use html entities and it works smoothly, thanks for your help
1

you can use VueCodeBlock to display codes. it also comes with amazing themes that can be configured in dark and light mode

 <template>
    <VCodeBlock
      :code="code"
      highlightjs
      lang="javascript"
      theme="neon-bunny"
    />
 </template>
 <script setup>
   const code = ref(`const text = 'hello'`)
 </script>

Comments

0

So I fix it by using this website to encode my code https://mothereff.in/html-entities

and then I use the encoded version and put it in a variable and pass it to v-html, and vue will treat it as a string and will display it as string

<pre>
  <code v-html="yourCodeVariable">
  </code>
</pre>
...
<script>
...
data() {
  return {
     yourCodeVariable: `your encoded html code here`
  }
}
...

4 Comments

This is the long way around. If you're wiling to encode the html, you don't need any of this, you can just put the encoded version directly in the template. If you pull it out into a data variable, then you don't have to encode it; just embed it without v-html (which means vue will encode it for you!)
@DanielBeck i just tried it, and it gives me an error for the 2nd block of code, because there are some mustage symbols in it and vue take it as a normal mustage symbol, i think its saver to do it with v-html and variables to avoid errors
Ah, good point, but you can use v-pre to fix that (I updated my answer to show an example). I really don't know why you'd want to use v-html here; if you've already gone to the effort of pulling the HTML string out into a data variable, you can let Vue do the work of encoding it instead of having to do it manually.
@DanielBeck oh yeah you're right, thanks for your suggestion

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.