diff --git a/src/components/validity/lifecycles.js b/src/components/validity/lifecycles.js index 827ca92..4e41b20 100644 --- a/src/components/validity/lifecycles.js +++ b/src/components/validity/lifecycles.js @@ -38,6 +38,14 @@ export default function (Vue: GlobalAPI): Object { return targets } + function watchModelable (val: any): void { + this.$emit('input', { + result: this.result, + progress: this.progress, + progresses: this.progresses + }) + } + function created (): void { this._elementable = null @@ -69,6 +77,16 @@ export default function (Vue: GlobalAPI): Object { instance.unregister(this.field, this, { named: name, group }) } + if (this._unwatchResultProp) { + this._unwatchResultProp() + this._unwatchResultProp = null + } + + if (this._unwatchProgressProp) { + this._unwatchProgressProp() + this._unwatchProgressProp = null + } + this._unwatchValidationRawResults() this._elementable.unlistenInputableEvent() @@ -85,6 +103,11 @@ export default function (Vue: GlobalAPI): Object { // TODO: should be warn } + if (hasModelDirective(this.$vnode)) { + this._unwatchResultProp = this.$watch('result', watchModelable) + this._unwatchProgressProp = this.$watch('progress', watchModelable) + } + toggleClasses(this.$el, this.classes.untouched, addClass) toggleClasses(this.$el, this.classes.pristine, addClass) } @@ -116,3 +139,8 @@ function checkBuiltInElement (vnode: VNode): any { !vnode.componentOptions && vnode.tag } + +function hasModelDirective (vnode: VNode): boolean { + return ((vnode && vnode.data && vnode.data.directives) || []).find(dir => { return dir.name === 'model' }) ? true : false +} + diff --git a/src/components/validity/states.js b/src/components/validity/states.js index 09ecd79..e57861b 100644 --- a/src/components/validity/states.js +++ b/src/components/validity/states.js @@ -44,6 +44,9 @@ export default function (Vue: GlobalAPI): Object { child: { type: Object, required: true + }, + value: { + type: Object } }, baseProps) diff --git a/test/unit/components/validity-functional.test.js b/test/unit/components/validity-functional.test.js index cc45029..da057fe 100644 --- a/test/unit/components/validity-functional.test.js +++ b/test/unit/components/validity-functional.test.js @@ -1003,4 +1003,64 @@ describe('validity functional component', () => { }) }) }) + + describe('v-model', () => { + it('should be work', done => { + function createModelDirective (key, value, modifier) { + const modifiers = modifier ? { validity: true } : {} + return [{ + expression: key, + modifiers, + name: 'model', + rawName: 'v-model', + value: value + }] + } + const vm = new Vue({ + data: { validation: {}}, + components, + validators: { + exist (val) { + return new Promise((resolve, reject) => { + setTimeout(() => { + val === 'dio' ? resolve() : reject() + }, 5) + }) + } + }, + render (h) { + const input = (function ($event) { this.validation = $event }).bind(this) + return h('div', [ + h('validity', { + props: { + field: 'field1', + validators: ['required', 'numeric', 'exist'] + }, + directives: createModelDirective('validation', this.validation), + on: { input }, + ref: 'validity', + }, [ + h('input', { ref: 'textbox', attrs: { type: 'text' }}) + ]) + ]) + } + }).$mount(el) + const { validity, textbox } = vm.$refs + waitForUpdate(() => { + validity.validate() // validate !! + }).thenWaitFor(1).then(() => { + assert.deepEqual(vm.validation, { + result: validity.result, + progress: validity.progress, + progresses: validity.progresses + }) + }).thenWaitFor(6).then(() => { + assert.deepEqual(vm.validation, { + result: validity.result, + progress: validity.progress, + progresses: validity.progresses + }) + }).then(done) + }) + }) })