Skip to content Skip to sidebar Skip to footer

Prop Value In Vuejs Child Component Not Available To Bind To Element Attribute

I am working on an admin app in Vuejs with Vuetify, and I have three fields in a form for a user to select a hex color value. To make it easier for the user, I have implemented a c

Solution 1:

If you correct some typos and such (like string instead of String, no parameters at v-bind, clearing out the mounted() hook in the picker template) in the code, it should work.

Here's a working example (the inner color changes as you pick a new color, and it's set on initial load):

https://codesandbox.io/s/p9620jzoy7

I hope I correctly understood your problem and this snippet helps.

I paste the code here (the code is edited so it can be used in a sandbox environment):

// ColorPickerButton.vue

<template><divref="colorpicker"class="color-picker-outer"><spanclass="color-picker-inner":style="{ 'background-color': colorValue}"
      @click="togglePicker"
    ></span>
    Child init: {{initColor}}
    Child color: {{colorValue}}
    <chrome-picker:value="colors" @input="updateFromPicker"v-if="displayPicker"/></div></template><script>import { Chrome } from"vue-color";

exportdefault {
  props: {
    fieldName: String,
    initColor: String
  },
  components: {
    "chrome-picker": Chrome
  },
  data() {
    return {
      colors: {
        hex: "#000000"
      },
      colorValue: this.initColor,
      displayPicker: false
    };
  },
  mounted() {
    // actually there's no such as 'this.color'// in this template// this.setColor(this.color || "#3121e0");
  },
  methods: {
    setColor(color) {
      this.updateColors(color);
      this.colorValue = color;
    },
    updateColors(color) {
      if (color.slice(0, 1) === "#") {
        this.colors = {
          hex: color
        };
      } elseif (color.slice(0, 4) === "rgba") {
        var rgba = color.replace(/^rgba?\(|\s+|\)$/g, "").split(","),
          hex =
            "#" +
            (
              (1 << 24) +
              (parseInt(rgba[0], 10) << 16) +
              (parseInt(rgba[1], 10) << 8) +
              parseInt(rgba[2], 10)
            )
              .toString(16)
              .slice(1);
        this.colors = {
          hex: hex,
          a: rgba[3]
        };
      }
    },
    showPicker() {
      document.addEventListener("click", this.documentClick);
      this.displayPicker = true;
    },
    hidePicker() {
      document.removeEventListener("click", this.documentClick);
      this.displayPicker = false;
    },
    togglePicker() {
      this.displayPicker ? this.hidePicker() : this.showPicker();
    },
    updateFromInput() {
      this.updateColors(this.colorValue);
    },
    updateFromPicker(color) {
      this.colors = color;
      if (color.rgba.a === 1) {
        this.colorValue = color.hex;
      } else {
        this.colorValue =
          "rgba(" +
          color.rgba.r +
          ", " +
          color.rgba.g +
          ", " +
          color.rgba.b +
          ", " +
          color.rgba.a +
          ")";
      }
    },
    documentClick(e) {
      var el = this.$refs.colorpicker,
        target = e.target;
      if (el !== target && !el.contains(target)) {
        this.hidePicker();
      }
      this.$emit("update-color", this.colorValue, this.fieldName);
    }
  },
  watch: {
    initColor: function(newVal, oldVal) {
      console.log(newVal);
      this.colorValue = newVal;
    }
  }
};
</script><stylescoped>div.color-picker-outer {
  width: 55px;
  height: 50px;
  display: inline-block;
  background-color: #EEE;
  position: relative;
}

.color-picker-inner {
  width: 30px;
  height: 30px;
  position: relative;
  top: 10px;
  left: 13px;
  display: inline-block;
}

.vc-chrome {
  position: absolute;
  top: 0px;
  left: 55px;
  z-index: 9;
}
</style>

The other template:

// TenantTemplateEdit.vue

<template><v-layoutrow><v-flexxs4><v-text-fieldv-bind:field-name="fields.alertBackgroundColor"v-model="templateModel.alertBackgroundColor"placeholder="#4A4A4A"
      />
      Parent: {{templateModel.alertBackgroundColor}}
    </v-flex><v-flexxs2><ColorPickerButtonv-bind:field-name="'alertBackgroundColor'"v-bind:init-color="templateModel.alertBackgroundColor"v-on:update-color="getUpdatedColor"
      ></ColorPickerButton></v-flex><!-- Alert Text Color --><v-flexxs4><v-text-fieldv-bind:field-name="fields.alertTextColor"v-model="templateModel.alertTextColor"placeholder="#4A4A4A"
      /></v-flex><v-flexxs2><ColorPickerButtonv-bind:field-name="'alertTextColor'"v-bind:init-color="templateModel.alertTextColor"v-on:update-color="getUpdatedColor"
      ></ColorPickerButton></v-flex></v-layout></template><script>importColorPickerButtonfrom"./ColorPickerButton";
exportdefault {
  components: {
    ColorPickerButton
  },
  data() {
    return {
      fields: {
        alertBackgroundColor: "#00ff00",
        alertTextColor: "#ff0000"
      },
      templateModel: {
        alertBackgroundColor: "#00ff00",
        alertTextColor: "#ff0000"
      }
    };
  },
  methods: {
    getUpdatedColor(colorValue, fieldName) {
      this.fields[fieldName] = colorValue;
      this.templateModel[fieldName] = colorValue;
    }
  }
};
</script>

EDIT

I updated the sandbox (and the code here on SO) to work from the input field. I think it does everything it's supposed to do.

Post a Comment for "Prop Value In Vuejs Child Component Not Available To Bind To Element Attribute"