Skip to content

Commit

Permalink
fix re-render when props updated (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
weizhenye committed Oct 22, 2016
1 parent f66936f commit 06c919e
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 18 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Then you can use the components in your template.
<highcharts-renderer :width="width" :height="height"></highcharts-renderer>
```

The `options` object can be found in [Highcharts API Reference](http://api.highcharts.com/highcharts).
The `options` object can be found in [Highcharts API Reference](http://api.highcharts.com/highcharts). Note you should never pass in `chart.renderTo` for watching it may cause stack overflow.

`<highcharts-renderer>` [creates an independent renderer](http://api.highcharts.com/highcharts/Renderer).

Expand Down
3 changes: 2 additions & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ module.exports = function(config) {
'node_modules/vue/dist/vue.js',
'node_modules/highcharts/highstock.js',
'node_modules/highcharts/modules/map.js',
'src/index.js',
'test/test.js'
],
preprocessors: {
'test/test.js': ['rollup', 'coverage']
'src/index.js': ['rollup', 'coverage']
},
rollupPreprocessor: {
format: 'iife',
Expand Down
36 changes: 26 additions & 10 deletions src/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,45 @@ function create(tagName, Highcharts) {
}
: { options: { type: Object, required: true } },
methods: {
_init: function() {
this._renderChart();
if (isRenderer) {
this.$watch('width', this._renderChart);
this.$watch('height', this._renderChart);
} else {
this.$watch('options', this._renderChart, { deep: true });
}
},
_renderChart: function() {
if (isRenderer) {
this.renderer && this.$el.removeChild(this.renderer.box);
this.renderer = new Ctor(this.$el, this.width, this.height);
} else {
var opts = this.options;
opts.chart = opts.chart || {};
opts.chart.renderTo = this.$el;
this.chart = new Ctor(opts);
var opts = {};
for (var property in this.options) {
opts[property] = this.options[property];
}
this.chart = new Ctor(this.$el, opts);
}
}
},
mounted: function() {
this._renderChart();
},
updated: function() {
this._renderChart();
this._init();
},
beforeDestroy: function() {
!isRenderer && this.chart.destroy();
if (isRenderer) {
this.$el.removeChild(this.renderer.box);
for (var property in this.renderer) {
delete this.renderer[property];
}
this.renderer = null;
} else {
this.chart.destroy();
}
},
// compat Vue v1.x
ready: function() {
this._renderChart();
this._init();
}
};
}
Expand Down
79 changes: 73 additions & 6 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
* See https://github.com/npm/npm/issues/5499
*
* For it's impossible to install multiple versions of a dependency,
* only latest version of Vue will be tested.
* only latest version of Vue and Highcharts will be tested.
*
* Vue v1.x should be tested manually.
* Old version of Vue and Highcharts should be tested manually.
*/

import VueHighcharts from '../src/index.js';

/* istanbul ignore next */
/* global expect, Vue, Highcharts, VueHighcharts */
/* eslint-env mocha */
/* eslint max-len: 0 */
describe('vue-highcharts', function() {
var createVM = function(template) {
return new Vue({
Expand All @@ -20,7 +20,7 @@ describe('vue-highcharts', function() {
var componentHelper = function(done, template) {
var vm = createVM(template);
vm.$nextTick(function() {
expect(this.$el.querySelector('.highcharts-root')).to.exist;
expect(vm.$el.querySelector('.highcharts-root')).to.exist;
done();
});
};
Expand Down Expand Up @@ -60,4 +60,71 @@ describe('vue-highcharts', function() {
done();
});
});

it('should destroy the chart instance when vm destroyed', function(done) {
var chart = null;
var renderer = null;
var el = null;
var vm = new Vue({
el: document.createElement('div'),
template:
'<div>' +
'<highcharts :options="{}" ref="highcharts"></highcharts>' +
'<highcharts-renderer :width="400" :height="300" ref="highchartsRenderer"></highcharts-renderer>' +
'</div>',
beforeDestroy: function() {
el = vm.$el;
chart = vm.$refs.highcharts.chart;
renderer = vm.$refs.highchartsRenderer.renderer;
expect(el.querySelector('.highcharts-root')).to.exist;
expect(chart).to.not.be.empty;
expect(renderer).to.not.be.empty;
},
destroyed: function() {
this.$nextTick(function() {
expect(el.querySelector('.highcharts-root')).to.not.exist;
expect(chart).to.be.empty;
expect(renderer).to.be.empty;
done();
});
}
});
vm.$destroy();
});

it('should watch `options`', function(done) {
var vm = new Vue({
el: document.createElement('div'),
template: '<highcharts :options="options" ref="highcharts"></highcharts>',
data: {
options: { title: { text: 'origin' } }
}
});
expect(vm.$refs.highcharts.chart.title.textStr).to.equal('origin');
vm.options.title.text = 'changed';
vm.$nextTick(function() {
expect(vm.$refs.highcharts.chart.title.textStr).to.equal('changed');
done();
});
});

it('should watch `width` and `height`', function(done) {
var vm = new Vue({
el: document.createElement('div'),
template: '<highcharts-renderer :width="width" :height="height" ref="highchartsRenderer"></highcharts-renderer>',
data: {
width: 100,
height: 100
}
});
expect(vm.$refs.highchartsRenderer.renderer.width).to.equal(100);
expect(vm.$refs.highchartsRenderer.renderer.height).to.equal(100);
vm.width = 400;
vm.height = 300;
vm.$nextTick(function() {
expect(vm.$refs.highchartsRenderer.renderer.width).to.equal(400);
expect(vm.$refs.highchartsRenderer.renderer.height).to.equal(300);
done();
});
});
});

0 comments on commit 06c919e

Please sign in to comment.