-1

How do I import vue-color into my project? When I try to import and render the component like so

<template>
  <div class="helloWorld">
    <Chrome />
  </div>
</template>

<script>
  import { Chrome } from 'vue-color'

  export default {
    components: {
      'chrome-picker': Chrome
    },
  }
</script>

I get this error

vue.runtime.esm.js?2b0e:619 [Vue warn]: Unknown custom element: <Chrome> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

found in

---> <Anonymous>
       <Root>

How do I import vue-color and use it in my nuxt.js/vue.js project?

kissu
  • 40,416
  • 14
  • 65
  • 133
Digglit
  • 576
  • 1
  • 4
  • 11

2 Answers2

2

As it turns out, vue-color does not support server-side rendering, which is where nuxt.js is running into problems with this component. You'll need to render the component only on the client-side, which is slightly more involved than importing directly to the file.

First, you'll want to create a new file in your plugins directory called "MyPlugin.client.js". By adding that client.js part, we are telling nuxt.js that this plugin is only to be rendered on the client. (Note: There is also a .server.js extension for server-only rendering).

In this file, we'll need to add our picker of choice to our project with the following

import Vue from 'vue'
import { Chrome } from 'vue-color'

Vue.component('chrome-picker', Chrome)

Save this file, then we're going to need to import that in our nuxt.config.js. In that file, find your "plugins" and add the file. Your plugins property should like something like this

plugins: [
  { src: '~/plugins/ColorPicker.client.js', mode: 'client'},
],

In this case, "mode: 'client'" is slightly redundant, as we've already specified to nuxt that our plugin is client only with the .client.js extension - I just add it in for good measure.

Now, to reference our new component, we'll add the following code inside our html

<client-only>
  <chrome-picker :value="primaryColor" @input="updateColor" class="colorPicker"/>
</client-only>

Your vue-color component should now be rendering as planned. I hope this helps some people struggling with this, as I was very confused myself.

Digglit
  • 576
  • 1
  • 4
  • 11
  • This is importing the whole thing globally, which may not be the desired behavior if used in only one place tho. – kissu May 24 '22 at 16:22
1

Your answer is supposing that you will use the package from a plugin, which means:

  • that it will be available globally across your application (rather than just in one place)
  • it will add loading time overall because plugins are initially loaded
  • in this case, it adds a good 25.5kB on top of the rest too

If you want to load your vue-color in only one place, you could use the solution given at the end of my answer here aka

export default {
  components: {
    // a destructuring step may be further needed here? like { Chrome }
    [process.client && 'chrome-picker']: () => import('vue-color'),
  }
}

This will ensure that the package is loaded only on the client-side and locally on that page/component.

kissu
  • 40,416
  • 14
  • 65
  • 133
  • Does that ~25.5kB influence load times for all rendering methods? I.e. SPA, SSR and static? – Digglit May 24 '22 at 17:10
  • @Digglit this impacts the JS part, happening during the hydration which is triggered in all of the 3 listed cases yes (you cannot not hydrate in Nuxt). – kissu May 24 '22 at 17:12
  • I see. Do you happen to know where I could learn more about all of that? – Digglit May 24 '22 at 17:19
  • 1
    @Digglit depends what do you mean by `that`. I am a good source overall, otherwise you could look into websites [like that](https://www.patterns.dev/posts/), explaining how to optimize the whole JS on the client side. – kissu May 24 '22 at 17:31