Vuejs子组件中的属性值不可绑定到元素属性

时间:2019-05-07 03:55:55

标签: javascript data-binding vuejs2 vue-component vuetify.js

我正在使用Vuetify在Vuejs中开发一个管理应用程序,并且在表单中有三个字段供用户选择十六进制颜色值。为了使用户更轻松,我基于this codepen实现了一个颜色选择器。

这里是---- -------- ------------------ -------- ------- autogen 0s 168h0m0s 1 false oneday 24h0m0s 1h0m0s 1 true onemonth 720h0m0s 24h0m0s 1 false MONTH 720h0m0s 24h0m0s 1 false YEARs 8736h0m0s 168h0m0s 1 false 组件:

ColorPickerButton

这是我从父级<template> <div ref="colorpicker" class="color-picker-outer"> <span class="color-picker-inner" v-bind:style="{ 'background-color': colorValue}" @click="togglePicker"></span> <chrome-picker :value="colors" @input="updateFromPicker" v-if="displayPicker" /> </div> </template> <script> import { Chrome } from 'vue-color' export default { props: { fieldName: String, initColor: string }, components: { 'chrome-picker': Chrome }, data() { return { colors: { hex: '#000000', }, colorValue: this.initColor, displayPicker: false, } }, mounted() { 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 }; } else if(color.slice(0, 4) == 'rgba') { var rgba = color.replace(/^rgba?\(|\s+|\)$/g,'').split(','), hex = '#' + ((1 << 24) + (parseInt(rgba[0]) << 16) + (parseInt(rgba[1]) << 8) + parseInt(rgba[2])).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: { colorValue(val) { if(val) { this.updateColors(val); this.$emit('input', val); //document.body.style.background = val; } } } } </script> <style scoped> 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> 组件调用它的方式。

TenantTemplateEdit.vue

我正在努力解决的问题是在更改数据时为 <v-layout row> <v-flex xs4> <v-text-field v-bind="fields.alertBackgroundColor" v-model="templateModel.alertBackgroundColor" placeholder="#4A4A4A" /> </v-flex> <v-flex xs2> <ColorPickerButton v-bind:field-name="'alertBackgroundColor'" v-bind:init-color="templateModel.alertBackgroundColor" v-on:update-color="getUpdatedColor"> </ColorPickerButton> </v-flex> <!-- Alert Text Color --> <v-flex xs4> <v-text-field v-bind="fields.alertTextColor" v-model="templateModel.alertTextColor" placeholder="#4A4A4A" /> </v-flex> <v-flex xs2> <ColorPickerButton v-bind:field-name="'alertTextColor'" v-bind:init-color="templateModel.alertTextColor" v-on:update-color="getUpdatedColor" ></ColorPickerButton> </v-flex> </v-layout> 元素设置初始颜色。 span.color-picker-inner会调用ColorPickerButton组件。我已经验证TenantTemplateEdit道具已经正确传递并且可以在initColor中使用,但是我没有得到模板中的ColorPickerButton属性。

要在初始加载时设置background-color,我需要更改什么?

1 个答案:

答案 0 :(得分:0)

如果您更正了某些拼写错误(如 string 而不是 String ),则在 v-bind 处没有参数,请清除代码中的> Mount()钩子,它应该可以工作。

这是一个可行的示例(内部颜色随您选择新颜色而变化,并且在初始加载时设置):

https://codesandbox.io/s/p9620jzoy7

希望我能正确理解您的问题,并且此片段对您有所帮助。

我将代码粘贴到此处(对代码进行了编辑,以便可以在沙盒环境中使用):

// ColorPickerButton.vue

<template>
  <div ref="colorpicker" class="color-picker-outer">
    <span
      class="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";

export default {
  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
        };
      } else if (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>

<style scoped>
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>

另一个模板:

// TenantTemplateEdit.vue

<template>
  <v-layout row>
    <v-flex xs4>
      <v-text-field
        v-bind:field-name="fields.alertBackgroundColor"
        v-model="templateModel.alertBackgroundColor"
        placeholder="#4A4A4A"
      />
      Parent: {{templateModel.alertBackgroundColor}}
    </v-flex>
    <v-flex xs2>
      <ColorPickerButton
        v-bind:field-name="'alertBackgroundColor'"
        v-bind:init-color="templateModel.alertBackgroundColor"
        v-on:update-color="getUpdatedColor"
      ></ColorPickerButton>
    </v-flex>
    <!-- Alert Text Color -->
    <v-flex xs4>
      <v-text-field
        v-bind:field-name="fields.alertTextColor"
        v-model="templateModel.alertTextColor"
        placeholder="#4A4A4A"
      />
    </v-flex>
    <v-flex xs2>
      <ColorPickerButton
        v-bind:field-name="'alertTextColor'"
        v-bind:init-color="templateModel.alertTextColor"
        v-on:update-color="getUpdatedColor"
      ></ColorPickerButton>
    </v-flex>
  </v-layout>
</template>
<script>
import ColorPickerButton from "./ColorPickerButton";
export default {
  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>

编辑

我更新了沙箱(以及SO上的代码)以从输入字段开始工作。我认为它可以完成应该做的所有事情。