vuejs/rfcs

Add impassive event modifier !passive

wangf1978 opened this issue · 2 comments

What problem does this feature solve?

In modern browsers, for some events, for example, wheel, touchstart and so on, if you want to add event listener to it, passive option with true or false need to be specified explicitly, otherwise browser will report some warnings like as:
image
In some scenario, this default behavior has to be prevented like as using the below code

    <div v-if="img.focused == true && img.selected == false" class="photo_selection" 
            v-on:click="on_toggle_photo_checkbox(img, true, $event, imgTypePos + start_list_idx_in_vw)"
            v-on:touchstart.prevent="on_toggle_photo_checkbox(img, true, $event, imgTypePos + start_list_idx_in_vw)">

but there is no way to specify passive: false to vue runtime-dom
https://github.com/vuejs/core/tree/main/packages/runtime-dom/src/modules)/events.ts
image
tons of warnings will be reported by the latest chrome and edge console

What does the proposed API look like?

https://github.com/vuejs/core/tree/main/packages/runtime-dom/src/modules)/events.ts

@[touchstart|wheel....].prevent.!passive
v-on:[touchstart|wheel....].prevent.!passive
const optionsModifierRE = /(?:Once|Passive|!Passive|Capture)$/

function parseName(name: string): [string, EventListenerOptions | undefined] {
  let options: EventListenerOptions | undefined
  if (optionsModifierRE.test(name)) {
    options = {}
    let m
    while ((m = name.match(optionsModifierRE))) {
      name = name.slice(0, name.length - m[0].length)
      if (m[0][0] === '!')
         ;(options as any)[m[0].slice(1).toLowerCase()] = false
      else
        ;(options as any)[m[0].toLowerCase()] = true
    }
  }
  const event = name[2] === ':' ? name.slice(3) : hyphenate(name.slice(2))
  return [event, options]
}

If you're referring to https://chromestatus.com/feature/5093566007214080 it sounds like it only applies when touchstart is added to the document, not when its added to a div. I've been trying to come up with a reproduction with a vue div that will trigger that warning, but haven't been able to. Do you have a reproduction e.g. sfc.vuejs.org ? Here's what I tried:

https://sfc.vuejs.org/#eNptks9OAyEQxl9lQkzUaFmjt7X1z8HEB/DIQUqnuygLBGZrms2+uwO17cVNljB8A/xmPibxGqPcjShascwm2UiQkcb4pDyAHWJIBFPC7QzbFAa45NTLIpXfIYELHayAE66UUOL6KG1Hb8gGX/S3HXq6wjJew1RU3ho6udNuRLhZwWfVWriY6kTSPuIMNoPR3qDTa4fPJ/G8NivlP8txs/LL5gDP2BwQDtFpwlrEcmN38GKcNd8rJY48TFtB+HuhMJo+k04kY6q3/J+Yae+QpbU2310Ko9+0YPbaP0KPtuu5ggccHuHHbqhv4f6uBGPGtMjo0LDsg0clKhXAOyYsRWpgQAkfaQ9nEODWDSgrf8N63VN5clsXGfRpmhhynpdNCUoPTnWLW3HwbjHoKL9y8Oxvbb36E7IS7dEMJdjVEivRE8XcNk3emvIqvrIMqWt4JtPoyTIS5mGxTuGH6+KDD91hA2Yx/wLqBsgX

When I add touchstart to the document, .cancelable is false (meaning it's passive). But touchstart on the div has .cancelable true (meaning it's active)

I can reproduce the warning with the above playground link:
image