Skip to content

Instantly share code, notes, and snippets.

@rvanzon
Last active September 1, 2022 13:25
Show Gist options
  • Select an option

  • Save rvanzon/096132b7b46be43659cf26360c664e9a to your computer and use it in GitHub Desktop.

Select an option

Save rvanzon/096132b7b46be43659cf26360c664e9a to your computer and use it in GitHub Desktop.
A way to use vue-chartjs as a plugin of Nuxt.js

(WARNING: THIS IS OUTDATED, DON'T USE AS IS! INSTEAD CHECK OUT THE COMMENTS AT THE BOTTOM)

And check out: https://github.com/nuxt/nuxt.js/tree/dev/examples/vue-chartjs

How does this work

  1. Create a custom plugin and put it in plugins (plugins_vue-chartjs.js).
  2. Add the plugin to nuxt.config.js and set ssr to false to prevent the server to initialize it.
  3. You can use the component now just like other Vue-components. The only problem is that you get errors because the DOM-tree is out of sync (because the server misses the component)
  4. As mounted() is only called by the client (browser) we're using this to render the component only in the browser. Add showLine: false to data (so the server will not render it) and turn it to true in mounted().
  5. Use v-if to render the component. Now it won't be rendered on the server side, but it will show up in de browser.

This way also works with other Vue.js plugins

Used in this example:
npm install vue-chartjs --save
npm install chart.js --save

// just an example. A cleaner way is to wrap the showLine-stuff in a dedicated component
<template>
<div>
<my-line v-if="showLine" :data="lineData" :options="options">
</div>
</template>
<script>
export default {
data () {
return {
showLine: false
}
},
mounted () {
this.showLine = true // showLine will only be set to true on the client. This keeps the DOM-tree in sync.
},
asyncData () {
const lineData = {} // some data
const options = {} // some options
return { lineData, options }
}
}
</script>
...
/*
** Build configuration
*/
plugins: [
{ src: '~/plugins/vue-chart.js', mode: 'client' },
],
...
import Vue from 'vue'
import { Line } from 'vue-chartjs'
Vue.component('my-line', Line.extend({
props: ['data', 'options'],
mounted () {
this.renderChart(this.data, this.options)
}
}))
@uptownhr

uptownhr commented Jun 7, 2017

Copy link
Copy Markdown

Nice!

@frankspin89

Copy link
Copy Markdown

Very Nice!

@FPierre

FPierre commented Oct 17, 2017

Copy link
Copy Markdown

Same setup, but need to use make plugin like this:

import Vue from 'vue'
import { Bar } from 'vue-chartjs'

Vue.component('portolio-chart', {
  extends: Bar,
  props: ['data', 'options'],
  mounted () {
    this.renderChart(this.data, this.options)
  }
})

Otherwise it's produce vue-chartjs.js:7 Uncaught TypeError: __WEBPACK_IMPORTED_MODULE_1_vue_chartjs__.Bar.extend is not a function error

@rahulrumalla

Copy link
Copy Markdown

What FPierre said. Running into the error __WEBPACK_IMPORTED_MODULE_1_vue_chartjs__.Bar.extend is not a function

Any suggestions on how to fix this, please?

@imdunkind

imdunkind commented Nov 12, 2017

Copy link
Copy Markdown
import { Line } from 'vue-chartjs'

export default {
  extends: Line,
  props: ['data', 'options'],
  mounted () {
    this.renderChart(this.data, this.options)
  }
}

try it.. plugins/vue-chartsjs.js

@Kency1013

Copy link
Copy Markdown

with error Uncaught TypeError: WEBPACK_IMPORTED_MODULE_1_vue_chartjs
try
import Vue from 'vue';
import {Line} from 'vue-chartjs';
Vue.component('line-chart', {
extends: Line,
props: ['data', 'options'],
mounted() {
this.renderChart(this.data, this.options);
}
});

@lobaak

lobaak commented Apr 19, 2018

Copy link
Copy Markdown

This was very helpful, cheers

@sergiorodenas

Copy link
Copy Markdown

This Nuxt official example is SSR working: https://github.com/nuxt/nuxt.js/tree/dev/examples/vue-chartjs

@raviasthra

Copy link
Copy Markdown

hi , charts not working in vue+nuxt.js.
package.json
"dependencies": {
"@nuxtjs/axios": "^5.3.1",
"axios": "^0.18.0",
"body-parser": "^1.18.2",
"chart.js": "^2.7.2",
"es6-promise": "^4.2.4",
"express": "^4.16.3",
"express-session": "^1.15.6",
"fs": "0.0.1-security",
"hchs-vue-charts": "^1.2.8",
"net": "^1.0.2",
"nuxt": "^1.4.0",
"vee-validate": "^2.1.0-beta.2",
"vue-chartjs": "^3.4.0",
"vue-image-compressor": "^1.0.3",
"vuetify": "^1.0.0",
"vuex": "^3.0.1",
"whatwg-fetch": "^2.0.4"
},

Pages/Dashboard.vue



Dashboard: {{ $store.state }}



<script> import { Bar } from '~/components/bar-charts.js' export default { data () { return { showLine: false, barChartData: { labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], datasets: [ { label: 'Nuxt.js Commit Activity', backgroundColor: '#41b883', data: [40, 39, 10, 40, 39, 80, 40] } ] } } }, components: { Bar } } </script>

components/abr-charts.js
import { Bar } from 'vue-chartjs'

export default {
extends: Bar,
props: ['data', 'options'],
mounted () {
this.renderChart(this.data, this.options)
}
}

nuxt.config.js
/*
** Build configuration
/
build: {
babel: {
plugins: [
["transform-imports", {
"vuetify": {
"transform": "vuetify/es5/components/${member}",
"preventFullImport": true
}
}]
]
},
vendor: [
'~/plugins/vuetify.js',
'~plugins/vue-chartjs.js'
],
vendor: ['axios'],
extractCSS: true,
/

** Run ESLint on save
*/
extend (config, ctx) {
if (ctx.isDev && ctx.isClient) {
config.module.rules.push({
enforce: 'pre',
test: /.(js|vue)$/,
loader: 'eslint-loader',
exclude: /(node_modules)/
})
}
if (ctx.isServer) {
config.externals = [
nodeExternals({
whitelist: [/^vuetify/]
})
]
}
}
},

result empty view only showed.
pls help me to solve this.

@codehunter12345

codehunter12345 commented Dec 4, 2019

Copy link
Copy Markdown

@Kency1013 Syntax for creating chart component has been changed in the latest version (3.0.0) :

import { Line } from 'vue-chartjs'


Vue.component("my-line", {
  extends: Line,
  props: [ "options", "mydata"],
  mounted() {
    this.renderChart(this.mydata, this.options);
  }
});

And with reactiveProp There is no need for data props :

<my-line v-if="showLine" :options="options" :mydata="lineData">

@AleWasser

Copy link
Copy Markdown

For Nuxt > 2.9.0 you should use mode: 'client' in the nuxt.config.js:

 plugins: [
    {
      src: '~/plugins/vue-chart.js', mode: 'client'
    }
  ]

And to render it you should use a <client-only> tag

<client-only>
    <my-line :data="data"></my-line>
</client-only>

@Carlos-Henreis

Copy link
Copy Markdown

Help me! Unknown custom element: <my-line> - did you register the component correctly? For recursive components, make sure to provide the "name" option.e

@rvanzon

rvanzon commented Jan 9, 2021

Copy link
Copy Markdown
Author

@Carlos-Henreis are you sure you added the plugin to nuxt.config.js?

@MarcelloTheArcane

Copy link
Copy Markdown

If anyone's getting the "export 'default' (imported as 'Chart') was not found in 'chart.js' error or WEBPACK_IMPORTED_MODULE errors, downgrade your chart.js version to ^2.9.3.

@nuno-studiographene

nuno-studiographene commented Apr 7, 2021

Copy link
Copy Markdown

MarcelloTheArcane Thanks a lot! I spent 3 hours trying to figure out why it wasnt working. Your solution fixed my WEBPACK_IMPORTED_MODULE issue

ghost commented Apr 8, 2021

Copy link
Copy Markdown

@MarcelloTheArcane Thanks Dude. I spent a lot of time why WEBPACK_IMPORTED_MODULE happening I couldn't find anything. I solved

@isebarn

isebarn commented Apr 8, 2021

Copy link
Copy Markdown

For Nuxt > 2.9.0 you should use mode: 'client' in the nuxt.config.js:

 plugins: [
    {
      src: '~/plugins/vue-chart.js', mode: 'client'
    }
  ]

And to render it you should use a <client-only> tag

<client-only>
    <my-line :data="data"></my-line>
</client-only>

Thanks!

If anyone's getting the "export 'default' (imported as 'Chart') was not found in 'chart.js' error or WEBPACK_IMPORTED_MODULE errors, downgrade your chart.js version to ^2.9.3.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment