Skip to content

子组件

相对页面组件而言,子组件有三类成员:PropsEmitsSlots。那么在 Zova 中子组件的三类成员如何定义和使用呢?

Props

card子组件为例,定义三个 Props:headercontent、和 footer

初始化代码骨架

TIP

右键菜单 - [模块路径/src/component/card]: Zova Refactor/Add Component Props

定义Props接口

首先,在controller.ts中定义 Props 接口:

typescript
export interface Props {
  header?: string;
  content?: string;
  footer?: string;
}

还可以为 Props 设置缺省值:

typescript
export class ControllerCard {
  static $propsDefault = {
    header: 'default header',
  };
}

访问Props

render.tsx中访问 Props:

typescript
export class RenderCard {
  render() {
    return (
      <div>
        <div>
          <div style={{ backgroundColor: 'teal' }}>
            <div>{`Prop: ${this.$props.header}`}</div>
          </div>
          <div style={{ backgroundColor: 'orange' }}>
            <div>{`Prop: ${this.$props.content}`}</div>
          </div>
          <div style={{ backgroundColor: 'green' }}>
            <div>{`Prop: ${this.$props.footer}`}</div>
          </div>
        </div>
      </div>
    );
  }
}

使用Props

接下来,在父组件中使用子组件:

typescript
import { ZCard } from '../../index.js';

export class RenderComponent {
  render() {
    return (
      <div>
        <ZCard
          header="header"
          content="content"
          footer="footer"
        ></ZCard>
      </div>
    );
  }
}

Emits

接下来,在card子组件中,定义一个 Emit:reset

初始化代码骨架

TIP

右键菜单 - [模块路径/src/component/card]: Zova Refactor/Add Component Emits

定义Emits接口

首先,在controller.ts中定义 Emits 接口:

typescript
export type Emits = {
  (e: 'reset', time: Date): void;
};

触发Emit

render.tsx中触发 Emit:

typescript
export class RenderCard {
  render() {
    return (
      <div>
        <button
          onClick={() => {
            this.$emit('reset', new Date());
          }}
        >
          Reset Time
        </button>
      </div>
    );
  }
}

使用Emits

接下来,在父组件中使用子组件:

typescript
import { ZCard } from '../../index.js';

export class RenderComponent {
  render() {
    return (
      <div>
        <ZCard
          onReset={time => {
            console.log(time);
          }}
        ></ZCard>
      </div>
    );
  }
}

Slots

接下来,在card子组件中,定义三个 Slots:headerdefaultfooter

初始化代码骨架

TIP

右键菜单 - [模块路径/src/component/card]: Zova Refactor/Add Component Slots

定义Slots接口

首先,在controller.ts中定义 Slots 接口:

typescript
export interface Slots {
  header?(): JSX.Element;
  default?(): JSX.Element;
  footer?(): JSX.Element;
}

渲染Slots

render.tsx中渲染 Slots:

typescript
export class RenderCard {
  render() {
    return (
      <div>
        <div>
          <div style={{ backgroundColor: 'teal' }}>
            {this.$slots.header?.()}
          </div>
          <div style={{ backgroundColor: 'orange' }}>
            {this.$slots.default?.()}
          </div>
          <div style={{ backgroundColor: 'green' }}>
            {this.$slots.footer?.()}
          </div>
        </div>
      </div>
    );
  }
}

使用Slots

接下来,在父组件中使用子组件:

typescript
import { ZCard } from '../../index.js';

export class RenderComponent {
  render() {
    return (
      <div>
        <ZCard
          slots={{
            header: () => {
              return <div>this is a header slot from parent</div>;
            },
            default: () => {
              return <div>this is a default slot from parent</div>;
            },
            footer: () => {
              return <div>this is a footer slot from parent</div>;
            },
          }}
        ></ZCard>
      </div>
    );
  }
}

基于 MIT 许可发布