基于Ant Design Vue封装一个属于自己的modal框

6,355 阅读1分钟

这是我参与新手入门的第一篇文章

前言

前两天leader说要统一所有页面modal的宽度,并且只能点击关闭按钮才能关闭(组件默认点击蒙层是可以关闭)。当时,我在想不可能一个一个去改吧,这不把人累死,刚好最近在学C#的WinForm窗体,人家窗体有继承,可以统一属性。那我们前端直接封装一个组件,不就可以统一属性了嘛~~~

提前声明:

本篇文章用的是Vue Ui库:Ant Design of Vue,没有安装的同学请提前安装哦,安装教程请查看官网。

定义Prop

首先我们会想到定义需要的Prop,一共四个参数。

1.Modal.props

先把Modal引进来,再使用拓展运算符放入props

<script>
    import {Modal} from 'ant-design-vue'

    export default {
      name: 'MyModal',
      props: {
        ...Modal.props
      }
    }
</script>

2.maskClosable

设置一个点击蒙层是否允许关闭的属性

    props: {
        maskClosable: {
          type: Boolean,
          default: false
        }
    }

3.size

设置modal框的固定大小

    props: {
        // 大小设置 mini / small / medium
        size: {
          type: String,
          default: ''
        }
    }

4.width

设置自由宽度

props: {
    // 宽度 520 / 650 / 750 / 900
    width: {
      type: Number,
      default: 520
    }
}

完善固定宽度的设置

编写一个对应宽度的方法setWidth()

然后我们就可以用setWidth()方法通过常量sizeObj,遍历输出固定的宽度。

<script>
    import {Modal} from 'ant-design-vue'

    const sizeObj = { 'mini': 650, 'small': 750, 'medium': 900 }

    export default {
      name: 'MyModal',
      props: {
        ...Modal.props,
        // 点击蒙层是否允许关闭
        maskClosable: {
          type: Boolean,
          default: false
        },
        // 大小设置 mini / small / medium
        size: {
          type: String,
          default: ''
        },
        // 宽度 520 / 650 / 750 / 900
        width: {
          type: Number,
          default: 520
        }
      },
      data() {
        return {
          customizeWidth: this.width
        }
      },
      mounted () {
        this.setWidth()
      },
      methods: {
        // 设置宽度
        setWidth() {
          Object.keys(sizeObj).forEach(key => {
            if (key === this.size) this.customizeWidth = sizeObj[key]
          })
        }
      }
    }
</script>

完善模板的属性

最后我们来完善一下模板的属性。

这里我们值得注意的是$props$listeners这两个属性。

#vm.$props

当前组件接收到的 props 对象。Vue 实例代理了对其 props 对象 property 的访问。

#vm.$listeners

包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。

以上两个属性是官网的介绍,我觉得理解起来不是很直观。我的理解是这样的,$props是继承了当前Modal的属性,而$listeners就是Modal组件的emit传递。

<template>
  <a-modal v-bind="$props" v-on="$listeners" :maskClosable="maskClosable" :width="customizeWidth">
    <slot></slot>
  </a-modal>
</template>

结束语

以下是本篇文章的全部代码,我觉得本篇文章值得注意的是$props$listeners这两个属性,如果想深入理解的同学,可以直接打印这两属性,有兴趣的同学可以粘到自己的项目里试试看。最后如果我哪里有写的不对的地方请大家多多指正,谢谢大家!

<template>
  <a-modal v-bind="$props" v-on="$listeners" :maskClosable="maskClosable" :width="customizeWidth">
    <slot></slot>
  </a-modal>
</template>

<script>
import {Modal} from 'ant-design-vue'

const sizeObj = { 'mini': 650, 'small': 750, 'medium': 900 }

export default {
  name: 'MyModal',
  props: {
    ...Modal.props,
    // 点击蒙层是否允许关闭
    maskClosable: {
      type: Boolean,
      default: false
    },
    // 大小设置 mini / small / medium
    size: {
      type: String,
      default: ''
    },
    // 宽度 520 / 650 / 750 / 900
    width: {
      type: Number,
      default: 520
    }
  },
  data() {
    return {
      customizeWidth: this.width
    }
  },
  mounted () {
    this.setWidth()
  },
  methods: {
    // 设置宽度
    setWidth() {
      Object.keys(sizeObj).forEach(key => {
        if (key === this.size) this.customizeWidth = sizeObj[key]
      })
    }
  }
}
</script>