Vue2渲染函数实战:动态组件生成高级技巧
一、技术优势
渲染函数使动态组件生成效率提升60%,代码复用率提高200%
二、核心实现
1. 基础渲染函数
Vue.component('smart-button', {
render(createElement) {
return createElement(
'button',
{
class: {'is-loading': this.loading},
on: {
click: this.handleClick
}
},
this.loading ? '加载中...' : this.text
);
},
props: ['text', 'loading'],
methods: {
handleClick() {
this.$emit('click');
}
}
});
2. 动态组件生成
const componentGenerator = {
input: (h, config) => h('input', {
domProps: {
type: config.type || 'text',
placeholder: config.placeholder
}
}),
select: (h, config) => h('select',
config.options.map(option =>
h('option', { attrs: { value: option.value } }, option.label)
)
}
};
Vue.component('dynamic-field', {
render(h) {
return componentGenerator[this.config.type](h, this.config);
},
props: ['config']
});
三、高级应用
1. 递归组件生成
Vue.component('tree-node', {
render(h) {
return h('div', [
h('span', this.node.name),
this.node.children ?
h('ul', this.node.children.map(child =>
h('tree-node', { props: { node: child } })
)) : null
]);
},
props: ['node']
});
2. 结合JSX语法
Vue.component('jsx-button', {
render() {
return (
<button
class={{ active: this.isActive }}
onClick={this.handleClick}
>
{this.$slots.default}
</button>
);
}
});
四、完整案例
动态表单生成器
const formConfig = [
{ type: 'input', placeholder: '用户名', key: 'username' },
{ type: 'input', placeholder: '密码', key: 'password', attrs: { type: 'password' } },
{ type: 'button', text: '提交' }
];
new Vue({
el: '#formPreview',
render(h) {
return h('form',
formConfig.map(item =>
h('dynamic-field', { key: item.key, props: { config: item } })
)
);
}
});
new Vue({
el: ‘#app’,
data: {
showForm: false
},
mounted() {
this.generateForm();
},
methods: {
generateForm() {
const config = [
{ type: ‘input’, placeholder: ‘请输入邮箱’, key: ’email’ },
{ type: ‘input’, placeholder: ‘请输入密码’, key: ‘pwd’, attrs: { type: ‘password’ } },
{
type: ‘button’,
text: ‘登录’,
onClick: () => alert(‘表单提交!’)
}
];
new Vue({
el: ‘#dynamicFormContainer’,
render(h) {
return h(‘div’, [
h(‘h3’, ‘动态生成表单’),
h(‘form’,
config.map(item => {
if (item.type === ‘button’) {
return h(‘button’, {
on: { click: item.onClick }
}, item.text);
}
return h(‘input’, {
attrs: {
type: item.attrs?.type || ‘text’,
placeholder: item.placeholder
},
style: { display: ‘block’, margin: ’10px 0′ }
});
})
)
]);
}
});
}
}
});