1

Using Vue.js and I am trying to add a conditional event handler to the keydown event on an <input>. I want to avoid adding the click handler at all if the condition is not met. I followed Evan You's suggestion: https://github.com/vuejs/vue/issues/7349#issuecomment-354937350

I'm getting an error saying Cannot read property '_wrapper' of null for the following:

<input v-on: {
  keydown: fieldData.fixedLength ? inputEnforceMaxlength : null,
}>

I also tried passing an empty object but got a different error saying: handler.apply is not a function for the following:

<input v-on: {
  keydown: fieldData.fixedLength ? inputEnforceMaxlength : {},
}>

Is this the proper way to add conditional event handlers or are there are other alternatives? Thanks!

6
  • 1
    why not just use an if else check inside the function ? Commented Mar 15, 2019 at 11:41
  • @DhananjaiPai I'm trying to avoid binding the click handler at all if that condition--fieldData.fixedLength-- is not met Commented Mar 15, 2019 at 11:43
  • I was just wondering why bother the entire overloaded logic ? You are effectively trying to bind,unbind and rebind every-time the fieldData length changes? Commented Mar 15, 2019 at 11:45
  • Not really. I'm just checking if fieldData.length is an available property. That property is hardcoded. If it is available, my aim is to add the event handler to the input Commented Mar 15, 2019 at 11:47
  • 1
    That doesn't avoid binding a handler at all. It just conditonally calls a function on keypress or tries to call null or {} as a function which is why you get the error. Commented Mar 15, 2019 at 11:49

2 Answers 2

4

You should be able to do something like this...

<input v-on="fieldData.fixedLength ? { keydown: inputEnforceMaxlength } : null">

Or you can just use a render() function instead of a <template>

Using a render function...

render(h) {
    const data = {
        on: {
            blur: this.validate,
            focus: this.showLabel,
        },
    };

    if (this.fieldData.fixedLength) {
        data.on.keydown = this.inputEnforceMaxlength;
    }

    if (this.fieldName === 'Phone') {
        data.on.keypress = this.inputMaskTel;
    }

    return h('input', data);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Nice. What would that syntax look like if I had other event handlers for the same element? Right now I have set up as v-on="{ blur: validate, focus: showLabel, keydown: fieldData.fixedLength ? inputEnforceMaxlength : {}, keypress: fieldName === 'Phone' ? inputMaskTel : {} }"
In that case i would just use a render function.
0

If you need to use some events, that must go to the parent component, you can write smth like this:

<template>
  <input v-on="customEvents" />
</template>
<script>
  export default {
    computed: {
      customEvents: () => {
        return [
          ...this.$listeners,
          this.fieldData.fixedLength && { keydown: this.inputEnforceMaxlength }
        ];
      }
    }
  }
</script>

1 Comment

This just extracts what they're trying to do into a child component, can you add how this would answer the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.