vue jsx模板封装ant-design-vue2+版本Modal组件

最近在项目中二次封装了Modal弹窗,目的是为了项目中的弹窗统一,样式修改方便,多人开发的时候不会出现各种不同的代码,封装的时候也踩了坑,下面总结一下封装经验:

//JSX代码

import { defineComponent, Fragment } from "vue"
import { Spin, Modal } from 'ant-design-vue'
export default defineComponent({
  name: 'btModal',
  props:{
    visible: {
      type: Boolean,
      default: false,
    },
    title: {
      type: String,
      default: ''
    },
    width: {
      type: Number
    },
    //是否展示关闭按钮
    closable: {
      type: Boolean,
      default: false
    },
    // 点击遮罩是否可关闭
    maskClosable: {
      type: Boolean,
      default: false
    },
    // 不展示 footer
    footer: {
      type: String,
      default: null
    },
    bodyStyle: Object, // Modal body 样式
    // 关闭时是否销毁 Modal 里的子元素
    destroyOnClose: {
      type: Boolean,
      default: true
    },
    // 是否支持键盘 esc 关闭
    keyboard: {
      type: Boolean,
      default: false
    },
    // 遮罩 modal 的loading 样式
    loading: {
      type: Boolean,
      default: false
    }, 
  },
  setup(props, { slots, attrs }) {
    const modalSlots = Object.keys(slots).map(slot => {
      return (
        <Fragment v-slots={slot}>
          {slots[slot]()}
        </Fragment>
      )
    })
    const btModal = () => {
      const {loading} = props;
      return (
        <Spin
          spinning={loading}
        >
          <Modal {...attrs} {...props}>
            {modalSlots}
          </Modal>
        </Spin>
      )
    }
    return () => (
      <div style="position: relative">
        {btModal()}
      </div>
    )
  }
})

其中需要注意的是:

1、循环渲染slot方法:modalSlots中,必须调用一下 {slots[slot]()},因为是个函数,不调用,页面不会呈现slot内容。

2、在父组件中,我用的vue2.6中的写法,具名插槽用 # 为前缀命名,这里需要注意,如果是默认插槽,也需要给个标注,如果不给标注,那么有名字的插槽会被优先渲染出来,没有名字的插槽会最后渲染,这样就不符合你需要的页面样式,所以默认的插槽需要用 #default 来标注一下。具名插槽就正常起名字就好,比如 #footer。

有默认名字的插槽代码:

  <ModalInfo :visible="state.modalVisible" :title="'modal弹窗title'">
    <template #default><span>这是标注了default的插槽内容.</span></template>
    <template #footer>
      <div class="modal-footer">
        <Button @click="closeFunc">Return</Button>
        <Button type="primary" @click="closeFunc">Submit</Button>
      </div>
    </template>
  </ModalInfo>

结果: 

 

再看没有默认标注的插槽代码:

<ModalInfo :visible="state.modalVisible" :title="'modal弹窗title'">
    <span>这是没有任何标注的内容</span>
    <template #footer>
      <Button>Return</Button>
      <Button type="primary">Submit</Button>
    </template>
  </ModalInfo>

 再看结果:文字被渲染到了按钮的下方:

 总结:

如果是默认插槽,必须给标注,如果不给标注,那么有名字的插槽会被优先渲染出来,没有名字的话会最后渲染。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

maxenjoycode

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值