Browse Source

feat: 完善cell组件

zhenyulei 5 years ago
parent
commit
f5e4adab0e

BIN
src/assets/img/cell-avatar.jpeg


File diff suppressed because it is too large
+ 0 - 1
src/assets/svg/address.svg


File diff suppressed because it is too large
+ 0 - 1
src/assets/svg/collection.svg


File diff suppressed because it is too large
+ 0 - 1
src/assets/svg/my-icon.svg


File diff suppressed because it is too large
+ 0 - 1
src/assets/svg/task.svg


+ 7 - 1
src/packages/avatar/avatar.vue

@@ -29,13 +29,19 @@ export default {
     bgImage: {
       type: String,
       default: ''
+    },
+    sizeNum:{
+      type: [Number,String],
+      default: 20
     }
   },
   computed: {
     styles() {
       return {
         backgroundImage: this.bgImage ? `url(${this.bgImage})` : null,
-        backgroundColor: `${this.bgColor}`
+        backgroundColor: `${this.bgColor}`,
+        width: this.sizeNum+'px',
+        height: this.sizeNum+'px'
       };
     },
     iconStyles() {

+ 34 - 8
src/packages/cell/__test__/cell.spec.js

@@ -8,24 +8,50 @@ describe('Cell.vue', () => {
         
     });
     
-    it('文案展示', () => {
-        wrapper.setProps({ title: '测试title', subTitle: '测试subTitle', desc: '测试desc', showIcon:true });
+    it('主标题文案展示', () => {
+        wrapper.setProps({ title: '测试title'});
 
         return Vue.nextTick().then(function () {
             expect(wrapper.find('.nut-cell-title').text()).toBe('测试title');
+        })
+    });
+    it('副标题文案展示', () => {
+        wrapper.setProps({ subTitle: '测试subTitle'});
+
+        return Vue.nextTick().then(function () {
             expect(wrapper.find('.nut-cell-sub-title').text()).toBe('测试subTitle');
+        })
+    });
+    it('描述文案展示', () => {
+        wrapper.setProps({ desc: '测试desc'});
+
+        return Vue.nextTick().then(function () {
             expect(wrapper.find('.nut-cell-desc').text()).toBe('测试desc');
-            expect(wrapper.find('.nut-cell-icon').isEmpty()).toBe(false);
-            
         })
     });
 
-    it('链接', () => {
+    it('是否显示右侧icon', () => {
+        wrapper.setProps({ showIcon:true });
+        return Vue.nextTick().then(function () {
+            expect(wrapper.find('.nut-cell-icon').isEmpty()).toBe(false); 
+        })
+    });
+    it('链接是否生效', () => {
         wrapper.setProps({ title: '测试title', subTitle: '测试subTitle', desc: '测试desc', showIcon: true, isLink: true, linkUrl:'http://m.jd.com' });
-
         return Vue.nextTick().then(function () {
-            expect(wrapper.classes('nut-cell-link')).toBe(true);
-            expect(wrapper.attributes('href')).toBe('http://m.jd.com');
+            expect(wrapper.find('.nut-cell').attributes('href')).toBe('http://m.jd.com');
+        })
+    });
+    it('背景颜色是否生效', () => {
+        wrapper.setProps({ title: '测试title', subTitle: '测试subTitle', desc: '测试desc', showIcon: true, bgColor:'red'});
+        return Vue.nextTick().then(function () {
+            expect(wrapper.find('.nut-cell').hasStyle('background-color','red')).toBe(true);
+        })
+    });
+    it('链接是否打开新页面', () => {
+        wrapper.setProps({ title: '测试title', subTitle: '测试subTitle', desc: '测试desc', showIcon: true, isLink: true, target:"_target", linkUrl:'http://m.jd.com' });
+        return Vue.nextTick().then(function () {
+            expect(wrapper.find('.nut-cell').attributes('target')).toBe('_target');
         })
     });
 });

+ 78 - 59
src/packages/cell/cell.scss

@@ -1,67 +1,86 @@
-.nut-cell {
-  display: block;
-  padding: 0 10px;
-  text-decoration: none;
-  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-  outline: none;
-  &.nut-cell-link:active {
-    background-color: $light-color !important;
-  }
-  .nut-cell-box {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    min-height: 48px;
-    @include nut-cell-border;
-  }
-  .nut-cell-left {
-    flex: 1;
-    flex-direction: column;
-  }
-  .nut-cell-title {
+.wrapper-cell{
+  background: #fff;
+  .nut-cell {
     display: block;
-    line-height: $line-height-base;
-    font-size: $font-size-base;
-    color: $title-color;
-  }
-  .nut-cell-sub-title {
-    display: block;
-    line-height: 1;
-    font-size: $font-size-small;
-    color: $text-color;
-    margin-top: 5px;
-    &:empty {
-      display: none;
-    }
-  }
-  .nut-cell-right {
-    display: flex;
-    align-items: center;
-    font-size: $font-size-small;
-    color: $text-color;
-  }
-  .nut-cell-icon {
-    display: flex;
-    align-items: center;
-    img {
-      height: 14px;
-      margin-left: 10px;
+    margin:0 20px;
+    padding: 12px 0px;
+    text-decoration: none;
+    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+    outline: none;
+    border-bottom: 1px solid rgba(230,230,230,1);
+    &.nut-cell-link:active {
+      background-color: $light-color !important;
     }
-  }
-  &:first-of-type {
-    @include nut-cell-border;
     .nut-cell-box {
-      background-image: none;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      // min-height: 48px;
+      // @include nut-cell-border;
+      .nut-icon{
+        margin-right: 13px;
+      }
+    }
+    .nut-cell-left {
+      flex: 1;
+      flex-direction: column;
+    }
+    .nut-cell-title {
+      display: block;
+      line-height: 24px;
+      font-size: 15px;
+      color: rgba(100,100,100,1);;
+    }
+    .nut-cell-sub-title {
+      display: block;
+      line-height: 18px;
+      font-size: $font-size-small;
+      color: #C8C8C8FF;
+      &:empty {
+        display: none;
+      }
+    }
+    .nut-cell-right {
+      display: flex;
+      align-items: center;
+      font-size: $font-size-small;
+      color: $text-color;
+      .nut-cell-desc{
+        color: #969696FF;
+        margin-right: 10px;
+      }
+    }
+    .nut-cell-icon {
+      display: flex;
+      align-items: center;
+      img {
+        height: 14px;
+        margin-left: 10px;
+      }
     }
+    // &:first-of-type {
+    //   @include nut-cell-border;
+    //   .nut-cell-box {
+    //     background-image: none;
+    //   }
+    // }
+    // &:last-of-type {
+    //   @include nut-cell-border;
+    //   background-position: bottom;
+    // }
+    // &:only-of-type {
+    //   background: linear-gradient(rgba($dark-color, 0.5), rgba($dark-color, 0.5)) bottom,
+    //     linear-gradient(rgba($dark-color, 0.5), rgba($dark-color, 0.5)) top;
+    //   background-size: 100% 1px;
+    //   background-repeat: no-repeat;
+    // }
   }
-  &:last-of-type {
-    @include nut-cell-border;
-    background-position: bottom;
+  
+  &:last-child .nut-cell{
+    border-bottom: none;
   }
-  &:only-of-type {
-    background: linear-gradient(rgba($dark-color, 0.5), rgba($dark-color, 0.5)) bottom,
-      linear-gradient(rgba($dark-color, 0.5), rgba($dark-color, 0.5)) top;
-    background-size: 100% 1px;
-    background-repeat: no-repeat;
+  &:only-of-type{
+    border-bottom: none;
   }
 }
+

+ 7 - 1
src/packages/cell/cell.vue

@@ -1,4 +1,5 @@
 <template>
+  <div class="wrapper-cell">
   <a :class="['nut-cell', { 'nut-cell-link': isLink }]" :href="linkUrl" :style="{ 'background-color': bgColor }" :target="target" @click="jumpPage">
     <div class="nut-cell-box" @click="clickCell">
       <slot name="avatar"></slot>
@@ -7,7 +8,11 @@
           ><slot name="title">{{ title }}</slot></span
         >
         <span class="nut-cell-sub-title"
-          ><slot name="sub-title">{{ subTitle }}</slot></span
+          >
+          <slot name="sub-title">
+            <template>{{ subTitle.substring(0,12) }}</template>
+            <template v-if="subTitle.length>12">...</template>
+          </slot></span
         >
       </div>
       <div class="nut-cell-right">
@@ -22,6 +27,7 @@
       </div>
     </div>
   </a>
+  </div>
 </template>
 <script>
 import Icon from '../icon/icon.vue';

+ 65 - 16
src/packages/cell/demo.vue

@@ -1,23 +1,61 @@
 <template>
   <div>
-    <h4>基本用法</h4>
-    <div>
-      <nut-cell title="我是标题" desc="描述文字" @click-cell="clickEvnt" to="/index"> </nut-cell>
-      <nut-cell :is-link="true" link-url="//m.jd.com" :show-icon="true" title="带链接" target="_target"> </nut-cell>
+    <h4>基础样式</h4>
+    <div class="cell-box">
+      <nut-cell title="列表内容A" to="/index"></nut-cell>
+      <nut-cell title="列表内容B" @click-cell="clickEvnt"></nut-cell>
+      <nut-cell title="列表内容C" @click-cell="clickEvnt"></nut-cell>
     </div>
-    <h4>通过Slot插槽分发内容</h4>
-    <div>
-      <nut-cell :is-link="true" :show-icon="true">
-        <span slot="title">我是主标题</span>
-        <span slot="sub-title">我是副标,我们都是通过Slot分发的</span>
-        <span slot="desc">我是描述</span>
+    <h4>带箭头的样式</h4>
+    <div class="cell-box">
+      <nut-cell title="列表内容A" :is-link="true" link-url="//m.jd.com" :show-icon="true" target="_target"> </nut-cell>
+      <nut-cell title="列表内容B" :is-link="true" link-url="//m.jd.com" :show-icon="true" target="_target"></nut-cell>
+      <nut-cell title="列表内容C" :is-link="true" link-url="//m.jd.com" :show-icon="true" target="_target"></nut-cell>
+    </div>
+    <h4>带解释说明的样式</h4>
+    <div class="cell-box">
+      <nut-cell :is-link="true">
+          <span slot="title">列表标题</span>
+          <span slot="sub-title">这里是对标题的解释说明</span>
+      </nut-cell>
+    </div>
+    <h4>菜单列表</h4>
+    <div class="cell-box">
+      <nut-cell :show-icon="true" title="我的主页" @click-cell="clickEvnt">
+        <div slot="avatar"><nut-icon type="self" color="#9D49F8FF" size="18px" :url="require('../../assets/svg/avatar.svg')">></nut-icon></div>
+      </nut-cell>
+      <nut-cell :show-icon="true" title="店铺定位" desc="查看店铺" @click-cell="clickEvnt">
+          <div slot="avatar"><nut-icon type="self" color="#FF6E4CFF" size="18px" :url="require('../../assets/svg/nav.svg')">></nut-icon></div>
+      </nut-cell>
+      <nut-cell :show-icon="true" title="我的收藏" @click-cell="clickEvnt">
+        <div slot="avatar"><nut-icon type="self" color="#FFBA12FF" size="18px" :url="require('../../assets/svg/star.svg')">></nut-icon></div>
       </nut-cell>
-      <nut-cell :show-icon="true">
-        <span slot="title">通过Slot自定义右侧ICON</span>
-        <nut-icon type="tick" slot="icon" size="15px" color="#848484"></nut-icon>
+      <nut-cell :show-icon="true" title="设置" desc="版本升级" @click-cell="clickEvnt">
+          <div slot="avatar"><nut-icon type="self" color="#1EA3FFFF" size="18px" :url="require('../../assets/svg/set.svg')">></nut-icon></div>
       </nut-cell>
-      <nut-cell :show-icon="true" title="我是标题" sub-title="我是副标题" desc="展示默认ICON">
-        <div slot="avatar"><nut-avatar></nut-avatar></div>
+    </div>
+    <h4>消息列表</h4>
+    <div class="cell-box">
+      <nut-cell title="噜啦噜" sub-title="我又来送福利啦!关注之后你就会">
+        <div slot="avatar"><nut-avatar sizeNum="60" :bg-image="require('../../assets/img/cell-avatar.jpeg')" bg-icon></nut-avatar></div>
+        <div slot="desc">
+          <p class="timer">10:12</p>
+          <p class="badge"><nut-badge  :value="9" :max="99" top="0px" right="15px"></nut-badge></p>
+        </div>
+      </nut-cell>
+      <nut-cell title="噜啦噜" sub-title="我又来送福利啦!关注之后你就会">
+        <div slot="avatar"><nut-avatar sizeNum="60" :bg-image="require('../../assets/img/cell-avatar.jpeg')" bg-icon></nut-avatar></div>
+        <div slot="desc">
+          <p class="timer">1小时前</p>
+          <p class="badge"><nut-badge  :is-dot="true" :max="99" top="0px" right="5px"></nut-badge></p>
+        </div>
+      </nut-cell>
+      <nut-cell title="噜啦噜" sub-title="我又来送福利啦!关注之后你就会">
+        <div slot="avatar"><nut-avatar sizeNum="60" :bg-image="require('../../assets/img/cell-avatar.jpeg')" bg-icon></nut-avatar></div>
+        <div slot="desc">
+          <p class="timer">星期五</p>
+          <p class="badge"><nut-badge  :value="100" :max="99" top="0px" right="25px"></nut-badge></p>
+        </div>
       </nut-cell>
     </div>
   </div>
@@ -28,12 +66,14 @@ import locale from '../../mixins/locale';
 import { locale as i18n } from '../../locales';
 import Icon from '../icon/icon.vue';
 import Avatar from '../avatar/avatar.vue';
+import Badge from '../badge/badge.vue'
 
 export default {
   mixins: [locale],
   components: {
     'nut-icon': Icon,
-    'nut-avatar': Avatar
+    'nut-avatar': Avatar,
+    'nut-badge':Badge
   },
   data() {
     return {};
@@ -55,4 +95,13 @@ export default {
 h4 {
   padding: 0 10px;
 }
+.timer{
+  color:#C8C8C8FF;
+}
+.badge{
+  .nut-badge{
+    width: 100%;
+    height: 100%;
+  }
+}
 </style>

+ 67 - 23
src/packages/cell/doc.md

@@ -2,52 +2,89 @@
 
 列表项,可组成列表。
 
-## 基本用法
+## 基础样式
 
 **to**有值的时候,跳转路由,**click-cell**点击cell触发事件
 
 ```html
-<nut-cell title="我是标题" desc="描述文字" @click-cell="clickEvnt" to="/index">
-</nut-cell>
+<div class="cell-box">
+  <nut-cell title="列表内容A" to="/index"></nut-cell>
+  <nut-cell title="列表内容B" @click-cell="clickEvnt"></nut-cell>
+  <nut-cell title="列表内容C" @click-cell="clickEvnt"></nut-cell>
+</div>
 ```
 
-设置**link-url**,点击可跳转。设置**target**,可以配置是否打开新的页面
+带箭头的样式
 
 ```html
-<nut-cell :is-link="true" link-url="//m.jd.com" :show-icon="true" title="带链接" target="_target">
-</nut-cell>
+<div class="cell-box">
+  <nut-cell title="列表内容A" :is-link="true" link-url="//m.jd.com" :show-icon="true" target="_target"> </nut-cell>
+  <nut-cell title="列表内容B" :is-link="true" link-url="//m.jd.com" :show-icon="true" target="_target"></nut-cell>
+  <nut-cell title="列表内容C" :is-link="true" link-url="//m.jd.com" :show-icon="true" target="_target"></nut-cell>
+</div>
 ```
-可以通过设置slot,设置cell的具体内容
 
+带解释说明的样式
 ```html
-<nut-cell :is-link="true" :show-icon="true">
-    <span slot="title">我是主标题</span>
-    <span slot="sub-title">我是副标,我们都是通过Slot分发的</span>
-    <span slot="desc">我是描述</span>
-</nut-cell>
+<div class="cell-box">
+  <nut-cell :is-link="true">
+      <span slot="title">列表标题</span>
+      <span slot="sub-title">这里是对标题的解释说明</span>
+  </nut-cell>
+</div>
 ```
 
+可以通过设置slot,设置cell的具体内容,比如以下的菜单列表,注意使用了 icon 组件
+
 ```html
-<nut-cell :show-icon="true">
-    <span slot="title">通过Slot自定义右侧ICON</span>
-    <nut-icon type="tick" slot="icon" size="15px" color="#848484"></nut-icon>
-</nut-cell>
+<div class="cell-box">
+  <nut-cell :show-icon="true" title="我的主页" @click-cell="clickEvnt">
+    <div slot="avatar"><nut-icon type="self" color="#9D49F8FF" size="18px" :url="require('../../assets/svg/avatar.svg')">></nut-icon></div>
+  </nut-cell>
+  <nut-cell :show-icon="true" title="店铺定位" desc="查看店铺" @click-cell="clickEvnt">
+      <div slot="avatar"><nut-icon type="self" color="#FF6E4CFF" size="18px" :url="require('../../assets/svg/nav.svg')">></nut-icon></div>
+  </nut-cell>
+  <nut-cell :show-icon="true" title="我的收藏" @click-cell="clickEvnt">
+    <div slot="avatar"><nut-icon type="self" color="#FFBA12FF" size="18px" :url="require('../../assets/svg/star.svg')">></nut-icon></div>
+  </nut-cell>
+  <nut-cell :show-icon="true" title="设置" desc="版本升级" @click-cell="clickEvnt">
+      <div slot="avatar"><nut-icon type="self" color="#1EA3FFFF" size="18px" :url="require('../../assets/svg/set.svg')">></nut-icon></div>
+  </nut-cell>
+</div>
 ```
-**slot为avatar**可以添加左侧头像,具体组件配置请参考avatar组件
+可以通过设置slot,设置cell的更为丰富的内容,比如以下的消息列表,注意使用了 badge、avatar 组件
 
 ```html
-<nut-cell :show-icon="true" title="我是标题" sub-title="我是副标题" desc="展示默认ICON">
-  <div slot="avatar"><nut-avatar></nut-avatar></div>
-</nut-cell>
+<div class="cell-box">
+  <nut-cell title="噜啦噜" sub-title="我又来送福利啦!关注之后你就会">
+    <div slot="avatar"><nut-avatar sizeNum="60" :bg-image="require('../../assets/img/cell-avatar.jpeg')" bg-icon></nut-avatar></div>
+    <div slot="desc">
+      <p class="timer">10:12</p>
+      <p class="badge"><nut-badge  :value="9" :max="99" top="0px" right="15px"></nut-badge></p>
+    </div>
+  </nut-cell>
+  <nut-cell title="噜啦噜" sub-title="我又来送福利啦!关注之后你就会">
+    <div slot="avatar"><nut-avatar sizeNum="60" :bg-image="require('../../assets/img/cell-avatar.jpeg')" bg-icon></nut-avatar></div>
+    <div slot="desc">
+      <p class="timer">1小时前</p>
+      <p class="badge"><nut-badge  :is-dot="true" :max="99" top="0px" right="5px"></nut-badge></p>
+    </div>
+  </nut-cell>
+  <nut-cell title="噜啦噜" sub-title="我又来送福利啦!关注之后你就会">
+    <div slot="avatar"><nut-avatar sizeNum="60" :bg-image="require('../../assets/img/cell-avatar.jpeg')" bg-icon></nut-avatar></div>
+    <div slot="desc">
+      <p class="timer">星期五</p>
+      <p class="badge"><nut-badge  :value="100" :max="99" top="0px" right="25px"></nut-badge></p>
+    </div>
+  </nut-cell>
+</div>
 ```
 
 ## Prop
 
 | 字段 | 说明 | 类型 | 默认值
 |----- | ----- | ----- | ----- 
-| title | 左侧主标题 | String | -
-| sub-title | 左侧副标题 | String | -
-| desc | 右侧部分内容 | String | -
+| title | 左侧标题 | String | -
 | is-link | 是否是链接 | Boolean | false
 | link-url | 链接Url | String | -
 | show-icon | 是否展示右侧箭头Icon | Boolean | false
@@ -55,7 +92,14 @@
 | to      |路由路径| String |-|
 | target |同`<a>`中target属性|String|_self|
 
+## slot
 
+| 字段 | 说明 | 类型 | 默认值
+|----- | ----- | ----- | ----- 
+| title | 有主副标题时,左侧主标题 | -- | -
+| sub-title | 左侧副标题 | -- | -
+| desc | 右侧部分内容 | -- | -
+| avatar | 左侧图片 | -- | -
 
 ## Event
 |字段|说明|回调参数|