programing

Vue: 사용자 지정 구성 요소에서 파생된 사용자 지정 구성 요소에서 v-model 및 입력 이벤트

bestcode 2022. 8. 30. 22:19
반응형

Vue: 사용자 지정 구성 요소에서 파생된 사용자 지정 구성 요소에서 v-model 및 입력 이벤트

가치 소품을 받고 입력 이벤트에 입력 이벤트를 내보내는 커스텀 입력이 있습니다.이 커스텀 입력은 모델에 문제 없이 사용할 수 있습니다.커스텀 입력으로 초기화하는 커스텀 패스워드 입력을 만들고 있습니다만, 값이나 입력 이벤트 핸들러를 사용해 모델을 바인드 할 수 없습니다(커스텀 입력에 전달).어떻게 접근하면 좋을까요?

커스텀 입력:

  • 마이 프로그램 모델> 커스텀 입력 (값 및 입력 이벤트 핸들러) : 동작합니다.
  • 프로그램 모델> 커스텀 패스워드(값 및 입력 이벤트 핸들러)> 커스텀 입력: 동작하지 않습니다.

코드:

Input.vue:

<template>
    <div class="form-group">

      <label for="" v-if="typeof label !== 'undefined'">{{ label }}</label>

      <!-- GROUP  -->
      <template v-if="isGroup">
        <div class="input-group">
          <!-- PREPEND  -->
          <div v-if="hasPrepend" class="input-group-prepend"
              :class="{'inside bg-transparent' : prependInside, 'pointer': prependPointer}"
              @click="clickPrepend">

            <span class="input-group-text"
                  :class="{'bg-transparent' : prependInside}">

              <i  aria-hidden="true"
                  v-if="prependType === 'icon'"
                  :class="'fa fa-' + prependContent"></i>

              <template v-if="prependType === 'text'">{{ prependContent }}</template>
            </span>

          </div>

          <!-- INPUT  -->
          <input  class="form-control"
              :type="type"
              :class="generatedInputClass"
              :readonly="readonly"
              :disabled="disabled"
              :value="value"
              @input="inputEvent"
              @change="onChange">

          <!-- APPEND  -->
          <div v-if="hasAppend" class="input-group-append"
              :class="{'inside bg-transparent' : appendInside, 'pointer': appendPointer}"
              @click="clickAppend">

            <span class="input-group-text"
                  :class="{'bg-transparent' : appendInside}">

              <i  aria-hidden="true"
                  v-if="appendType === 'icon'"
                  :class="'fa fa-' + appendContent"></i>

              <template v-if="appendType === 'text'">{{ appendContent }}</template>

            </span>

          </div>
      </div>
      </template>

      <!-- INPUT  -->
      <template v-else>
        <input  class="form-control"
              :type="type"
              :class="generatedInputClass"
              :readonly="readonly"
              :disabled="disabled"
              :value="value"

              @input="inputEvent"
              @change="onChange"
              >
      </template>

      <small  class="form-text"
              v-if="typeof helpText !== 'undefined'"
              :class="generatedHelperClass">
        {{ helpText }}
      </small>

    </div>
</template>

<script>
export default {
  name: 'InputGroup',
  props: {
    value: String,
    label: String,
    helpText: String,
    size: String,
    prependContent: String,
    appendContent: String,
    prependType: {
      type: String,
      default: 'icon',
    },
    appendType: {
      type: String,
      default: 'icon',
    },
    prependInside: {
      type: Boolean,
      default: false,
    },
    appendInside: {
      type: Boolean,
      default: false,
    },
    prependPointer: {
      type: Boolean,
      default: false,
    },
    appendPointer: {
      type: Boolean,
      default: false,
    },
    readonly: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    type: {
      type: String,
      default: 'text',
    },
    valid: {
      type: Boolean,
      default: null,
    },
  },
  watch: {
    valid() {

    },
  },
  computed: {
    isGroup() {
      return this.hasPrepend || this.hasAppend;
    },
    hasPrepend() {
      return typeof this.prependContent !== 'undefined';
    },
    hasAppend() {
      return typeof this.appendContent !== 'undefined';
    },
    generatedInputClass() {
      const size = typeof this.size !== 'undefined' ? `form-control-${this.size}` : '';
      let valid = '';
      if (this.valid !== null) {
        valid = this.valid ? 'is-valid' : 'is-invalid';
      }
      return `${size} ${valid}`;
    },
    generatedHelperClass() {
      let valid = 'text-muted';
      if (this.valid !== null) {
        valid = this.valid ? 'valid-feedback' : 'invalid-feedback';
      }
      return `${valid}`;
    },
  },
  methods: {
    inputEvent(e) {
      this.$emit('input', e.target.value);
    },
    clickPrepend(e) {
      this.$emit('click-prepend', e);
    },
    clickAppend(e) {
      this.$emit('click-append', e);
    },
    onChange(e) {
      this.$emit('change', this.value, e);
    },
  },
};
</script>

패스워드vue:

<template>
<div>

  <app-input
              :label="label"
              :type="type"
              prepend-content="lock"
              :append-content="passwordIcon"
              :append-inside="true"
              :append-pointer="true"
              @click-append="tooglePassword"
              :value="value"
              @input="inputEvent">
  </app-input>
</div>
</template>

<script>
import Input from './Input';

export default {
  name: 'Password',
  components: {
    appInput: Input,
  },
  props: {
    value: String,
    label: {
      type: String,
      default: 'Contraseña',
    },
    readonly: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    valid: {
      type: Boolean,
      default: null,
    },
  },
  data() {
    return {
      pass: '',
      type: 'password',
    };
  },
  computed: {
    passwordIcon() {
      return this.type === 'password' ? 'eye' : 'eye-slash';
    },
  },
  methods: {
    tooglePassword() {
      this.type = this.type === 'password' ? 'text' : 'password';
    },
    inputEvent(e) {
      this.$emit('input', e.target.value);
    },
  },
};
</script>

중요한 건input이벤트:Password리슨 폼app-input컴포넌트: 요소가 아닌 실제 문자열 값이 값으로 이미 설정되어 있습니다(호출할 필요가 있습니다).e.target.value문자열 값을 가져옵니다.)

즉, Password(비밀번호)입니다.vue, 대신:

inputEvent(e) {
  this.$emit('input', e.target.value);
},

작업:

inputEvent(e) {
  this.$emit('input', e);
},

Code Sandbox »입니다.

언급URL : https://stackoverflow.com/questions/49989463/vue-v-model-and-input-event-in-custom-component-derived-of-a-custom-component

반응형