预渲染 vue.js 2.0 组件(类似于 vue 1 中的 this.$compile)

Posted

技术标签:

【中文标题】预渲染 vue.js 2.0 组件(类似于 vue 1 中的 this.$compile)【英文标题】:Prerender vue.js 2.0 component (similar to this.$compile in vue 1) 【发布时间】:2017-08-19 11:52:41 【问题描述】:

我正在尝试为gridstack 制作可重用组件

我找不到类似于 vue 1 中的this.$compile 方法的简单方法。 我见过这个example。

这是我的 vue 脚本:

export default 
  components: 
    'horizontal-fab': HorizontalFab,
    'd-widget': DWidget
  ,
  data () 
    return 
  
,
mounted () 
  var options = 
    cellHeight: 80,
    verticalMargin: 10,
    width: 3
  
  $('#grid-stack').gridstack(options)
,

addWid () 
  var grid = $('#grid-stack').data('gridstack')
  grid.addWidget('<d-widget></d-widget>', 0, 0, 1, 1, true)
,

addGraph () 
  var grid = $('#grid-stack').data('gridstack')
  grid.addWidget(`
    <div class="grid-stack-item" data-gs->
      <div class="grid-stack-item-content">
        <p>html (added)</p>
      </div>
    </div>
  `, 0, 0, 1, 1, true)

这里是相关的html:

<span @click="addGraph" >Line graph</span></li>
<span @click="addWid">Sparklines</span></li>
...
<div id="grid-stack" class="grid-stack grid-stack-3">
  <d-widget data-gs-x="0" data-gs-y="0" data-gs- data-gs-></d-widget>
</div>

问题是:

该方法 addGraph 完美运行,而 addWid - 没有。即使直接作为组件插入到 html 中,它也可以工作。

我猜是因为组件中的 html 没有被预编译。不过 vue1 中的 compile 解决了这个问题。

我已经尝试过的:

    Mount,正如 here 所建议的那样,但它无法正常工作,因为它看不到已定义的组件,我猜 我看到有可能使它与push 一起工作,正如here 所建议的那样。但是我的vue知识还没有那么强,我找不到让它以这种方式工作的方法,因为会有几种类型的块,并且它们都应该被gridstack视为相同的元素。此外,同一个组件可以在一块板上多次使用,但参数不同。 我看到有一种方法可以编译standalone component,比如here,但看起来非常不推荐,所以我正在寻找其他方法。 我也见过 these render functions,但又一次 - 不幸的是我的技能不太好应用它。

所以,总结一下 - 我真的很感谢一些关于这些方法的建议,或者可能是关于其他实现方式的建议。问题是我还应该依靠 gridstack 脚本,而不是简单地插入元素。

谢谢!

UPD:d-widget 的定义:

这基本上是单个组件,定义在单独的文件中,称为 Widget.vue

<template>
<div class="grid-stack-item" data-gs->
    <div class="grid-stack-item-content">
        <p>Wiiidget! (added)</p>
    </div>
</div>
</template>
<script>
export default 
  data () 
    return 
    
  

</script>

【问题讨论】:

什么是d-widget?我们能看到定义吗? @BertEvans,感谢您的提问!我刚刚添加了定义,您可能会看到它与我在 addGraph() 中使用的模板基本相同,只是作为组件导入,而不是 html。 您是要向d-widget 组件添加的不仅仅是HTML,还是只是一个模板。本质上,您的问题是使用单个文件组件,模板被编译为渲染函数,而您真的只想要模板本身(就像现在一样)。 @BertEvans 是的,你理解正确。但是,是的,我需要在该组件中有更多方法,我还将发送参数并且模板本身会更复杂(d3 图表)。这只是理解问题的一个基本示例。因此,在将组件提供给 addWid () 方法之前,我无法找到一种方法来预渲染(让我们这样称呼它)组件中的 html @BertEvans 我现在也在研究 vue 属性,也许这是另一种方法 【参考方案1】:

使用mount,你应该能够得到你需要传递给grid.addWidget的东西。

首先我们想把组件变成我们可以构造的东西。

const MyWidget = Vue.extend(DWidget);

然后,我们就可以挂载那个构造函数了。

const mounted = new MyWidget().$mount();

我没有向$mount() 传递任何内容,它不会将组件添加到 DOM。我们可以使用mounted.$el 访问它生成的元素。我希望您应该能够将其传递给addWidget

grid.addWidget(mounted.$el, 0,0,1,1,true);

【讨论】:

嗨,伯特。好吧,在某种程度上它有所帮助!谢谢!现在,当我第一次调用 addWid() 时——它真的生成了!一切都井井有条。但是,当我再次调用此方法时 - 添加了一个组件,尽管完全删除了前一个组件。 (所以 gridstack 只是留下空白而不是第一个)。虽然我可以使用 addGraph () 添加任意数量的组件,并且所有组件都同时显示 哦,我刚刚意识到我的一些错误,现在它起作用了:)!太好了,非常感谢!【参考方案2】:

所以,正如@Bert 建议的那样,我必须使用 mount。他的方法非常有效。 这是一个结果 addWid () 方法,它实际上是可重用的组件:

addWid () 
  const MyWidget = Vue.extend(DWidget)
  const mounted = new MyWidget().$mount()
  var grid = $('#grid-stack').data('gridstack')
  grid.addWidget(mounted.$el, 0, 0, 1, 1, true)

希望对某人有所帮助!

【讨论】:

以上是关于预渲染 vue.js 2.0 组件(类似于 vue 1 中的 this.$compile)的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 2.0 在一个项目上呈现相同的组件,但在另一个项目上不呈现

在 vue.js 组件中渲染子组件

Vue.js 3.0 组件是如何渲染为 DOM 的?

Vue和Material Design开源框架Vuetify发布2.0 release版本

带你初识vue.js(基础知识)

Vue.js学习笔记