首页 > 解决方案 > 自定义Vue Material md-Input如何获取isDirty或isTouched

问题描述

我想创建自己的 CustomMdInput,并进行基本验证。我想实现一个以这种方式工作的输入:

我使用 a <fp-input v-model="test"></fp-input>,并且重要的是,当需要此输入时,当有人单击它或键入某些内容(变为“触摸”或“脏”属性)时,然后散焦此输入并转到另一个输入,即前一个在所有验证中保持无效,所以我有这样的事情:

<template>
  <div class="md-layout-item">
    <md-field>
      <label :for="id">Imię</label>
      <md-input :name="id" :id="id" :required="required" v-model="value" :ref="id" @input="emitValue()"></md-input>
      <span class="md-error">Imię jest obowiązkowe</span>
    </md-field>
  </div>
</template>

<script>
export default {
  name: 'FpInput',
  props: {
    value: {
      required: true
    },
    id: {
      required: true,
      type: String
    },
    required: {
      default: false,
      type: Boolean
    }
  },
  methods: {
    emitValue () {
      this.$emit('input', this.$refs[this.id].value)
    }
  }
}
</script>

<style scoped>

</style>

但我不知道如何检查此输入是脏还是已触摸,以及如何设置此输入的有效性以在提交后检查 isFormValid

标签: vue.jsvuejs2vue-componentvue-material

解决方案


举个例子

const MyInput = {
			template: '#myInput',
			props: ['value'],
			data () {
				return {
					inputValue: this.value,
					dirty: false,
					touched: false,
					inValid: false
				}
			},
			methods: {
				validate () {
					if(this.inputValue.length<5){
						this.inValid = true
						this.dirty = true
					}else{
						this.inValid = false
						this.dirty = false
						this.touched = false
					}
				},
				emitValue() {
					this.validate()
					this.$emit('input', this.inputValue);
				}
			}
		}

		var app = new Vue({
		  el: '#app',
		  components: {MyInput},
		  data () {
		    return {
		    }
		  }
		})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	<div id="app">
	  <my-input value="5"></my-input>
	</div>

	<script type="text/x-template" id="myInput">
		<div>
      		<input v-model="inputValue" @input="emitValue()" @touchstart="touched = true" @mousedown="touched = true"/>
			<span v-show="(dirty || touched) && inValid">must be at least 5 letters</span>
			<div>dirty:{{dirty}}</div>
			<div>touched:{{touched}}</div>
			<div>inValid:{{inValid}}</div>
		</div>
	</script>

给你一个完整的例子

const MyInput = {
  template: '#myInput',
  props: ['value'],
  data () {
    return {
      inputValue: this.value,
      dirty: false,
      touched: false,
      inValid: false
    }
  },
  methods: {
    validate () {
      if(('' + this.inputValue).length<5){
        this.inValid = true
        this.dirty = true
      }else{
        this.inValid = false
        this.dirty = false
        this.touched = false
      }
    },
    emitValue(e) {
      this.validate()
      this.$emit('input', this.inputValue);
    }
  },
  created () {
    this.inputValue = this.value;
    this.validate();
    this.dirty = false;
  }
}

var app = new Vue({
  el: '#app',
  components: {MyInput},
  data () {
    return {
      inputList: new Array(4).fill('').map(o=>({val:5}))
    }
  },
  methods: {
    submit () {
      if(this.$refs.inputs.some(o=>o.inValid)){
        alert('you have some input invalid')
      }else{
        alert('submit data...')
      }
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	<div id="app">
  <form @submit.prevent="submit">
      <my-input ref="inputs" v-for="item in inputList" v-model="item.val"></my-input>
    <button type="submit">submit</button>
  </form>
</div>

<script type="text/x-template" id="myInput">
  <div>
        <input v-model="inputValue" @input="emitValue()" @touchstart="touched = true"/>
    <span v-show="(dirty || touched) && inValid">must be at least 5 letters</span>
  </div>
</script>


推荐阅读