# 常见问题

# 如何添加事件?

x-component-props 中可以用 @ 来标识事件,同时也支持 onXxx 这种方式来标识事件。两者区别在于使用 @ 标识的内容不会再作为 prop 传入组件,而 onXxx 这种会。这是为了兼容某些组件具有 onXxx 的 prop,如 ElementUI 中的 upload 组件 (opens new window)

WARNING

事件名冲突时,@ 的优先级更高。例如同时设置了 @changeonChange,只有 @change 会生效。

# 如何使用插槽?

使用 x-content 可以在组件的 default 插槽中插入内容。可以传入文本或组件。

# 如何使用具名插槽?

x-content 中以键名来表示插槽名。

WARNING

注意键名不可包含 templaterendersetup 三个关键字,否则整个 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>
Last Updated: 9/23/2021, 7:22:09 AM