主题
Spread 合并
完整 VNodeData spread
jsx
const data = {
class: ['card'],
attrs: { title: 'title' },
on: { click: handleClick }
}
return <article {...data} />多个数据段通过虚拟 runtime 按 Vue 2 规则合并:
attrs、props、domProps浅合并on、nativeOn的同名 handler 合并为数组hook的同名 hook 合并为顺序调用函数class、style保留组合顺序directives按出现顺序合并并展平为单层数组- 其他根属性以后出现者为准
推荐:分组也放入显式 VNodeData
jsx
const buttonData = {
attrs: {
'aria-label': 'save'
},
on: {
click: save
}
}
return <button {...buttonData}>保存</button>插件也兼容官方 Babel preset 的 attrs={attrs}、on={listeners} 分组属性,但 Demo 优先使用完整 data object,避免把业务属性和 VNodeData 分组写法混在一起。
Children spread
vue
<script lang="jsx">
export default {
name: 'SpreadDemo',
directives: {
mark: {
bind(element, binding) {
element.dataset.mark = String(binding.value)
}
}
},
data() {
return { count: 0 }
},
render() {
const vnodeData = {
class: ['spread-card'],
attrs: { title: '完整 VNodeData spread', 'data-spread': 'root' },
on: { dblclick: () => { this.count += 2 } }
}
const buttonData = {
attrs: {
'data-group': 'attrs spread',
'aria-label': 'spread demo'
},
on: {
click: () => { this.count += 1 }
}
}
const firstDirectives = [
{ name: 'mark', value: 'first' }
]
const secondDirectives = [
{ name: 'mark', value: 'second', modifiers: { merged: true } }
]
const nodes = [
<span class="badge" key="a">spread child A</span>,
<span class="badge" key="b">spread child B</span>
]
return (
<article {...vnodeData} class="demo-card">
<span class="case-label">spread merge</span>
<h3>完整 VNodeData、directives 与 children spread</h3>
<p>多个 directives 数组会按出现顺序合并为同一个扁平数组。</p>
<button {...buttonData} class="button">click + 1 / dblclick + 2</button>
<div
{...{ directives: firstDirectives }}
{...{ directives: secondDirectives }}
class="result-line"
>
directives spread 合并结果:data-mark=second
</div>
<div class="badge-row">{...nodes}</div>
<p>count:{this.count}</p>
</article>
)
}
}
</script>directives spread
jsx
const directives = [
{ name: 'my-dir', value: 123, modifiers: { abc: true } }
]
return <div {...{ directives }} />也可以和其他指令数据及 JSX 指令混用:
jsx
return (
<div
{...{ directives: first }}
{...{ directives: second }}
vShow={visible}
/>
)最终 VNodeData.directives 始终是扁平数组,不会生成 [[directiveA], [directiveB]]。