Subscribe on changes!

v-bind on "component" component not passing "is" prop correctly

avatar
Aug 12th 2022

Vue version

3.2.37

Link to minimal reproduction

https://sfc.vuejs.org/#eNqVkt1ugzAMhV/Fyy62SQ1o6x2ilfoekSZ+QklXnCgJrBXi3edAR7t1QtodNj6ffez0bGdM1LWSJSx1hVXGg5O+NVuBqjHaeujBygoGqKxu4IlKnwQKLDQ6D9p4B5tQ8NwrlwhWvwo2vAhM4wlGGAq8bMwx85IigLTQBEaJHjqeKyw3ggWOYFvBpoxgaTxX/S1KlLvoIkXSBRRkWMJ3SLL/w7eHlrwuIx44h1FVv1FLV+v2WEIuQXfSWlVKhPx8oQPnV82uKLQtFe7Ba6i9Ny6J427NG7W3mVcaw3EOLtJ2H+dWZh9Uyos6w7108cSLat8cH9/X/MTdGX12mhtcfV1Hu1/UuD86epigVFUlbVDM2tWym5+bSOP51mzFphfEm8xEB6eR3lgf5qKW4w/qm8CYCTnyGWIa87IFVxU35ukrsi161chIuobnVn86aQks2OqGEVOSpuRkoiQndon5q/SOG7CDwIENX+icF7I=

Steps to reproduce

  1. Create an object containing the key "is" with the value of the name of another component (ex. {is:"h1"})
  2. In the template, add a component tag with v-bind set to the previously created object (ex. <component v-bind="opts">this should render as an "h1"</component>)

What is expected?

The component tag should render as the tag defined in the object passed through v-bind

What is actually happening?

The component tag still renders as a component tag, though other properties passed through v-bind are applied correctly

System Info

npx: installed 1 in 1.386s

  System:
    OS: Linux 5.10 Ubuntu 20.04.4 LTS (Focal Fossa)
    CPU: (8) x64 Intel(R) Core(TM) i7-8665U CPU @ 1.90GHz
    Memory: 170.50 MB / 5.79 GB
    Container: Yes
    Shell: 5.0.17 - /bin/bash
  Binaries:
    Node: 14.19.3 - ~/.nvm/versions/node/v14.19.3/bin/node
    Yarn: 1.22.18 - ~/.nvm/versions/node/v14.19.3/bin/yarn
    npm: 6.14.17 - ~/.nvm/versions/node/v14.19.3/bin/npm
  npmPackages:
    vue: ^3.0.0 => 3.2.37

Any additional comments?

As seen in the minimal reproduction link, if the "is" property is applied using :is or v-bind:is, the tag is replaced correctly. Also notably, if both a v-bind:is and v-bind object with the "is" key is provided, the v-bind:is property is always used, rather than being overwritten if provided first (according to https://v3-migration.vuejs.org/breaking-changes/v-bind.html#_3-x-syntax)

avatar
Aug 16th 2022
  <component v-bind:is="opts.is">just "v-bind:is"</component>
  <component is="h2" v-bind="opts">"is" set to different component, should be overriden by v-bind</component>

The first component tag is parsed as _createBlock(_resolveDynamicComponent($setup.opts.is). The second component tag is parsed as _createBlock(_resolveDynamicComponent("h2"). When opts.is changed, the second component tag is still _createBlock(_resolveDynamicComponent("h2"). So that's why opts.is doesn't work.

image