vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
46.37k stars 8.14k forks source link

v-pre stripping attributes starting with "on-" #8417

Open schrags08 opened 1 year ago

schrags08 commented 1 year ago

Vue version

3

Link to minimal reproduction

https://play.vuejs.org/#eNo9TdEKwjAM/JWjL1Nw7n0Wwf/YS3FRB11X2qwIpf9uZtkgcHdJ7i6rh/fXtJLqlY7PMHm+D46+fgmMkV5mtYw8OGA0bE7nyoFAvAa3K2CO7x7Nh6xdmktdltuGZXAyujuyRTDN3homUYAepwSmyFhc+8cptjtNrQ/1Dch5a0GROHF1YpOD7o4wVX53QESZ

Steps to reproduce

Visit the SFC Playground link and view the Elements panel with the developer tools. Inspect the rendered output.

I'm using the v-pre directive on an element with attributes, for example:

<div test on-test is-on-test v-pre>{{ msg }}</div>

What is expected?

I'd expect the rendered output to be:

<div test on-test is-on-test>{{ msg }}</div>

What is actually happening?

The rendered output is:

<div test is-on-test>{{ msg }}</div>

Note the absence of the on-test attribute.

System Info

No response

Any additional comments?

This also affects child elements of the element using v-pre.

I asked about this in the #vue-3-advanced discord channel on 5/25/2023 and they thought this was a bug as well.

skirtles-code commented 4 months ago

There are various other cases that need to be considered too. For example, how should this be rendered?

<input
  v-pre
  indeterminate
  type="checkbox"
  :a="b"
  ^c="d"
  .e="f"
>

Currently, it'll render as:

<input type="checkbox" :a="b" c="d">

The type and :a attributes are rendered correctly. The ^c has the ^ stripped off. The other attributes are being set as properties.

I would assume that all attributes in the template are expected to be rendered as-is, even the indeterminate.

Ideally, I think any solution should be purely within the compiler, without needing explicit support at runtime.

I can think of two approaches that might gives us what we want:

  1. Prefix the VNode prop names with ^ in the compiler, so they all get set as attributes.
  2. Use createStaticVNode to create the node.

The first approach is probably easier to implement.