在使用vben框架的时候发现部分的样式不符合实际的需求,ant-design-vue的样式也不支持我们的需求,那怎么办呢,只能自己来修改,下面我就改大家说说我遇到的一些修改过的样式和组件。
一、inputNumber带前后标志
先看下目前支持的样式,底下是ant-design-vue支持的样式,当他输入的时候还需要光标方法%后面。$也会被删掉,所以非常难受。
实际需求的样式是这样的
开发思路:
- 不影响原先的inputNumber组件在封装一个BInputNumber组件
- 增加前后两个slot(插槽)prefix, suffix
- 将原先的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的自定义封装,下次有机会再和大家分享,大家也可以积极留言沟通。