子组件的值绑定到同一vue组件的另一个实例的属性。

问题描述 投票:0回答:1

我有一个自定义组件的问题。问题是这样的。

Password show problem

这个屏幕实际上是3次相同的Vue组件。

<div class="passwords__form">
            <InputField class="passwords__field" label="Mot de passe actuel" :password="true" v-model="currentPassword" />
            <InputField class="passwords__field" label="Nouveau mot de passe" :password="true" v-model="newPassword" />
            <InputField class="passwords__field" label="Répéter le nouveau mot de passe" :password="true" v-model="repeatedPassword" />
            <Button title="Changer le mot de passe" @click="updatePassword"/>
</div>

这是组件的代码

<template>
  <div
    class="field__container"
    :class="{ 'field__container--disabled': disabled }"
  >
    <label
      :for="this._uid"
      class="field__label"
      :class="{ 'field__label--disabled': disabled }"
      v-if="labelEnabled"
      >{{ label }}</label
    >
    <input
      :id="this._uid"
      class="field__input"
      :class="{
        'left-rounded': !labelEnabled && !password,
        'right-rounded': !buttonEnabled && !password
      }"
      :value="value"
      :placeholder="placeholder"
      @input="$emit('input', $event.target.value)"
      @keyup.enter="$emit('keyup-enter')"
      :disabled="disabled"
      :type="fieldType"
    />
    <input
      v-if="password && enableShowPassword"
      type="checkbox"
      v-model="showPassword"
      id="password-checkbox"
      class="field__password-checkbox"
    /><label
      v-if="password && enableShowPassword"
      for="password-checkbox"
      class="field__password-checkbox-label"
      :class="{
        'right-rounded': !buttonEnabled,
      }"
    ><span v-if="enableShowPassword && showPassword"><EyeSlash class="field__password-checkbox-icon"/></span><span v-if="!showPassword" ><Eye class="field__password-checkbox-icon field__password-checkbox-icon--eye " /></span></label>
    <a
      v-if="buttonEnabled"
      class="field__button"
      @click.stop="$emit('button-click')"
    >
      {{ button }}
    </a>
  </div>
</template>

<script lang="ts">
import Component from "vue-class-component";
import Vue from "vue";
import { Prop } from "vue-property-decorator";
import Eye from "../assets/images/icons/eye-regular.svg"
import EyeSlash from "../assets/images/icons/eye-slash-regular.svg"

@Component({
  components: {
    Eye,
    EyeSlash
  }
})
export default class InputField extends Vue {
  @Prop({ default: "", required: false })
  label!: string;

  @Prop({ required: true })
  value!: string;

  @Prop({ default: "", required: false })
  placeholder!: string;

  @Prop({ default: "", required: false })
  button!: string;

  @Prop({ default: false, required: false })
  disabled!: boolean;

  @Prop({ default: false, required: false })
  password!: boolean;

  @Prop({ default: true, required: false })
  enableShowPassword!: boolean;

  showPassword = false;

  get fieldType(): string {
    if (this.password && !this.showPassword) {
      return "password";
    }
    return "text";
  }

  get labelEnabled(): boolean {
    return this.label !== "";
  }

  get buttonEnabled(): boolean {
    return this.button !== "";
  }
}
</script>

<style lang="scss">
.field {
  &__container {
    display: flex;
    flex-direction: row;
    border: 1px solid $color-grey-7;
    font-size: 1.6rem;
    transition: all 0.3s;

    &:hover:not(&--disabled),
    &:focus:not(&--disabled) {
      border: 1px solid $color-complementary;

      & > .field__label {
        background: $color-complementary;
      }
    }

    &--disabled {
      cursor: not-allowed;
    }
  }
  &__label {
    text-align: center;
    padding: 0.5rem 2rem;
    border-right: 1px solid $color-grey-8;
    background-color: $color-grey-8;
    transition: all 0.3s;

    &--disabled {
      cursor: not-allowed;
    }
  }
  &__input {
    flex-grow: 2;
    border: none;

    color: $color-grey-1;
    transition: all 0.3s;
    padding: 0 1rem;

    &:hover,
    &:focus {
      outline: none;
    }

    &--disabled {
      cursor: not-allowed;
    }
  }

  &__button {
    text-align: center;
    padding: 0.5rem 2rem;
    border-left: 1px solid $color-grey-7;
    transition: all 0.3s;

    &:hover,
    &:active {
      background: $color-grey-7;
    }
  }

  &__password-checkbox {
    display: none;
  }

  &__password-checkbox-label {
    background-color: $color-grey-9;
    padding: 0.6rem 1rem;
    cursor: pointer;

    &:hover,
    &:active {
      background-color: $color-complementary-lighter;
    }
  }

  &__password-checkbox-icon {
    width: 1.5rem;

    &--eye {
      position: relative;
      top: 1px;
    }
  }
}
</style>

我认为问题来自于 v-model 属性的复选框。在我看来,v-model绑定到了复选框上的 showPassword 属性,而不是绑定到InputField的当前实例。

我不知道为什么它的行为是这样的,我的错误是什么,以及如何纠正它做正确的方式。有人有什么线索吗?

vue.js data-binding components multiple-instances
1个回答
1
投票

我想你应该使用一个独特的 身份证 输入类型="password",就像你输入一般的输入一样。:id="this._uid" 因为在一个HTML页面上,所有的 id元素中声明的''必须是唯一的。

© www.soinside.com 2019 - 2024. All rights reserved.