使用没有 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,开发服务器/热重载将 如果容器是完整的文档?<html>...</html>
【参考方案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 中渲染组件的主要内容,如果未能解决你的问题,请参考以下文章