Skip to content

Instantly share code, notes, and snippets.

@rvanzon
Last active September 1, 2022 13:25
Show Gist options
  • Save rvanzon/096132b7b46be43659cf26360c664e9a to your computer and use it in GitHub Desktop.
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)
}
}))
@raviasthra
Copy link

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
Copy link

codehunter12345 commented Dec 4, 2019

@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

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

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
Copy link
Author

rvanzon commented Jan 9, 2021

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

@MarcelloTheArcane
Copy link

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
Copy link

nuno-studiographene commented Apr 7, 2021

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

Copy link

ghost commented Apr 8, 2021

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

@isebarn
Copy link

isebarn commented Apr 8, 2021

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