Skip to content

Leave Vue's reserved attributes out of the split, and select a select's options - #11

Merged
dannote merged 2 commits into
mainfrom
split-vue-attributes
Oct 8, 2026
Merged

dannote merged 2 commits into
mainfrom
split-vue-attributes

Conversation

@dannote

@dannote dannote commented Oct 8, 2026

Copy link
Copy Markdown
Member

Found through PhoenixVapor, comparing its server render with Vue's own server renderer (@vue/server-renderer) on the same templates.

Reserved attributes

split_template/2 printed a static ref or key as an attribute (<input ref="search">), and passed ref and key to components and root attributes as props. Vue reserves both and never renders them. A bound :key was already left out; now ref and key are, static or bound, in attributes/4 and props/3.

<select v-model>

A select's v-model produced a warning and no slot, so a renderer couldn't mark the selected option. Vue's server renderer outputs <option value="b" selected>. Now each <option> inside a <select v-model>, in an <optgroup> or a v-for too, has a :model slot in its start tag, tag: "option", carrying:

  • the select's model expression as :value;
  • the option's own value, in this order:
    • its bound :value, as the slot's new :option_value field (an addition to encoded_model_slot, regenerated with RustQ);
    • its value attribute;
    • its text, as Vue values an option without one.

An option outside a <select v-model> has no slot.

PhoenixVapor's side renders selected on a match (Vue's looseEqual, membership for multiple), checked against this branch: the output now matches Vue's for ref, ref_for, ref_key, key and the select.

Checks

mix lint (rustq.gen --check, format, credo, ex_dna, reach, dialyzer, cargo fmt, clippy -D warnings) clean; mix test: 137 passed (11 doctests), with new tests for both. PhoenixVapor's suite on this branch: 381 passed.

…'s options

split_template/2 rendered a static ref or key as an attribute, and
passed ref and key to components as props; Vue reserves both and never
renders them. It also rendered no selected option for a <select v-model>,
with a warning. Each <option> inside one now has a :model slot in its
start tag with the select's value and the option's own: its bound
:value (the slot's new :option_value), its value attribute, or its text,
so a renderer can select it as Vue's server renderer does.
@dannote
dannote merged commit 2e4df9a into main Oct 8, 2026
2 checks passed
@dannote
dannote deleted the split-vue-attributes branch October 8, 2026 22:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant