使用没有 src 属性的 vuejs 在 iframe 中渲染组件

Posted

技术标签:

【中文标题】使用没有 src 属性的 vuejs 在 iframe 中渲染组件【英文标题】:Render Component in iframe using vuejs without src attribute 【发布时间】:2017-08-22 15:08:33 【问题描述】:
<iframe id="frame"  >

</ifrme>

我想在这个 iframe 中渲染组件。是否有在 iframe 中创建 html 元素或渲染组件的选项?

new Vue(
   el:'#frame',
   store:store,
   router:router,
   render: component
)

【问题讨论】:

【参考方案1】:

您可以参考下面的链接,这对我帮助很大。 这是链接和代码sn-ps。

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/

【讨论】:

一开始我并不清楚的是,Linusborg 的链接示例在他的模板中没有使用真正的 这可行,但是如何将 CSS 加载到 iframe 中。我试图避免在 iframe 中发出 css 请求,是否有任何选项可以嵌入到样式中? 是的,我们需要知道如何将 CSS 放入 iframe :) 知道如何在文件组件中执行此操作吗?【参考方案2】:
new Vue(
el:'#frame',
store:store,
router:router,
render: component
)

只需尝试为您的路线视图命名。 希望有效

【讨论】:

【参考方案3】:

我试过了,还没有找到直接在#iframe上挂载vue的方法。

不过,您可以将 div 添加到 #iframe 并挂载到该位置:

// create iframe element
var iframe = document.createElement('iframe')
iframe.id = 'iframe'
// place iframe inside page html
document.documentElement.insertBefore(iframe, document.querySelector('html').firstChild)

// append div to iframe
var container = document.createElement('div')
container.id = 'container'
iframe.contentWindow.document.body.appendChild(container)

// render vue component inside iframe on #container
new Vue(
el: container,
render: h => h(component)
)

结果:

<html>
  <iframe id="iframe">
    #document
    <html>
      <head>
      </head>
      <body><!-- <-- here was <div id="container"></div> -->
        <div class="message" style="color: orange;">Hello from Vue component!</div>
      </body>
    </html>
  </iframe>
  <head>
  </head>
  <body>
  </body>
</html>

附:我在 chrome 扩展内容脚本 中使用了这段代码(javascript 注入页面)。如果你要使用 在别处确保不要破坏Same-origin policy。

【讨论】:

我有同样的用例。创建 iframe 并在其中渲染 Vue 组件。虽然不应用组件的样式。您对此有什么建议吗? var extStyle = document.createElement('link'); extStyle.rel = '样式表'; extStyle.href = browser.extension.getURL("somestyle.css"); iframe.contentWindow.document.head.appendChild(extStyle); @nteath 你解决过这个问题吗?具有完全相同的用例。使用 Vue CLI,开发服务器/热重载将 如果容器是完整的文档? &lt;html&gt;...&lt;/html&gt;【参考方案4】:

对我来说最简单的方法是使用srcdoc 属性。它加载原始 html 覆盖 src 属性。

<template>
    <iframe :srcdoc="html"></iframe>
</template>

更新:更详细的示例:考虑用户 html 输入的文本区域并希望在 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>

【讨论】:

这太完美了!非常简单,不使用不必要且复杂的抽象层。 我希望这有更多的解释,以及相关的 javascript 代码。我认为"html" 代表应该由 vue 以某种方式提供的 html 片段? @abulka 我用更详细的例子更新了我的答案,希望你能理解。 codesandbox.io/s/musing-haze-c0ydz?file=/src/App.vue

以上是关于使用没有 src 属性的 vuejs 在 iframe 中渲染组件的主要内容,如果未能解决你的问题,请参考以下文章

VueJS $set 没有在对象数组中创建新属性

使属性反应,道具Vuejs2数据绑定

vuejs属性绑定

VueJS:为啥这个数据属性没有在开发工具中的点击事件上更新?

带有 Vuejs 类组件的双向计算属性

VueJs---V-bind指令