Skip to content

Commit

Permalink
feat: allow usage of Vuelidate outside Vue components (vuelidate#828)
Browse files Browse the repository at this point in the history
* fix: allow usage outside vue components

* fix: use proper type for childResults
  • Loading branch information
dobromir-hristov authored Mar 24, 2021
1 parent 0790a56 commit 4816b7d
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 11 deletions.
28 changes: 19 additions & 9 deletions packages/vuelidate/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,13 @@ export function useVuelidate (validations, state, globalConfig = {}) {
}
let { $registerAs, $scope = CollectFlag.COLLECT_ALL, $stopPropagation } = globalConfig

const instance = getCurrentInstance()
let instance = getCurrentInstance()

const componentOptions = isVue3 ? instance.type : instance.proxy.$options
const componentOptions = instance
? (isVue3 ? instance.type : instance.proxy.$options)
: {}
// if there is no registration name, add one.
if (!$registerAs) {
if (!$registerAs && instance) {
// NOTE:
// ._uid // Vue 2.x Composition-API plugin
// .uid // Vue 3.0
Expand All @@ -108,7 +110,13 @@ export function useVuelidate (validations, state, globalConfig = {}) {
const validationResults = ref({})
const resultsCache = new ResultsStorage()

const { childResults, sendValidationResultsToParent, removeValidationResultsFromParent } = nestedValidations({ $scope, $stopPropagation })
const {
childResults,
sendValidationResultsToParent,
removeValidationResultsFromParent
} = instance
? nestedValidations({ $scope })
: { childResults: ref({}) }

// Options API
if (!validations && componentOptions.validations) {
Expand Down Expand Up @@ -159,17 +167,19 @@ export function useVuelidate (validations, state, globalConfig = {}) {
childResults,
resultsCache,
globalConfig,
instance: instance.proxy
instance: instance ? instance.proxy : {}
})
}, {
immediate: true
})
}

// send all the data to the parent when the function is invoked inside setup.
sendValidationResultsToParent(validationResults, { $registerAs, $scope, $stopPropagation })
// before this component is destroyed, remove all the data from the parent.
onBeforeUnmount(() => removeValidationResultsFromParent($registerAs))
if (instance) {
// send all the data to the parent when the function is invoked inside setup.
sendValidationResultsToParent(validationResults, { $registerAs, $scope, $stopPropagation })
// before this component is destroyed, remove all the data from the parent.
onBeforeUnmount(() => removeValidationResultsFromParent($registerAs))
}

// TODO: Change into reactive + watch
return computed(() => {
Expand Down
23 changes: 22 additions & 1 deletion packages/vuelidate/test/unit/specs/validation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import {
shouldBePristineValidationObj,
shouldBeInvalidValidationObject,
shouldBeErroredValidationObject,
createSimpleComponent
createSimpleComponent,
shouldBeValidValidationObj
} from '../utils'
import { withMessage, withParams } from '@vuelidate/validators/src/common'
import useVuelidate, { CollectFlag } from '../../../src'
Expand Down Expand Up @@ -1118,6 +1119,26 @@ describe('useVuelidate', () => {
})
})

describe('Usage outside of Vue components', () => {
it('does not throw', () => {
const { validations, state } = simpleValidation()
expect(() => useVuelidate(validations, state)).not.toThrow()
})

it('returns a reactive Vuelidate state', async () => {
const { validations, state } = simpleValidation()
const v = useVuelidate(validations, state)
expect(v).toHaveProperty('value')
await nextTick()
shouldBeInvalidValidationObject({ v: v.value, property: 'number', validatorName: 'isEven' })
v.value.$touch()
shouldBeErroredValidationObject({ v: v.value, property: 'number', validatorName: 'isEven' })
v.value.number.$model = 6
await nextTick()
shouldBeValidValidationObj(v.value.number)
})
})

// it('should allow watching a v state', async () => {
// let watcherValue = null
// let watcherValueOld = null
Expand Down
9 changes: 8 additions & 1 deletion packages/vuelidate/test/unit/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export async function createOldApiSimpleWrapper (rules, state, config = {}) {
}

export const shouldBePristineValidationObj = (v) => {
expect(v).toHaveProperty('$error', false)
expect(v).toHaveProperty('$error', false)
expect(v).toHaveProperty('$errors', [])
expect(v).toHaveProperty('$silentErrors', [])
Expand All @@ -57,6 +56,14 @@ export const shouldBePristineValidationObj = (v) => {
expect(v).toHaveProperty('$reset', expect.any(Function))
}

export const shouldBeValidValidationObj = (v) => {
expect(v).toHaveProperty('$error', false)
expect(v).toHaveProperty('$errors', [])
expect(v).toHaveProperty('$silentErrors', [])
expect(v).toHaveProperty('$invalid', false)
expect(v).toHaveProperty('$pending', false)
}

export const shouldBeInvalidValidationObject = ({ v, property, propertyPath = property, validatorName }) => {
expect(v).toHaveProperty('$error', false)
expect(v).toHaveProperty('$errors', [])
Expand Down

0 comments on commit 4816b7d

Please sign in to comment.