0

The later versions of Vue JS 2 are complaining about using v-model on a button. It shows the error:

<button v-model="settings.primary_color">: v-model is not supported on this element type. If you are working with contenteditable, it's recommended to wrap a library dedicated for that purpose inside a custom component.

Here is my button:

<button type="button" class="colorpicker" v-model="settings.primary_color" :data-color="settings.primary_color" :style="{'background-color' : settings.primary_color}"></button>

Is it possible to achieve two way data binding using something like the data-color property rather than an input value?

2 Answers 2

1

Off course it is possible, that's the goal of modern JS frameworks.

What the error says is that binding data on "button" tag is not possible. The reason is that "button" is a native html element.

So if you want to bind datas on a button, just create a new component like "my-button", then you could achieve ti !

<my-button 
    class="colorpicker"
    :type="button"
    v-model="settings.primary_color" 
    :data-color="settings.primary_color" 
    :style="{'background-color' : settings.primary_color}"
></my-button>
Sign up to request clarification or add additional context in comments.

7 Comments

But isn't there an easier way just to bind the data considering that there could be an unlimited number of buttons, each with their own setting or that these buttons could be created on the fly?
So, what is your real need ? I don't get it :/ If i look at your vars, you apparently want to bind a color to the button, right ?
Yep right, but these buttons are each bound to different settings properties, and in the future these buttons could also be created on the fly. So I can't hard code a new button component for every button? Can I?
So, i don't even think you need to create a component, you just to define a css class and do : <button class='bg-primary'></button> with a "bg-primary" class you can redfine later (with a custom theme by user for exemple)
Actually I think you were right with the component. I've not used them before and I see you can add custom props which should work nicely...
|
0

By better understanding your problem, I propose you this solution

Just change your button by an input[type="color"]

The component :

<template>
  <div>
    <input type="color" v-model="color"/>
    {{ color }}
  </div>
</template>

<script>
export default {
  name: "ColorPicker",
  data: () => ({
    color: "#000000",
  }),
};
</script>

And because we have now an input, v-model is possible

EDIT : So, stay with your button (i guess, that your colorpicker class is important because you already did some work on it)

According to VueJs documentation, to create your own two ways data binding, you have to get the prop "value" and emit the signal "input" on the component

(I just made a generateRandomColor() function to be faster)

Create a button component :

<template>
  <div>
    <button class="colorpicker" @click="triggered">Click me</button>
  </div>
</template>


<script>
export default {
  name: "ColorPicker",
  props: {
    value: String,
  },
  data: () => ({
    value_: "#000000",
  }),
  methods: {
    triggered: function () {
      this.value_ = this.getRandomColor();
      this.$emit("input", this.value_);
    },
    getRandomColor: function () {
      var letters = "0123456789ABCDEF";
      var color = "#";
      for (var i = 0; i < 6; i++) {
        color += letters[Math.floor(Math.random() * 16)];
      }
      return color;
    },
  },
};
</script>

Then, call it in your parent :

<color-picker v-model="colors.primary"></color-picker>

For your use, you just have to update the value_ property in custom button component and value will automatically update in parent

4 Comments

The reason I'm not using a color input is because I can't style the preview button how I would like.
Updated again, this time if it is not ok, try to tchat me
How about a chat tomorrow? I'll post my full Vue code. What time zone are you in?
OK for me i'm at GMT+2 (Paris, France)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.