十一、Vben框架部分组件样式的重新封装

在使用vben框架的时候发现部分的样式不符合实际的需求,ant-design-vue的样式也不支持我们的需求,那怎么办呢,只能自己来修改,下面我就改大家说说我遇到的一些修改过的样式和组件。

一、inputNumber带前后标志

先看下目前支持的样式,底下是ant-design-vue支持的样式,当他输入的时候还需要光标方法%后面。$也会被删掉,所以非常难受。

实际需求的样式是这样的

 

开发思路:

  1. 不影响原先的inputNumber组件在封装一个BInputNumber组件
  2. 增加前后两个slot(插槽)prefix, suffix
  3. 将原先的change事件reture出去,方便外部调用

下面直接上代码:

Html部分

<template>
  <div class="b-input-number">
    <InputNumber :style="{'padding-left': prefix.length * 16 + 'px'}"
                 v-bind="getBindValue" @change="handleChange"/>
    <slot name="prefix">
      <span class="number-prefix">{
   
   { prefix }}</span>
    </slot>
    <slot name="suffix">
      <span class="number-suffix">{
   
   { suffix }}</span>
    </slot>
  </div>
</template>

 js部分,change方法采用源码的代码

<script lang="ts">
  import { computed, defineComponent } from 'vue';
  import { InputNumber } from 'ant-design-vue';

  export default defineComponent({
    name: "BInputNumber",
    components: {InputNumber},
    props: {
      prefix: {
        type: String,
        default: ''
      },
      suffix: String,
    },
    emits: ['change', 'update:value'],
    setup(props, {emit, attrs}) {
      const getBindValue = computed((): Recordable => {
        return {
          ...attrs,
          ...props,
        };
      });

      function handleChange() {
        let _len = arguments.length;
        let args = new Array(_len);
        let _key = 0;
        for (; _key < _len; _key++) {
          args[_key] = arguments[_key];
        }

        emit('update:value', args[0]);
        emit('change', ...args);
      }

      return {
        getBindValue,
        handleChange,
      }
    }
  })
</script>

css代码,使其定位到前后两边

<style lang="less">
  .b-input-number {
    display: inline-flex;
    position: relative;
    .ant-input-number-handler-wrap{
      z-index: 1
    }
    .number-prefix {
      position: absolute;
      left: 8px;
      top: 5px;
    }
    .number-suffix {
      position: absolute;
      right: 8px;
      top: 5px;
    }
  }
  .b-input-number[size="small"] {
    .number-prefix {
      top: 2px;
    }
    .number-suffix {
      top: 2px;
    }
  }
</style>

在父组件如何使用呢,如下图

二、select组件增加label返回

我们知道在ant-design-vue中select的v-model只能绑定value属性,想获取label还需要写change方法,然后再在其中取值赋值给变量。

那么能不能在有一个属性绑定label,让它也能双向绑定,那么就要改他的源码了。

开发思路:

1、不影响原先的select组件在封装一个BSelect

2、在emits返回时增加一个update:label的参数

3、在change事件中修改label的值,并考虑多选的情况。

下面直接上代码

<template>
  <Select v-bind="getBindValue" @change="handleChange">
    <template #default>
      <slot name="default"></slot>
    </template>
  </Select>
</template>
<script lang="ts">
  import { computed, defineComponent } from 'vue';
  import { Select } from 'ant-design-vue';

  export default defineComponent({
    name: "BSelect",
    components: {Select},
    emits: ['change', 'update:value', 'update:label'],
    setup(props, {emit, attrs}) {
      const getBindValue = computed((): Recordable => {
        return {
          ...attrs,
          ...props,
        };
      });

      function handleChange() {
        let _len = arguments.length;
        let args = new Array(_len);
        let _key = 0;
        for (; _key < _len; _key++) {
          args[_key] = arguments[_key];
        }

        emit('update:value', args[0]);
        if (getBindValue.value.mode === 'multiple') {
          emit('update:label', args[1].map(item => item.title || item.children[0].children));
        } else {
          emit('update:label', args[1] ? (args[1].title || args[1].children[0].children) : '');
        }

        emit('change', ...args);

      }

      return {
        getBindValue,
        handleChange
      }
    }
  })
</script>

 在父组件如何使用呢,如下图

好了,组件封装还有很多,像是table的拖拽功能,upload的自定义封装,下次有机会再和大家分享,大家也可以积极留言沟通。 

猜你喜欢

转载自blog.csdn.net/qq_43185384/article/details/129283446
今日推荐