Repository navigation
Description
Problem
With a type-only defineProps<T>() page component in @void/vue, the component's props are fixed by the first request that renders it in a process. If a later request's loader returns a key the first request did not return, that key is not passed as a prop; Vue renders it as an HTML attribute on the root element.
Versions: void@1.7.0, @void/vue@1.7.0.
Reproduction
https://gist.github.com/wintercn/5a21b099a048602b1c4561c703faba25
The loader of /items/:id returns { title: 'A' } for a and { title: 'B', note: 'N' } for b. File layout and commands are in the gist's README.md.
Fresh preview process, request /items/a, /items/b, /items/b:
/items/a <div><h1>A</h1><p>note=</p></div>
/items/b <div note="N"><h1>B</h1><p>note=</p></div>
/items/b <div note="N"><h1>B</h1><p>note=</p></div>
Fresh preview process, request /items/b, /items/a, /items/b:
/items/b <div><h1>B</h1><p>note=N</p></div>
/items/a <div><h1>A</h1><p>note=</p></div>
/items/b <div><h1>B</h1><p>note=N</p></div>
All responses are 200 with no error in the log.
Expected
/items/b renders <div><h1>B</h1><p>note=N</p></div> regardless of request order.
Related
#557 listed "Do not derive a permanent props declaration from the first received props object". #589 fixed only components with a runtime props declaration.
Analysis
@void/vue strips the type argument of defineProps<T>(), so the component has no runtime props. patchProps then sets comp.props = Object.keys(props) from the first page data and marks __voidPatched, so later keys are never declared.
问题
@void/vue 中,页面组件只用类型参数声明 props(defineProps<T>())时,props 由进程里第一个渲染它的请求固定。之后的请求如果 loader 返回了第一次没有的字段,这个字段不会作为 prop 传入,而是被渲染成根元素上的 HTML 属性。
复现
https://gist.github.com/wintercn/5a21b099a048602b1c4561c703faba25
/items/:id 的 loader 对 a 返回 { title: 'A' },对 b 返回 { title: 'B', note: 'N' }。文件布局和命令见 gist 的 README.md。
新预览进程,依次请求 /items/a、/items/b、/items/b:
/items/a <div><h1>A</h1><p>note=</p></div>
/items/b <div note="N"><h1>B</h1><p>note=</p></div>
/items/b <div note="N"><h1>B</h1><p>note=</p></div>
新预览进程,依次请求 /items/b、/items/a、/items/b:
/items/b <div><h1>B</h1><p>note=N</p></div>
/items/a <div><h1>A</h1><p>note=</p></div>
/items/b <div><h1>B</h1><p>note=N</p></div>
所有响应都是 200,日志没有错误。
预期
不论请求顺序,/items/b 都渲染为 <div><h1>B</h1><p>note=N</p></div>。
分析
@void/vue 去掉了 defineProps<T>() 的类型参数,组件没有运行时 props。patchProps 用第一次的页面数据设置 comp.props = Object.keys(props) 并标记 __voidPatched,后来新增的字段不会再被声明。
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Activity
[-][Vue] Type-only defineProps: props are fixed by the first request / 仅类型声明的 defineProps:props 被首个请求固定[/-][+]请求顺序改变了组件的内容[/+][-]请求顺序改变了组件的内容[/-][+]Request order changes the component's content / 请求顺序改变了组件的内容[/+]fix(vue): declare inline typed page props before rendering (#777)