mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-05-22 06:31:45 +08:00
feat(Row): gutter support vertical space (#12439)
Co-authored-by: inottn <inottn@outlook.com>
This commit is contained in:
parent
a75a458062
commit
632ff0be31
@ -4,6 +4,7 @@ import {
|
||||
createNamespace,
|
||||
makeNumericProp,
|
||||
makeStringProp,
|
||||
extend,
|
||||
} from '../utils';
|
||||
import { useParent } from '@vant/use';
|
||||
import { ROW_KEY } from '../row/Row';
|
||||
@ -31,15 +32,21 @@ export default defineComponent({
|
||||
return;
|
||||
}
|
||||
|
||||
const { spaces } = parent;
|
||||
|
||||
const { spaces, verticalSpaces } = parent;
|
||||
let styles = {};
|
||||
if (spaces && spaces.value && spaces.value[index.value]) {
|
||||
const { left, right } = spaces.value[index.value];
|
||||
return {
|
||||
styles = {
|
||||
paddingLeft: left ? `${left}px` : null,
|
||||
paddingRight: right ? `${right}px` : null,
|
||||
};
|
||||
}
|
||||
|
||||
const { bottom } = verticalSpaces.value[index.value] || {};
|
||||
|
||||
return extend(styles, {
|
||||
marginBottom: bottom ? `${bottom}px` : null,
|
||||
});
|
||||
});
|
||||
|
||||
return () => {
|
||||
|
@ -53,6 +53,20 @@ Set grid spacing using `gutter` attribute. The default value is 0.
|
||||
</van-row>
|
||||
```
|
||||
|
||||
### Vertical Spacing
|
||||
|
||||
If you want to set the vertical spacing, you can set `[horizontal, vertical]` as an array.
|
||||
|
||||
```html
|
||||
<!-- set the vertical spacing -->
|
||||
<van-row :gutter="[20, 20]">
|
||||
<van-col span="12">span: 12</van-col>
|
||||
<van-col span="12">span: 12</van-col>
|
||||
<van-col span="12">span: 12</van-col>
|
||||
<van-col span="12">span: 12</van-col>
|
||||
</van-row>
|
||||
```
|
||||
|
||||
### Justify Content
|
||||
|
||||
```html
|
||||
@ -87,7 +101,7 @@ Set grid spacing using `gutter` attribute. The default value is 0.
|
||||
|
||||
| Attribute | Description | Type | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| gutter | Grid spacing(px) | _number \| string_ | - |
|
||||
| gutter | Grid spacing(px) | _number \| string \| Array_ | - |
|
||||
| tag | Custom element tag | _string_ | `div` |
|
||||
| justify | Flex main axis, can be set to end/center/space-around/space-between | _string_ | `start` |
|
||||
| align | Flex cross axis, be set to center/bottom | _string_ | `top` |
|
||||
|
@ -52,6 +52,20 @@ Layout 组件提供了 `24列栅格`,通过在 `Col` 上添加 `span` 属性
|
||||
</van-row>
|
||||
```
|
||||
|
||||
### 垂直间距
|
||||
|
||||
如果需要设置垂直间距,可以使用数组形式设置 `[水平间距, 垂直间距]`。
|
||||
|
||||
```html
|
||||
<!-- 设置垂直间距 -->
|
||||
<van-row :gutter="[20, 20]">
|
||||
<van-col span="12">span: 12</van-col>
|
||||
<van-col span="12">span: 12</van-col>
|
||||
<van-col span="12">span: 12</van-col>
|
||||
<van-col span="12">span: 12</van-col>
|
||||
</van-row>
|
||||
```
|
||||
|
||||
### 对齐方式
|
||||
|
||||
通过 `justify` 属性可以设置主轴上内容的对齐方式,等价于 flex 布局中的 `justify-content` 属性。
|
||||
@ -92,7 +106,7 @@ Layout 组件提供了 `24列栅格`,通过在 `Col` 上添加 `span` 属性
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| gutter | 列元素之间的间距(单位为 px) | _number \| string_ | - |
|
||||
| gutter | 列元素之间的间距(单位为 px) | _number \| string \| Array_ | - |
|
||||
| tag | 自定义元素标签 | _string_ | `div` |
|
||||
| justify | 主轴对齐方式,可选值为 `end` `center` <br> `space-around` `space-between` | _string_ | `start` |
|
||||
| align | 交叉轴对齐方式,可选值为 `center` `bottom` | _string_ | `top` |
|
||||
|
@ -7,10 +7,12 @@ const t = useTranslate({
|
||||
'zh-CN': {
|
||||
title2: '在列元素之间增加间距',
|
||||
justify: '对齐方式',
|
||||
vertical: '垂直间距',
|
||||
},
|
||||
'en-US': {
|
||||
title2: 'Column Spacing',
|
||||
justify: 'Justify Content',
|
||||
vertical: 'Vertical Spacing',
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@ -41,6 +43,17 @@ const t = useTranslate({
|
||||
</van-row>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="t('vertical')">
|
||||
<div class="demo-vertical-space">
|
||||
<van-row :gutter="[20, 20]">
|
||||
<van-col span="12">span: 12</van-col>
|
||||
<van-col span="12">span: 12</van-col>
|
||||
<van-col span="12">span: 12</van-col>
|
||||
<van-col span="12">span: 12</van-col>
|
||||
</van-row>
|
||||
</div>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="t('justify')">
|
||||
<van-row justify="center">
|
||||
<van-col span="6">span: 6</van-col>
|
||||
@ -95,4 +108,10 @@ const t = useTranslate({
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.demo-vertical-space {
|
||||
.van-col {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -83,6 +83,42 @@ exports[`should render demo and match snapshot 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<!--[-->
|
||||
<div class="demo-vertical-space">
|
||||
<div class="van-row">
|
||||
<!--[-->
|
||||
<div
|
||||
style
|
||||
class="van-col van-col--12"
|
||||
>
|
||||
<!--[-->
|
||||
span: 12
|
||||
</div>
|
||||
<div
|
||||
style
|
||||
class="van-col van-col--12"
|
||||
>
|
||||
<!--[-->
|
||||
span: 12
|
||||
</div>
|
||||
<div
|
||||
style
|
||||
class="van-col van-col--12"
|
||||
>
|
||||
<!--[-->
|
||||
span: 12
|
||||
</div>
|
||||
<div
|
||||
style
|
||||
class="van-col van-col--12"
|
||||
>
|
||||
<!--[-->
|
||||
span: 12
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<!--[-->
|
||||
<div class="van-row van-row--justify-center">
|
||||
|
@ -49,6 +49,36 @@ exports[`should render demo and match snapshot 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="demo-vertical-space">
|
||||
<div class="van-row">
|
||||
<div
|
||||
class="van-col van-col--12"
|
||||
style="padding-right: 10px; margin-bottom: 20px;"
|
||||
>
|
||||
span: 12
|
||||
</div>
|
||||
<div
|
||||
style="padding-left: 10px; margin-bottom: 20px;"
|
||||
class="van-col van-col--12"
|
||||
>
|
||||
span: 12
|
||||
</div>
|
||||
<div
|
||||
class="van-col van-col--12"
|
||||
style="padding-right: 10px;"
|
||||
>
|
||||
span: 12
|
||||
</div>
|
||||
<div
|
||||
style="padding-left: 10px;"
|
||||
class="van-col van-col--12"
|
||||
>
|
||||
span: 12
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="van-row van-row--justify-center">
|
||||
<div class="van-col van-col--6">
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Col } from '..';
|
||||
import { Row } from '../../row';
|
||||
import { mount } from '../../../test';
|
||||
import { nextTick } from 'vue';
|
||||
|
||||
test('should render Col correctly', () => {
|
||||
const wrapper = mount(Col, {
|
||||
@ -41,3 +42,77 @@ test('should render gutter correctly', () => {
|
||||
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should render vertical space when gutter is an array and provide the second parameter', async () => {
|
||||
const wrapper = mount({
|
||||
render: () => (
|
||||
<Row gutter={[0, 20]}>
|
||||
<Col span="12">12</Col>
|
||||
<Col span="12">12</Col>
|
||||
<Col span="12">12</Col>
|
||||
<Col span="12">12</Col>
|
||||
</Row>
|
||||
),
|
||||
});
|
||||
|
||||
const fields = wrapper.findAll('.van-col');
|
||||
await nextTick();
|
||||
expect(fields[0].style.marginBottom).toEqual('20px');
|
||||
expect(fields[1].style.marginBottom).toEqual('20px');
|
||||
expect(fields[2].style.marginBottom).toBeFalsy();
|
||||
expect(fields[3].style.marginBottom).toBeFalsy();
|
||||
});
|
||||
|
||||
test('should not render vertical space when gutter is an array and provide the second parameter as negative number', async () => {
|
||||
const wrapper = mount({
|
||||
render: () => (
|
||||
<Row gutter={[16, -16]}>
|
||||
<Col span="12">12</Col>
|
||||
<Col span="12">12</Col>
|
||||
<Col span="12">12</Col>
|
||||
<Col span="12">12</Col>
|
||||
</Row>
|
||||
),
|
||||
});
|
||||
|
||||
const fields = wrapper.findAll('.van-col');
|
||||
await nextTick();
|
||||
fields.forEach((field) => {
|
||||
expect(field.style.marginBottom).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
test('should not render space when gutter is an empty array', async () => {
|
||||
const wrapper = mount({
|
||||
render: () => (
|
||||
<Row gutter={[]}>
|
||||
<Col span="12">12</Col>
|
||||
<Col span="12">12</Col>
|
||||
<Col span="12">12</Col>
|
||||
<Col span="12">12</Col>
|
||||
</Row>
|
||||
),
|
||||
});
|
||||
|
||||
const field = wrapper.findAll('.van-col')[0];
|
||||
await nextTick();
|
||||
expect(field.style.paddingRight).toBeFalsy();
|
||||
expect(field.style.marginBottom).toBeFalsy();
|
||||
});
|
||||
|
||||
test('should not render vertical space when gutter is an array and provide the second parameter as invalid number', async () => {
|
||||
const wrapper = mount({
|
||||
render: () => (
|
||||
<Row gutter={[0, 'invalid']}>
|
||||
<Col span="12">12</Col>
|
||||
<Col span="12">12</Col>
|
||||
<Col span="12">12</Col>
|
||||
<Col span="12">12</Col>
|
||||
</Row>
|
||||
),
|
||||
});
|
||||
|
||||
const field = wrapper.findAll('.van-col')[0];
|
||||
await nextTick();
|
||||
expect(field.style.marginBottom).toBeFalsy();
|
||||
});
|
||||
|
@ -6,20 +6,17 @@ import {
|
||||
type InjectionKey,
|
||||
type ExtractPropTypes,
|
||||
} from 'vue';
|
||||
import {
|
||||
truthProp,
|
||||
makeStringProp,
|
||||
makeNumericProp,
|
||||
createNamespace,
|
||||
} from '../utils';
|
||||
import { truthProp, makeStringProp, createNamespace } from '../utils';
|
||||
import { useChildren } from '@vant/use';
|
||||
|
||||
const [name, bem] = createNamespace('row');
|
||||
|
||||
export type RowSpaces = { left?: number; right: number }[];
|
||||
export type VerticalSpaces = { bottom?: number }[];
|
||||
|
||||
export type RowProvide = {
|
||||
spaces: ComputedRef<RowSpaces>;
|
||||
verticalSpaces: ComputedRef<VerticalSpaces>;
|
||||
};
|
||||
|
||||
export const ROW_KEY: InjectionKey<RowProvide> = Symbol(name);
|
||||
@ -37,7 +34,12 @@ export const rowProps = {
|
||||
tag: makeStringProp<keyof HTMLElementTagNameMap>('div'),
|
||||
wrap: truthProp,
|
||||
align: String as PropType<RowAlign>,
|
||||
gutter: makeNumericProp(0),
|
||||
gutter: {
|
||||
type: [String, Number, Array] as PropType<
|
||||
string | number | (string | number)[]
|
||||
>,
|
||||
default: 0,
|
||||
},
|
||||
justify: String as PropType<RowJustify>,
|
||||
};
|
||||
|
||||
@ -70,7 +72,12 @@ export default defineComponent({
|
||||
});
|
||||
|
||||
const spaces = computed(() => {
|
||||
const gutter = Number(props.gutter);
|
||||
let gutter = 0;
|
||||
if (Array.isArray(props.gutter)) {
|
||||
gutter = Number(props.gutter[0]) || 0;
|
||||
} else {
|
||||
gutter = Number(props.gutter);
|
||||
}
|
||||
const spaces: RowSpaces = [];
|
||||
|
||||
if (!gutter) {
|
||||
@ -94,7 +101,25 @@ export default defineComponent({
|
||||
return spaces;
|
||||
});
|
||||
|
||||
linkChildren({ spaces });
|
||||
const verticalSpaces = computed(() => {
|
||||
const { gutter } = props;
|
||||
const spaces: VerticalSpaces = [];
|
||||
if (Array.isArray(gutter) && gutter.length > 1) {
|
||||
const bottom = Number(gutter[1]) || 0;
|
||||
if (bottom <= 0) {
|
||||
return spaces;
|
||||
}
|
||||
groups.value.forEach((group, index) => {
|
||||
if (index === groups.value.length - 1) return;
|
||||
group.forEach(() => {
|
||||
spaces.push({ bottom });
|
||||
});
|
||||
});
|
||||
}
|
||||
return spaces;
|
||||
});
|
||||
|
||||
linkChildren({ spaces, verticalSpaces });
|
||||
|
||||
return () => {
|
||||
const { tag, wrap, align, justify } = props;
|
||||
|
Loading…
x
Reference in New Issue
Block a user