简体   繁体   中英

Prerender vue.js 2.0 component (similar to this.$compile in vue 1)

I'm trying to make reusable components for gridstack .

I cannot find a simple way to do something similar to this.$compile method from vue 1 . I've seen this example .

Here is my vue script:

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-width="4">
      <div class="grid-stack-item-content">
        <p>HTML (added)</p>
      </div>
    </div>
  `, 0, 0, 1, 1, true)
}

And here is relevant 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-width="1" data-gs-height="1"></d-widget>
</div>

The problem is:

that method addGraph works perfectly, when addWid - does not. Even though when inserting as a component directly in the html, it works too.

I guess that it because html from the component is not being precompiled. It was solved by compile in vue1 though.

What I've already tried:

  1. Mount , as suggested here , but it wasn't working because it couldn't see defined components, I guess
  2. I've seen there are a possibilities to make it work with push , as suggested here . But my vue knowledge is not that strong yet, and I cannot find a way to make it work in this way, since there would be several types of blocks, and all of them should be treated by gridstack as the same elements. Plus, same component may be used several times within one board, with different parameters.
  3. I've seen there is a method to compile a standalone component , like here , but looks like it is highly unrecommended, so I'm looking for other ways.
  4. I've also seen these render functions , but again - unfortunately my skills are not that good to apply it.

So, to sum it up - I'd really appreciate some advice about these methods, or maybe recommendations on the other way of implementing this. Problem is that I should also count on gridstack script, and not simply inserting the elements.

Thanks!

UPD: definition of d-widget:

This is basically single component, which is defined in the separate file, called Widget.vue

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

Using mount , you should be able to get what you need to pass to grid.addWidget .

First we want to turn the component into something we can construct.

const MyWidget = Vue.extend(DWidget);

Then, we can mount that constructor.

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

My passing nothing to $mount() , it will not add the component to the DOM. We can get access to the element it generated using mounted.$el . I expect you should be able to pass that to addWidget .

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

So, as @Bert suggested I had to use mount. And his method works perfectly. And here is a resulting addWid () method, which actually works as reusable component:

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

Hopefully it would be helpful to someone!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM