Search code examples
htmliframevue.js

Render Component in iframe using vuejs without src attribute


<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
})

Solution

  • 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/