问题
I would like to create my own CustomMdInput, with basic validation. I would like to implement a input that work that way:
I use a <fp-input v-model="test"></fp-input>
, and It is important, that when this input is required, when someone clicked on it or typesomething (turns 'touched' or 'dirty' property), and next defocus this input and go to the another input, the previous one stays Invalid with all the validation, so i have something like this:
<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>
But i don't know how to check if this input isDirty or isTouched, and how can i set Validity of this input to check isFormValid after submit
回答1:
give you an example
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>
give you a full example
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>
来源:https://stackoverflow.com/questions/50239044/custom-vue-material-md-input-how-to-get-isdirty-or-istouched