4

I am using Handsontable with vanilla javascript inside a VueJS single page application. Using the following listener:

document.addEventListener('DOMContentLoaded', function() ...

the table only appears on a page refresh, not initial load. I also tried using:

document.addEventListener('load', function() ...

but the table doesn't show at all (also doesn't show if I remove the DOMContentLoaded listener). Some of the examples on the handsontable site eg https://docs.handsontable.com/0.18.0/demo-bootstrap.html use the DOMContentLoaded listener others don't use any listener.

The VueJS page code is below.

TableView.vue:

<template>
    <div id="example"></div>
</template>

<script>
import Handsontable from 'handsontable'               
import 'handsontable/dist/handsontable.full.css'      
export default {            
  name: 'TablesView',       
  data () {                 
    return {                
      tableData: {}  
  }                       
},                        
created: function () {     
  this.populateHot()      
},    
methods: {
  populateHot: function() {
    document.addEventListener('DOMContentLoaded', function() {
      var data = [
        ['', 'Kia', 'Nissan', 'Toyota', 'Honda', 'Mazda', 'Ford'],
        ['2012', 10, 11, 12, 13, 15, 16],
        ['2013', 10, 11, 12, 13, 15, 16]
      ]
      var container1 = document.getElementById('example')
      var hot1 = new Handsontable(container1, {
        data: data,
        startRows: 2,
        startCols: 5
      })
    })
  }
}
</script>      

I tried moving the Handsontable code outside the VueJS export default block ie:

<script>
import ....
var hotData = []
export default {...
// update hotData with ajax loaded data
}
function initializeHandsOn() {...}
document.addEventListener('DOMContentLoaded', initializeHandsOn(), false)
</script>

But I get an error thrown by handsontable.js:

Uncaught TypeError: Cannot read property 'insertBefore' of null(…)

Any ideas on how best to integrate Handsontable with VueJS? (I tried vue-handsontable and vue-handsontable-official but had problems getting either to work)?

Don Smythe
  • 9,234
  • 14
  • 62
  • 105

2 Answers2

3

You can try by removing the event listner: document.addEventListener('DOMContentLoaded' and directly execute this code on mounted, as mounted in vue is roughly equivalent of DOMContentLoaded, like following:

<script>
import Handsontable from 'handsontable'               
import 'handsontable/dist/handsontable.full.css'      
export default {            
  name: 'TablesView',       
  data () {                 
    return {                
      tableData: {}  
  }                       
},                        
mointed: function () {     
  this.populateHot()      
},    
methods: {
  populateHot: function() {
      var data = [
        ['', 'Kia', 'Nissan', 'Toyota', 'Honda', 'Mazda', 'Ford'],
        ['2012', 10, 11, 12, 13, 15, 16],
        ['2013', 10, 11, 12, 13, 15, 16]
      ]
      var container1 = document.getElementById('example')
      var hot1 = new Handsontable(container1, {
        data: data,
        startRows: 2,
        startCols: 5
      })
  }
}
</script> 
Saurabh
  • 71,488
  • 40
  • 181
  • 244
  • The VueJS docs don't go into much detail on when to use created vs mounted - in general when should you use created vs mounted? – Don Smythe Apr 02 '17 at 02:59
  • @DonSmythe [created](https://vuejs.org/v2/api/#created), [mounted](https://vuejs.org/v2/api/#mounted), etc are [hooks](https://vuejs.org/v2/api/#Options-Lifecycle-Hooks) executed at different points of times when DOM is rendering. You can see those details [here](https://vuejs.org/v2/api/#Options-Lifecycle-Hooks). Mounted is when DOM has been rendered. – Saurabh Apr 02 '17 at 04:37
1

Use mounted method, the biggest difference when you have to go with mounted vs created is when your element was added to the DOM. It's quite popular problem when you need connection with other non-vue parts.

P.S. Also you may consider to use alternative tables, HT was built based on old technologies ignoring VNode ideas etc.

Revolist
  • 68
  • 8