# 常见问题
# 如何添加事件?
x-component-props
中可以用 @
来标识事件,同时也支持 onXxx
这种方式来标识事件。两者区别在于使用 @
标识的内容不会再作为 prop 传入组件,而 onXxx
这种会。这是为了兼容某些组件具有 onXxx
的 prop,如 ElementUI 中的 upload 组件 (opens new window)。
WARNING
事件名冲突时,@
的优先级更高。例如同时设置了 @change
和 onChange
,只有 @change
会生效。
# 如何使用插槽?
使用 x-content
可以在组件的 default
插槽中插入内容。可以传入文本或组件。
# 如何使用具名插槽?
x-content
中以键名来表示插槽名。
WARNING
注意键名不可包含 template
、render
、setup
三个关键字,否则整个 x-content
会被当做 vue 组件进行渲染。
# 如何使用作用域插槽?
x-content
使用函数式组件时, 渲染函数增加第二个参数,通过其 props
成员访问作用域插槽传入属性,支持 observer() 和 connect() 接入组件。
有 default 作用域插槽组件的插槽属性值
<template>
<FormProvider :form="form">
<SchemaField :schema="schema" />
</FormProvider>
</template>
<script>
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/vue'
import { observer } from '@formily/reactive-vue'
// 带有作用域插槽的普通组件
const TextPreviewer = {
functional: true,
name: 'TextPreviewer',
render(h, context) {
return h('div', {}, [
context.scopedSlots.default({
slotProp: '有 default 作用域插槽组件的插槽属性值',
onScopedFunc: ($event) => {
alert($event)
},
}),
])
},
}
// 响应式组件
const ObservedComponent = observer({
functional: true,
components: {
TextPreviewer,
},
render(h, context) {
return h(TextPreviewer, {
scopedSlots: {
default: (props) => context.scopedSlots.default(props),
},
})
},
})
// 作用域插槽组件
const ScopedSlotComponent = {
functional: true,
render(h, { props }) {
return h(
'div',
{
on: {
click: () => {
props.onScopedFunc('作用域插槽传递事件函数,事件发生后进行值的回传')
},
},
},
[props.slotProp]
)
},
}
const { SchemaField } = createSchemaField({
components: {
ObservedComponent,
},
})
const schema = {
type: 'object',
properties: {
textPreview: {
type: 'string',
'x-component': 'ObservedComponent',
'x-content': {
default: ScopedSlotComponent,
},
},
},
}
export default {
components: { FormProvider, SchemaField },
data() {
return {
form: createForm(),
schema,
}
},
}
</script>