<iframe id="frame" width="100%" height="100%">
</ifrme>
I want to render component in this iframe. Is there any option of creating html element or rendering component in iframe?
new Vue({
el:'#frame',
store:store,
router:router,
render: component
})
The best way to force Vue to re-render a component is to set a :key on the component. When you need the component to be re-rendered, you just change the value of the key and Vue will re-render the component.
The srcdoc attribute specifies the HTML content of the page to show in the inline frame. Tip: This attribute is expected to be used together with the sandbox and seamless attributes. If a browser supports the srcdoc attribute, it will override the content specified in the src attribute (if present).
Definition and UsageThe <iframe> tag specifies an inline frame. An inline frame is used to embed another document within the current HTML document. Tip: Use CSS to style the <iframe> (see example below). Tip: It is a good practice to always include a title attribute for the <iframe> .
A render function returns a virtual DOM node, commonly named VNode in the Vue ecosystem, which is an interface that allows Vue to write these objects in your browser DOM. They contain all the information necessary to work with Vue.
You can refer below link That helped me a lot. Here is the link and the code snippets.
Vue.component('i-frame', {
render(h) {
return h('iframe', {
on: { load: this.renderChildren }
})
},
beforeUpdate() {
//freezing to prevent unnessessary Reactifiation of vNodes
this.iApp.children = Object.freeze(this.$slots.default)
},
methods: {
renderChildren() {
const children = this.$slots.default
const body = this.$el.contentDocument.body
const el = document.createElement('DIV') // we will mount or nested app to this element
body.appendChild(el)
const iApp = new Vue({
name: 'iApp',
//freezing to prevent unnessessary Reactifiation of vNodes
data: { children: Object.freeze(children) },
render(h) {
return h('div', this.children)
},
})
iApp.$mount(el) // mount into iframe
this.iApp = iApp // cache instance for later updates
}
}
})
Vue.component('test-child', {
template: `<div>
<h3>{{ title }}</h3>
<p>
<slot/>
</p>
</div>`,
props: ['title'],
methods: {
log: _.debounce(function() {
console.log('resize!')
}, 200)
},
mounted() {
this.$nextTick(() => {
const doc = this.$el.ownerDocument
const win = doc.defaultView
win.addEventListener('resize', this.log)
})
},
beforeDestroy() {
const doc = this.$el.ownerDocument
const win = doc.defaultView
win.removeEventListener('resize', this.log)
}
})
new Vue({
el: '#app',
data: {
dynamicPart: 'InputContent',
show: false,
}
})
https://jsfiddle.net/Linusborg/ohznser9/
The easiest way for me is to use srcdoc attribute. It loads raw html overriding src attribute.
<template>
<iframe :srcdoc="html"></iframe>
</template>
Update: More detail example: Consider a textarea for a user html
input and want to display in an iframe
.
<template>
<div id="app">
<textarea v-model="html"></textarea>
<iframe :srcdoc="html"></iframe>
</div>
</template>
<script>
export default {
name: "App",
data(){
return {
html:"<h1>Hello I am H1 block</h1>"
}
}
};
</script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With