代码之家  ›  专栏  ›  技术社区  ›  wonder95

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

  •  1
  • wonder95  · 技术社区  · 6 年前

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

    这是 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 更改数据时的元素以及 颜色选择器按钮 组件从调用 TenantTemplateEdit . 我已经证实 initColor 道具正在正确传递,并且在 颜色选择器按钮 ,但我所拥有的并不是 background-color 模板中的属性。

    我需要改变什么才能得到 背景色 设置为初始负载?

    0 回复  |  直到 6 年前
        1
  •  0
  •   muka.gergely    6 年前

    如果你改正了一些错别字之类的 一串 而不是 字符串 ,没有参数 v形绑定 ,清除 安装() 钩住picker模板)在代码中,它应该可以工作。

    下面是一个工作示例(当您选择新颜色时,内部颜色会发生变化,并在初始加载时设置):

    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>
    

    编辑

    我更新了沙盒(以及这里的代码)以从输入字段开始工作。我想它能做它该做的一切。