2

I'm using Vuelidate in a project and when the user types something I set a timeout to wait for validation. I tried to use mixins and it was successful, but for good habits I need to create a Vue directive without registering it globally, and use that in some components.

I created an external file directives/delayTouch.js (I tried to export only const with export const but Vue forces me to use export default)

const delayTouch = {
  inserted ($v) {
    const touchMap = new WeakMap()

    $v.$reset()
    if (touchMap.has($v)) {
      clearTimeout(touchMap.get($v))
    }

    touchMap.set($v, setTimeout($v.$touch, 1000))
  }
}

export default delayTouch

And I imported into my component:

<template>
  <TextField
    v-delay-touch="$v.data.name"
    :v="$v.data.name"
    v-model.trim="$v.data.name.$model"
    id="name"
    label="Nome da campanha"
  />
</template>
<script>
import delayTouch from '@/directives/delayTouch'
    
export default {
  directives: { delayTouch }
}
</script>

In param ($v) I receive the HTML correctly but I'm still receiving the error $v.reset is not a function. Why?

Dan
  • 59,490
  • 13
  • 101
  • 110
Igoohd
  • 136
  • 7

1 Answers1

0

Directive hooks receive 4 arguments:

  • el, binding, vnode, and oldVnode

So the first argument to the inserted hook is the HTML element, not the $v object. To bring a component property into the directive, use the directive's vnode argument, getting the component's context through it:

inserted(el, binding, vnode) {
  const $v = vnode.context.$v;
  ...
}

Wherever you want to access the element in the directive, use el.

tony19
  • 125,647
  • 18
  • 229
  • 307
Dan
  • 59,490
  • 13
  • 101
  • 110