23

At the moment I pass some parameters into a vue component

 <Slider
      :images= "['/img/work/slide2.png', '/img/work/slide2.png', '/img/work/slide3.png']"
      :html="['<div>hello</div>', '<div>goodbye</div>']"
    </Slider>

The slider is either an 'html' slider or one with images.

This works fine although the html I pass in is going to get a lot more complex, maybe 30 lines and this will be harder to read and manage as params.

Can I pass in an external reference and pull that into the component?

<div v-for="content in html">
    <div class="work-slide">{{ content }}</div>
</div>

As you can see the loop in the component is a very simple v-for.

3 Answers 3

38

Don't pass HTML using attributes but using Slots:

Suppose we have a component called my-component with the following template:

<div>
  <h2>I'm the child title</h2>
  <slot>
    This will only be displayed if there is no content
    to be distributed.
  </slot>
</div>

And a parent that uses the component:

<div>
  <h1>I'm the parent title</h1>
  <my-component>
    <p>This is some original content</p>
    <p>This is some more original content</p>
  </my-component>
</div>

The rendered result will be:

<div>
  <h1>I'm the parent title</h1>
  <div>
    <h2>I'm the child title</h2>
    <p>This is some original content</p>
    <p>This is some more original content</p>
  </div>
</div>

You can also use Named Slots if you want to pass more than one field containing HTML.

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

Comments

7

You can inject raw html into Vue components with the v-html directive.

3 Comments

While this would work, you do not get any data-bindings this way.
You can certainly bind data with v-html, e.g. <p v-html="mydataVariable"></p>
How do I pass the html to mydataVariable from the html which uses the component?
2

I had similar problem in a project some months ago. I fixed it passing the HTML code in base64 format.

my parent component :

<wysywyg id="ssaasa" :bal="to64('<strong>Me</strong>')"></wysywyg>

my method:

methods: {
        to64(html) {
            return btoa(html)
        }
    }

my component:

<template>
    <div class="RenderHTMLEditor mx-3">
        <label class="subtitle-1 pb-3">{{label}}</label>
        <textarea html="true" v-model="to64"
        width="100%"
        :style="'height:'+height+'px;'"
        wysywyg="true"
        :name="id" :id="id"
        class="tinywy">
        </textarea>
    </div>
</template>

<script>
export default {
    props: ['label', 'id', 'height', 'bal'],
    data: function() {
        return {
            
        }
    },
    computed: {
        to64: function() {
            return atob(this.bal)
        }
    },
    mounted: function() {
        window.initWy(this.id)
    }
}
</script>

<style scoped>
.RenderHTMLEditor {
    width: 100%;
}
</style>

1 Comment

Congratulations. You've just exposed your site to the wonderful world of XSS attacks! :) - Although a novel solution to this problem, please don't do this, especially with v-model. Slots exist for this very use-case, and will protect you (at least partially) from exposing yourself to attacks. You're one malicious eval() away from disaster.

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.