vue.js - 视觉 : v-model and input event in custom component derived of a custom component

标签 vue.js vuejs2 vue-component

我有一个自定义输入,我在其中接收值 Prop 并在输入事件上发出输入事件。我可以使用这个自定义输入而不会出现模型问题,现在我正在创建一个自定义密码输入,我将其初始化为自定义输入但我无法使用值和输入事件处理程序绑定(bind)模型(将它们传递给自定义输入) .我该如何处理?

自定义输入:

  • 我的程序模型 > 自定义输入(值和输入事件处理程序):有效
  • 我的程序模型 > 自定义密码(值和输入事件处理程序)> 自定义输入:不起作用

代码:

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 事件,你的 Passwordapp-input 组件中监听,其值 已经是实际的字符串值,而不是元素(您必须调用 e.target.value 来获取字符串值)

换句话说,在 Password.vue 中,而不是:

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

做:

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

CodeSandbox demo here .

关于vue.js - 视觉 : v-model and input event in custom component derived of a custom component,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49989463/

相关文章:

vue.js - 存储有数据时如何调用函数

javascript - 从 Assets 文件夹编译/导入文件

vue.js - VueJS 和动态标题

javascript - JS 文件中未捕获的语法错误

javascript - Vue.js:数据不是 react 性的,并且在方法内没有正确更新

javascript - 尝试刷新 token 时 Axios 拦截器无限循环

javascript - Vue,具有 true/false boolean 值的 v-select 组件

vue.js - 发出 Axios 请求时加载微调器

javascript - 布局组件(抽屉、工具栏等)不作为组件工作

javascript - Vuejs 将 props 从对象传递到动态组件