[new feature] add grid component (#3669)

This commit is contained in:
neverland
2019-06-28 11:16:42 +08:00
committed by GitHub
parent 1850230102
commit 9737a8b9d0
36 changed files with 907 additions and 51 deletions
+97
View File
@@ -0,0 +1,97 @@
import { createNamespace, suffixPx } from '../utils';
import { ChildrenMixin } from '../mixins/relation';
import { route, routeProps } from '../utils/router';
import Icon from '../icon';
const [createComponent, bem] = createNamespace('grid-item');
export default createComponent({
mixins: [ChildrenMixin('vanGrid')],
props: {
...routeProps,
icon: String,
text: String
},
computed: {
style() {
const { square, gutter, columnNum } = this.parent;
const percent = `${100 / columnNum}%`;
const style = {
flexBasis: percent
};
if (square) {
style.paddingTop = percent;
} else if (gutter) {
const gutterValue = suffixPx(gutter);
style.paddingRight = gutterValue;
if (this.index >= columnNum) {
style.marginTop = gutterValue;
}
}
return style;
},
contentStyle() {
const { square, gutter } = this.parent;
if (square && gutter) {
const gutterValue = suffixPx(gutter);
return {
right: gutterValue,
bottom: gutterValue,
height: 'auto'
};
}
}
},
methods: {
onClick(event) {
this.$emit('click', event);
route(this.$router, this);
},
renderContent() {
const slot = this.slots();
if (slot) {
return slot;
}
return [
this.slots('icon') || (this.icon && <Icon name={this.icon} class={bem('icon')} />),
this.slots('text') || (this.text && <span class={bem('text')}>{this.text}</span>)
];
}
},
render(h) {
const { center, border, square, gutter, clickable } = this.parent;
return (
<div class={[bem({ square })]} style={this.style} onClick={this.onClick}>
<div
style={this.contentStyle}
class={[
bem('content', {
center,
square,
clickable,
surround: border && gutter
}),
{ 'van-hairline': border }
]}
>
{this.renderContent()}
</div>
</div>
);
}
});
+59
View File
@@ -0,0 +1,59 @@
@import '../style/var';
.van-grid-item {
position: relative;
box-sizing: border-box;
&--square {
height: 0;
}
&__content {
display: flex;
flex-direction: column;
box-sizing: border-box;
height: 100%;
padding: 15px 10px;
background-color: #fff;
&::after {
z-index: 1;
border-width: 0 1px 1px 0;
}
&--square {
position: absolute;
top: 0;
right: 0;
left: 0;
}
&--center {
align-items: center;
justify-content: center;
}
&--surround {
&::after {
border-width: 1px;
}
}
&--clickable:active {
background-color: @active-color;
}
}
&__icon {
font-size: 28px;
}
&__text {
color: @gray-darker;
font-size: 12px;
}
&__icon + &__text {
margin-top: 8px;
}
}