Commit da3117eff60e0573a381feb140fd0ac9444b76d3

Authored by 刘汉宸
1 parent 1027838c
Exists in master

refactor: 重构Cell组件

examples/assets/iconfont/iconfont.css
@@ -9,7 +9,6 @@ @@ -9,7 +9,6 @@
9 9
10 .iconfont { 10 .iconfont {
11 font-family: "iconfont" !important; 11 font-family: "iconfont" !important;
12 - font-size: 16px;  
13 font-style: normal; 12 font-style: normal;
14 -webkit-font-smoothing: antialiased; 13 -webkit-font-smoothing: antialiased;
15 -moz-osx-font-smoothing: grayscale; 14 -moz-osx-font-smoothing: grayscale;
examples/styles/variables.scss
@@ -54,19 +54,18 @@ $color-warning: #fa8c16; @@ -54,19 +54,18 @@ $color-warning: #fa8c16;
54 $color-error: #f5222d; 54 $color-error: #f5222d;
55 55
56 $color-minor: #8c8c8c; 56 $color-minor: #8c8c8c;
57 -$color-border: #f0f0f0;  
58 $color-disabled: #ccc; 57 $color-disabled: #ccc;
59 58
60 $bg-active: #f3f3f3; 59 $bg-active: #f3f3f3;
61 $bg-disabled: #f5f5f5; 60 $bg-disabled: #f5f5f5;
62 61
63 $font-lg: 1.25rem; 62 $font-lg: 1.25rem;
64 -$font-md: 1rem; 63 +$font-md: 0.9rem;
65 $font-sm: 0.65rem; 64 $font-sm: 0.65rem;
66 65
67 -$h-gap-lg: 0.65rem;  
68 -$h-gap-md: 0.45rem; 66 +$h-gap-lg: 0.75rem;
  67 +$h-gap-md: 0.5rem;
69 $h-gap-sm: 0.3rem; 68 $h-gap-sm: 0.3rem;
70 $v-gap-lg: 1.5rem; 69 $v-gap-lg: 1.5rem;
71 $v-gap-md: 1rem; 70 $v-gap-md: 1rem;
72 -$v-gap-sm: 0.65rem;  
73 \ No newline at end of file 71 \ No newline at end of file
  72 +$v-gap-sm: 0.6rem;
74 \ No newline at end of file 73 \ No newline at end of file
examples/views/docs/component/cell.md
@@ -12,7 +12,11 @@ @@ -12,7 +12,11 @@
12 <template> 12 <template>
13 <div class="demo-cell"> 13 <div class="demo-cell">
14 <zui-cell title="选项一" value="内容一"></zui-cell> 14 <zui-cell title="选项一" value="内容一"></zui-cell>
15 - <zui-cell title="选项二" value="内容二" label="描述"></zui-cell> 15 + <zui-cell title="选项二" value="内容二" short size="large"></zui-cell>
  16 + <zui-cell title="选项三" value="内容三" long></zui-cell>
  17 + <zui-cell title="选项四" value="内容四" label="副标题" is-link center></zui-cell>
  18 + <zui-cell title="选项五" value="内容五" is-link :clickable="false"></zui-cell>
  19 + <zui-cell title="选项六" value="内容六" label="描述" :border="false"></zui-cell>
16 </div> 20 </div>
17 </template> 21 </template>
18 22
@@ -95,7 +99,7 @@ @@ -95,7 +99,7 @@
95 关注微信公众号,可获取运单到账信息关注微信公众号,可获取运单到账信息关注微信公众号,可获取运单到账信息关注微信公众号,可获取运单到账信息 99 关注微信公众号,可获取运单到账信息关注微信公众号,可获取运单到账信息关注微信公众号,可获取运单到账信息关注微信公众号,可获取运单到账信息
96 </div> 100 </div>
97 </div> 101 </div>
98 - <div slot="right" style="height: 100%; text-align: right; display: flex; flex-direction: column; justify-content: space-between;"> 102 + <div style="height: 100%; text-align: right; display: flex; flex-direction: column; justify-content: space-between; white-space: nowrap; word-break: break-all;">
99 <div style="font-size: 12px; color: grey;">2020-03-18</div> 103 <div style="font-size: 12px; color: grey;">2020-03-18</div>
100 <div><zui-tag size="tiny" shape="dot" type="fill"></zui-tag></div> 104 <div><zui-tag size="tiny" shape="dot" type="fill"></zui-tag></div>
101 </div> 105 </div>
packages/button/index.vue
@@ -6,11 +6,11 @@ @@ -6,11 +6,11 @@
6 6
7 <script> 7 <script>
8 import color from 'color'; 8 import color from 'color';
9 -import BUTTON_MIXIN from '../mixins/button'; 9 +import MIX_BUTTON from '../mixins/button';
10 10
11 export default { 11 export default {
12 name: 'Button', 12 name: 'Button',
13 - mixins: [BUTTON_MIXIN], 13 + mixins: [MIX_BUTTON],
14 props: { 14 props: {
15 type: { 15 type: {
16 type: String, 16 type: String,
packages/cell/index.css
@@ -1,84 +0,0 @@ @@ -1,84 +0,0 @@
1 -.zui-cell {  
2 - position: relative;  
3 - display: -webkit-box;  
4 - display: -webkit-flex;  
5 - display: flex;  
6 - box-sizing: border-box;  
7 - width: 100%;  
8 - padding: 0.625rem 1rem;  
9 - overflow: hidden;  
10 - color: #323233;  
11 - font-size: 0.875rem;  
12 - background-color: #fff;  
13 -}  
14 -  
15 -.zui-cell--clickable {  
16 - cursor: pointer;  
17 -}  
18 -  
19 -.zui-cell--clickable:active {  
20 - background-color: #f2f3f5;  
21 -}  
22 -  
23 -.zui-cell__left-icon {  
24 - display: flex;  
25 - align-items: center;  
26 - margin-right: 0.375rem;  
27 -}  
28 -  
29 -.zui-cell__right-icon {  
30 - display: flex;  
31 - align-items: center;  
32 - margin-left: 0.375rem;  
33 -}  
34 -  
35 -.zui-cell__left-icon, .zui-cell__right-icon {  
36 - min-width: 1em;  
37 - font-size: 1rem;  
38 -}  
39 -  
40 -.zui-cell:not(:last-child)::after {  
41 - position: absolute;  
42 - box-sizing: border-box;  
43 - content: ' ';  
44 - pointer-events: none;  
45 - right: 0;  
46 - bottom: 0;  
47 - left: 1rem;  
48 - border-bottom: 1px solid #ebedf0;  
49 - -webkit-transform: scaleY(0.5);  
50 - transform: scaleY(0.5);  
51 -}  
52 -  
53 -.zui-cell__title, .zui-cell__value {  
54 - -webkit-box-flex: 1;  
55 - -webkit-flex: 1;  
56 - flex: 1;  
57 -}  
58 -  
59 -.zui-cell__title {  
60 - display: flex;  
61 - flex-direction: column;  
62 - justify-content: center;  
63 -}  
64 -  
65 -.zui-cell__value {  
66 - display: flex;  
67 - align-items: center;  
68 - justify-content: flex-end;  
69 -}  
70 -  
71 -.zui-cell__value {  
72 - position: relative;  
73 - overflow: hidden;  
74 - color: #969799;  
75 - text-align: right;  
76 - vertical-align: middle;  
77 - word-wrap: break-word;  
78 -}  
79 -  
80 -.zui-cell__label {  
81 - padding-top: 0.25rem;  
82 - color: #969799;  
83 - font-size: 0.75rem;  
84 -}  
packages/cell/index.scss 0 → 100644
@@ -0,0 +1,99 @@ @@ -0,0 +1,99 @@
  1 +.zui-cell {
  2 + $v-cell-gap-sm: 0.35rem;
  3 +
  4 + display: flex;
  5 + box-sizing: border-box;
  6 + width: 100%;
  7 + overflow: hidden;
  8 + font-size: $font-md;
  9 + background-color: $color-white;
  10 + padding-left: $v-gap-md;
  11 + &--border-short {
  12 + padding-left: $v-gap-md;
  13 + padding-right: $v-gap-md;
  14 + .zui-cell__content {
  15 + padding-left: 0;
  16 + padding-right: 0;
  17 + }
  18 + }
  19 + &--border-long {
  20 + padding-left: 0;
  21 + padding-right: 0;
  22 + .zui-cell__content {
  23 + padding-left: $v-gap-md;
  24 + padding-right: $v-gap-md;
  25 + }
  26 + }
  27 + &__content {
  28 + width: 100%;
  29 + padding: $h-gap-lg $v-gap-md $h-gap-lg 0;
  30 + position: relative;
  31 + display: flex;
  32 + justify-content: space-between;
  33 + &.zui-cell--border {
  34 + border-bottom: 1px solid $color-field;
  35 + }
  36 + &.zui-cell--border-solid::after {
  37 + position: absolute;
  38 + content: '';
  39 + width: 100%;
  40 + left: 0;
  41 + bottom: 0;
  42 + height: 1px;
  43 + background-color: $color-field;
  44 + -webkit-transform: scale(1, 0.5);
  45 + transform: scale(1, 0.5);
  46 + -webkit-transform-origin: center bottom;
  47 + transform-origin: center bottom;
  48 + }
  49 + }
  50 + &.large {
  51 + .zui-cell__content {
  52 + padding-top: $h-gap-lg * 1.2;
  53 + padding-bottom: $h-gap-lg * 1.2;
  54 + }
  55 + .zui-cell__icon {
  56 + padding-right: $v-gap-sm;
  57 + }
  58 + .zui-cell__right-icon {
  59 + font-size: $font-lg;
  60 + }
  61 + }
  62 + &__title, &__value {
  63 + flex: auto;
  64 + }
  65 + &__label {
  66 + font-size: $font-md * 0.8;
  67 + color: $color-text-minor;
  68 + }
  69 + &__value {
  70 + text-align: right;
  71 + color: $color-text-minor;
  72 + }
  73 + &__icon {
  74 + display: flex;
  75 + align-items: center;
  76 + padding-right: $v-cell-gap-sm;
  77 + }
  78 + &__right-icon {
  79 + display: flex;
  80 + align-items: center;
  81 + padding-left: $v-cell-gap-sm;
  82 + color: $color-disabled;
  83 + &, .zui-icon {
  84 + font-size: $font-md * 1.25;
  85 + }
  86 + }
  87 + &--clickable {
  88 + cursor: pointer;
  89 + &.zui-cell--hover {
  90 + background-color: $bg-active;
  91 + }
  92 + }
  93 + &--center {
  94 + align-items: center;
  95 + .zui-cell__title, .zui-cell__content {
  96 + align-items: center;
  97 + }
  98 + }
  99 +}
packages/cell/index.vue
1 <template> 1 <template>
2 - <div class="zui-cell" :class="classRender" @click="onClick">  
3 - <div v-if="$slots.icon || icon" class="zui-cell__left-icon">  
4 - <slot v-if="$slots.icon" name="icon"></slot>  
5 - <zui-icon v-else-if="icon" class="zui-cell__left-icon" :name="icon"></zui-icon>  
6 - </div>  
7 - <div v-if="$slots.title" class="zui-cell__title">  
8 - <slot name="title"></slot>  
9 - <div v-if="$slots.label" class="zui-cell__label">  
10 - <slot name="label"></slot>  
11 - </div>  
12 - <div v-else-if="label" class="zui-cell__label">  
13 - <span>{{ label }}</span> 2 + <div class="zui-cell" :class="bindClass" v-on="bindEvents">
  3 + <div class="zui-cell__content" :class="bindContentClass">
  4 + <!-- 左侧图标 -->
  5 + <template v-if="$slots['icon'] || icon">
  6 + <div class="zui-cell__icon">
  7 + <slot v-if="$slots.icon" name="icon"></slot>
  8 + <zui-icon v-else-if="icon" :name="icon"></zui-icon>
  9 + </div>
  10 + </template>
  11 + <!-- 标题 -->
  12 + <div class="zui-cell__title">
  13 + <slot v-if="$slots['title']" name="title"></slot>
  14 + <span v-else>{{ title }}</span>
  15 + <template v-if="$slots['label'] || label">
  16 + <div class="zui-cell__label">
  17 + <slot v-if="$slots['label']" name="label"></slot>
  18 + <span v-else>{{ label }}</span>
  19 + </div>
  20 + </template>
14 </div> 21 </div>
15 - </div>  
16 - <div v-else-if="title" class="zui-cell__title">  
17 - <span>{{ title }}</span>  
18 - <div v-if="$slots.label" class="zui-cell__label">  
19 - <slot name="label"></slot> 22 + <!-- 内容 -->
  23 + <div class="zui-cell__value">
  24 + <slot v-if="$slots['default']"></slot>
  25 + <span v-else>{{ value }}</span>
20 </div> 26 </div>
21 - <div v-else-if="label" class="zui-cell__label">  
22 - <span>{{ label }}</span>  
23 - </div>  
24 - </div>  
25 - <div v-if="$slots.default" class="zui-cell__value">  
26 - <slot></slot>  
27 - </div>  
28 - <div v-else-if="value" class="zui-cell__value">{{ value }}</div>  
29 - <div v-if="$slots.right || rightIcon" class="zui-cell__right-icon">  
30 - <slot v-if="$slots.right" name="right"></slot>  
31 - <zui-icon v-else-if="rightIcon && isLink" class="zui-cell__right-icon" :name="rightIcon"></zui-icon> 27 + <!-- 右侧图标 -->
  28 + <template v-if="$slots['right-icon'] || isLink">
  29 + <div class="zui-cell__right-icon">
  30 + <slot v-if="$slots['right-icon']" name="right-icon"></slot>
  31 + <zui-icon v-else :name="rightIcon || 'enter'"></zui-icon>
  32 + </div>
  33 + </template>
32 </div> 34 </div>
33 </div> 35 </div>
34 </template> 36 </template>
35 37
36 <script> 38 <script>
  39 +import MIX_BUTTON from '../mixins/button';
  40 +
37 export default { 41 export default {
38 name: 'Cell', 42 name: 'Cell',
  43 + mixins: [MIX_BUTTON],
39 props: { 44 props: {
40 - icon: String,  
41 title: String, 45 title: String,
42 - value: String,  
43 label: String, 46 label: String,
44 - isLink: Boolean,  
45 - rightIcon: { 47 + value: [String, Number],
  48 + icon: String,
  49 + rightIcon: String,
  50 + size: String,
  51 + border: {
  52 + type: Boolean,
  53 + default: true,
  54 + },
  55 + solid: Boolean,
  56 + long: Boolean,
  57 + short: Boolean,
  58 + isLink: {
  59 + type: Boolean,
  60 + default: undefined,
  61 + },
  62 + clickable: {
  63 + type: Boolean,
  64 + default: undefined,
  65 + },
  66 + hoverClass: {
46 type: String, 67 type: String,
47 - default: 'enter', 68 + default: 'zui-cell--hover',
  69 + },
  70 + center: {
  71 + type: Boolean,
  72 + default: true,
48 }, 73 },
49 }, 74 },
50 computed: { 75 computed: {
51 - classRender: function () { 76 + isClickable() {
  77 + if (this.isLink) {
  78 + return this.clickable !== false;
  79 + }
  80 + return this.clickable;
  81 + },
  82 + bindClass() {
52 return { 83 return {
53 - 'zui-cell--clickable': this.isLink, 84 + 'zui-cell--border-long': this.long,
  85 + 'zui-cell--border-short': this.short,
  86 + 'zui-cell--clickable': this.isClickable,
  87 + 'zui-cell--center': this.center,
  88 + [this.hoverClass]: this.hover,
  89 + [this.size]: !!this.size,
54 }; 90 };
55 }, 91 },
56 - },  
57 - methods: {  
58 - onClick: function () {  
59 - if (this.$listeners['click']) {  
60 - this.$emit('click');  
61 - } 92 + bindContentClass() {
  93 + const borderClass = `zui-cell--border${this.solid ? '-solid' : ''}`;
  94 + return {
  95 + [borderClass]: this.border,
  96 + };
62 }, 97 },
63 }, 98 },
64 }; 99 };
65 </script> 100 </script>
66 101
67 -<style>  
68 -@import './index.css'; 102 +<style lang="scss">
  103 +@import './index.scss';
69 </style> 104 </style>
packages/mixins/button.js
1 /** 1 /**
2 - * @file 仿微信小程序按钮hover-class 2 + * @description 仿微信小程序按钮hover-class
3 */ 3 */
4 4
5 export default { 5 export default {
packages/mixins/event.js 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +/**
  2 + * @description 处理组件内外事件
  3 + */
  4 +
  5 +export default {
  6 + computed: {
  7 + // 事件hack
  8 + bindEvents() {
  9 + return this.$listeners || {};
  10 + },
  11 + },
  12 +};