Значение пропуска в дочернем компоненте Vuejs недоступно для привязки к атрибуту элемента - PullRequest
3 голосов
/ 07 мая 2019

Я работаю над приложением администратора в Vuejs с Vuetify, и у меня есть три поля в форме, чтобы пользователь мог выбрать шестнадцатеричное значение цвета.Чтобы было проще для пользователя, я реализовал палитру цветов на основе этой кодовой ручки .

Вот компонент 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 в шаблоне.

Что мне нужно изменитьbackground-color установить при начальной загрузке?

1 Ответ

0 голосов
/ 07 мая 2019

Если вы исправите некоторые опечатки и тому подобное (например, string вместо String , никаких параметров в v-bind нет, очистка смонтированного () перехватывает шаблон выбора) в коде, он должен работать.

Вот рабочий пример (внутренний цвет изменяется при выборе нового цвета и устанавливается при начальной загрузке):

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>

EDIT

Я обновил песочницу (и код здесь на SO) доработать из поля ввода.Я думаю, что он делает все, что должен.

...