Browse Source

feat: card商品组件

Drjnigfubo 4 years ago
parent
commit
1829745d11

+ 11 - 0
src/config.json

@@ -957,6 +957,17 @@
           "sort": 1,
           "show": true,
           "author": "yangxiaolu3"
+        },
+        {
+          "version": "3.0.0",
+          "taro": true,
+          "name": "Card",
+          "type": "component",
+          "cName": "商品卡片",
+          "desc": "展示商品",
+          "sort": 1,
+          "show": true,
+          "author": "Drjingfubo"
         }
       ]
     }

+ 139 - 0
src/packages/__VUE/card/demo.vue

@@ -0,0 +1,139 @@
+<template>
+  <view class="demo">
+    <h2>默认用法</h2>
+    <nut-card
+      :img-url="state.imgUrl"
+      :title="state.title"
+      :price="state.price"
+      :vipPrice="state.vipPrice"
+      :shopDesc="state.shopDesc"
+      :delivery="state.delivery"
+      :shopName="state.shopName"
+    >
+    </nut-card>
+    <h2>自定义商品标签</h2>
+    <nut-card
+      :img-url="state.imgUrl"
+      :title="state.title"
+      :price="state.price"
+      :vipPrice="state.vipPrice"
+      :shopDesc="state.shopDesc"
+      :delivery="state.delivery"
+      :shopName="state.shopName"
+    >
+      <template #prolist>
+        <div class="search_prolist_attr">
+          <span class="word">活鲜</span>
+          <span class="word">礼盒</span>
+          <span class="word">国产</span>
+        </div>
+      </template>
+    </nut-card>
+    <h2>价格后自定义标签</h2>
+    <nut-card
+      :img-url="state.imgUrl"
+      :title="state.title"
+      :price="state.price"
+      :vipPrice="state.vipPrice"
+      :shopDesc="state.shopDesc"
+      :delivery="state.delivery"
+      :shopName="state.shopName"
+    >
+      <template #prolist>
+        <div class="search_prolist_attr">
+          <span class="word">活鲜</span>
+          <span class="word">礼盒</span>
+          <span class="word">国产</span>
+        </div>
+      </template>
+    </nut-card>
+    <h2>商家介绍自定义</h2>
+    <nut-card
+      :img-url="state.imgUrl"
+      :title="state.title"
+      :price="state.price"
+      :vipPrice="state.vipPrice"
+      :shopDesc="state.shopDesc"
+      :delivery="state.delivery"
+      :shopName="state.shopName"
+    >
+      <template #shop-tag>
+        <div>这里是自定义区域</div>
+      </template>
+      <template #origin>
+        <img
+          class="tag"
+          src="//img11.360buyimg.com/jdphoto/s58x28_jfs/t9451/359/415622649/15318/b0943e5d/59a78495N3bd2a9f8.png"
+          alt=""
+        />
+      </template>
+    </nut-card>
+    <h2>自定义右下角内容</h2>
+    <nut-card
+      :img-url="state.imgUrl"
+      :title="state.title"
+      :price="state.price"
+      :vipPrice="state.vipPrice"
+      :shopDesc="state.shopDesc"
+      :delivery="state.delivery"
+      :shopName="state.shopName"
+    >
+      <template #footer>
+        <div class="customize">自定义</div>
+      </template>
+    </nut-card>
+  </view>
+</template>
+
+<script lang="ts">
+import { reactive } from '@vue/reactivity';
+import { createComponent } from '../../utils/create';
+const { createDemo } = createComponent('card');
+
+export default createDemo({
+  setup() {
+    const state = reactive({
+      imgUrl:
+        '//img10.360buyimg.com/n2/s240x240_jfs/t1/210890/22/4728/163829/6163a590Eb7c6f4b5/6390526d49791cb9.jpg!q70.jpg',
+      title: '活蟹】湖塘煙雨 阳澄湖大闸蟹公4.5两 母3.5两 4对8只 鲜活生鲜螃蟹现货水产礼盒海鲜水',
+      price: '388',
+      vipPrice: '378',
+      shopDesc: '自营',
+      delivery: '厂商配送',
+      shopName: '阳澄湖大闸蟹自营店>'
+    });
+    return {
+      state
+    };
+  }
+});
+</script>
+
+<style lang="scss" scoped>
+.search_prolist_attr {
+  margin: 3px 0 1px;
+  height: 15px;
+  overflow: hidden;
+  > span {
+    float: left;
+    padding: 0 5px;
+    border-radius: 1px;
+    font-size: 10px;
+    height: 15px;
+    line-height: 15px;
+    color: #999;
+    background-color: #f2f2f7;
+    margin-right: 5px;
+  }
+}
+.tag {
+  display: inline-block;
+  vertical-align: middle;
+  margin-right: 5px;
+  margin-left: 2px;
+  height: 14px;
+}
+.customize {
+  font-size: 12px;
+}
+</style>

+ 90 - 0
src/packages/__VUE/card/doc.md

@@ -0,0 +1,90 @@
+# Card 商品卡片
+
+### 介绍
+
+商品卡片,用于展示商品的图片、价格等信息
+
+### 安装
+
+```javascript
+
+import { createApp } from 'vue';
+// vue
+import { Card } from '@nutui/nutui';
+// taro
+import { Card } from '@nutui/nutui-taro';
+
+const app = createApp();
+app.use(Card);
+
+```
+
+### 代码实例
+
+### 基本用法
+
+```html
+ <nut-card
+      :img-url="state.imgUrl"
+      :title="state.title"
+      :price="state.price"
+      :vipPrice="state.vipPrice"
+      :shopDesc="state.shopDesc"
+      :delivery="state.delivery"
+      :shopName="state.shopName"
+    >
+    </nut-card>
+```
+
+### 自定义内容
+
+```html
+<nut-card
+:img-url="state.imgUrl"
+:title="state.title"
+:price="state.price"
+:vipPrice="state.vipPrice"
+:shopDesc="state.shopDesc"
+:delivery="state.delivery"
+:shopName="state.shopName"
+>
+  <template #prolist>
+    <div class="search_prolist_attr">
+      <span class="word">活鲜</span>
+      <span class="word">礼盒</span>
+      <span class="word">国产</span>
+    </div>
+  </template>
+  <template #tag>
+    <img
+        class="tag" 
+        src="//img11.360buyimg.com/jdphoto/s58x28_jfs/t9451/359/415622649/15318/b0943e5d/59a78495N3bd2a9f8.png"
+        alt=""
+    />
+  </template>
+    <template #footer>
+      <div class="customize">自定义</div>
+    </template>
+</nut-card>
+```
+### Prop  
+
+| 字段    | 说明                                       | 类型    | 默认值    |
+|---------|--------------------------------------------|---------|-----------|
+| img-url   | 左侧图片Url                                 | String  | -         |
+| title     | 标题                   | String  | -    |
+| price | 商品价格                         | String  | -      |
+| vip-price     | 会员价格                               | String | -    |
+| shop-desc  | 店铺介绍                                  | String | -    |
+| delivery     | 配送方式 | String  | -      |
+| shop-name   | 店铺名称| String  | -      |
+
+
+### Slots
+
+| 名称    | 说明         |
+|---------|--------------|
+| prolist | 	自定义商品介绍 |
+| origin | 	价格后方自定义内容 |
+| shop-tag | 	店铺介绍自定义 |
+| footer | 	右下角内容自定义 |

+ 97 - 0
src/packages/__VUE/card/index.scss

@@ -0,0 +1,97 @@
+.nut-card {
+  width: 100%;
+  display: flex;
+
+  .nut-card__left {
+    width: 120px;
+    height: 120px;
+    flex-shrink: 0;
+
+    > img {
+      display: block;
+      width: 100%;
+      height: 100%;
+    }
+  }
+
+  .nut-card__right {
+    flex: 1;
+    padding: 0 10px 8px;
+
+    .nut-card__right__title {
+      display: -webkit-box;
+      -webkit-box-orient: vertical;
+      -webkit-line-clamp: 2;
+      overflow: hidden;
+      word-break: break-all;
+      line-height: 1.5;
+      font-size: 14px;
+    }
+
+    .nut-card__right__price {
+      display: flex;
+      align-items: center;
+      height: 18px;
+      line-height: 18px;
+      margin-top: 9px;
+
+      .nut-price {
+        .nut-price--symbol-large {
+          font-size: 12px;
+        }
+
+        .nut-price--large {
+          font-size: 18px;
+        }
+
+        .nut-price--decimal-large {
+          font-size: 12px;
+        }
+      }
+
+      .nut-card__right__price__origin {
+        &.nut-price {
+          margin-left: 2px;
+          color: #d2a448;
+
+          .nut-price--symbol-large {
+            font-size: 12px;
+          }
+
+          .nut-price--large {
+            font-size: 12px;
+          }
+
+          .nut-price--decimal-large {
+            font-size: 12px;
+          }
+        }
+      }
+    }
+
+    .nut-card__right__other {
+      display: flex;
+      align-items: center;
+      padding: 5px 0 2px;
+      .nut-tag {
+        border: none;
+        padding: 0 2px;
+        margin-right: 5px;
+        font-size: $card-font-size-0;
+      }
+    }
+
+    .nut-card__right__shop {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+
+      .nut-card__right__shop__name {
+        line-height: 1.5;
+        color: #999;
+        font-size: 12px;
+        padding-top: 4px;
+      }
+    }
+  }
+}

+ 81 - 0
src/packages/__VUE/card/index.taro.vue

@@ -0,0 +1,81 @@
+<template>
+  <div class="nut-card">
+    <div class="nut-card__left">
+      <img :src="imgUrl" alt="" />
+    </div>
+    <div class="nut-card__right">
+      <div class="nut-card__right__title">{{ title }}</div>
+      <slot name="prolist"></slot>
+      <div class="nut-card__right__price">
+        <nut-price :price="price"></nut-price>
+        <template v-if="isHaveSlot('origin')">
+          <slot name="origin"></slot>
+        </template>
+        <nut-price v-else class="nut-card__right__price__origin" :price="vipPrice"></nut-price>
+        <template v-if="isHaveSlot('tag')">
+          <slot name="tag"></slot>
+        </template>
+      </div>
+      <div class="nut-card__right__other">
+        <template v-if="isHaveSlot('shop-tag')">
+          <slot name="shop-tag"></slot>
+        </template>
+        <template v-else>
+          <nut-tag type="danger">{{ shopDesc }}</nut-tag>
+          <nut-tag plain>{{ delivery }}</nut-tag>
+        </template>
+      </div>
+      <div class="nut-card__right__shop">
+        <div class="nut-card__right__shop__name">{{ shopName }}</div>
+        <slot name="footer"></slot>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { computed, reactive } from 'vue';
+import { createComponent } from '../../utils/create';
+const { create } = createComponent('card');
+export default create({
+  props: {
+    imgUrl: {
+      type: String,
+      default: ''
+    },
+    title: {
+      type: String,
+      default: ''
+    },
+    price: {
+      type: String,
+      default: ''
+    },
+    vipPrice: {
+      type: String,
+      default: ''
+    },
+    shopDesc: {
+      type: String,
+      default: ''
+    },
+    delivery: {
+      type: String,
+      default: ''
+    },
+    shopName: {
+      type: String,
+      default: ''
+    }
+  },
+
+  setup(props, { emit, slots }) {
+    const isHaveSlot = (slot: string) => {
+      return slots[slot];
+    };
+    return {
+      isHaveSlot
+    };
+  }
+});
+</script>

+ 81 - 0
src/packages/__VUE/card/index.vue

@@ -0,0 +1,81 @@
+<template>
+  <div class="nut-card">
+    <div class="nut-card__left">
+      <img :src="imgUrl" alt="" />
+    </div>
+    <div class="nut-card__right">
+      <div class="nut-card__right__title">{{ title }}</div>
+      <slot name="prolist"></slot>
+      <div class="nut-card__right__price">
+        <nut-price :price="price"></nut-price>
+        <template v-if="isHaveSlot('origin')">
+          <slot name="origin"></slot>
+        </template>
+        <nut-price v-else class="nut-card__right__price__origin" :price="vipPrice"></nut-price>
+      </div>
+      <div class="nut-card__right__other">
+        <template v-if="isHaveSlot('shop-tag')">
+          <slot name="shop-tag"></slot>
+        </template>
+        <template v-else>
+          <nut-tag type="danger">{{ shopDesc }}</nut-tag>
+          <nut-tag plain>{{ delivery }}</nut-tag>
+        </template>
+      </div>
+      <div class="nut-card__right__shop">
+        <div class="nut-card__right__shop__name">{{ shopName }}</div>
+        <slot name="footer"></slot>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { computed, reactive } from 'vue';
+import { createComponent } from '../../utils/create';
+const { create } = createComponent('card');
+export default create({
+  props: {
+    imgUrl: {
+      type: String,
+      default: ''
+    },
+    title: {
+      type: String,
+      default: ''
+    },
+    price: {
+      type: String,
+      default: ''
+    },
+    vipPrice: {
+      type: String,
+      default: ''
+    },
+    shopDesc: {
+      type: String,
+      default: ''
+    },
+    delivery: {
+      type: String,
+      default: ''
+    },
+    shopName: {
+      type: String,
+      default: ''
+    }
+  },
+
+  setup(props, { emit, slots }) {
+    console.log(slots['origin']);
+
+    const isHaveSlot = (slot: string) => {
+      return slots[slot];
+    };
+
+    return {
+      isHaveSlot
+    };
+  }
+});
+</script>

+ 5 - 1
src/packages/styles/variables.scss

@@ -380,6 +380,10 @@ $sku-opetate-bg-buy: linear-gradient(
   rgba(255, 195, 13, 1) 69%,
   rgba(255, 207, 13, 1) 100%
 );
-
+// card
+$card-font-size-0: $font-size-0;
+$card-font-size-1: $font-size-1;
+$card-font-size-2: $font-size-2;
+$card-font-size-3: $font-size-3;
 @import './mixins/index';
 @import './animation/index';

+ 2 - 1
src/sites/mobile-taro/vue/src/app.config.ts

@@ -81,7 +81,8 @@ export default {
         'pages/signature/index',
         'pages/barrage/index',
         'pages/timeselect/index',
-        'pages/sku/index'
+        'pages/sku/index',
+        'pages/card/index'
       ]
     }
   ],

+ 4 - 0
src/sites/mobile-taro/vue/src/business/pages/card/index.config.js

@@ -0,0 +1,4 @@
+export default {
+  navigationBarTitleText: 'Card',
+  disableScroll: true
+};

+ 138 - 0
src/sites/mobile-taro/vue/src/business/pages/card/index.vue

@@ -0,0 +1,138 @@
+<template>
+  <view class="demo">
+    <h2>默认用法</h2>
+    <nut-card
+      :img-url="state.imgUrl"
+      :title="state.title"
+      :price="state.price"
+      :vipPrice="state.vipPrice"
+      :shopDesc="state.shopDesc"
+      :delivery="state.delivery"
+      :shopName="state.shopName"
+    >
+    </nut-card>
+    <h2>自定义商品标签</h2>
+    <nut-card
+      :img-url="state.imgUrl"
+      :title="state.title"
+      :price="state.price"
+      :vipPrice="state.vipPrice"
+      :shopDesc="state.shopDesc"
+      :delivery="state.delivery"
+      :shopName="state.shopName"
+    >
+      <template #prolist>
+        <div class="search_prolist_attr">
+          <span class="word">活鲜</span>
+          <span class="word">礼盒</span>
+          <span class="word">国产</span>
+        </div>
+      </template>
+    </nut-card>
+    <h2>价格后自定义标签</h2>
+    <nut-card
+      :img-url="state.imgUrl"
+      :title="state.title"
+      :price="state.price"
+      :vipPrice="state.vipPrice"
+      :shopDesc="state.shopDesc"
+      :delivery="state.delivery"
+      :shopName="state.shopName"
+    >
+      <template #prolist>
+        <div class="search_prolist_attr">
+          <span class="word">活鲜</span>
+          <span class="word">礼盒</span>
+          <span class="word">国产</span>
+        </div>
+      </template>
+      <template #tag>
+        <img
+          class="tag"
+          src="//img11.360buyimg.com/jdphoto/s58x28_jfs/t9451/359/415622649/15318/b0943e5d/59a78495N3bd2a9f8.png"
+          alt=""
+        />
+      </template>
+    </nut-card>
+    <h2>商家介绍自定义</h2>
+    <nut-card
+      :img-url="state.imgUrl"
+      :title="state.title"
+      :price="state.price"
+      :vipPrice="state.vipPrice"
+      :shopDesc="state.shopDesc"
+      :delivery="state.delivery"
+      :shopName="state.shopName"
+    >
+      <template #shop-tag>
+        <div>这里是自定义区域</div>
+      </template>
+    </nut-card>
+    <h2>自定义右下角内容</h2>
+    <nut-card
+      :img-url="state.imgUrl"
+      :title="state.title"
+      :price="state.price"
+      :vipPrice="state.vipPrice"
+      :shopDesc="state.shopDesc"
+      :delivery="state.delivery"
+      :shopName="state.shopName"
+    >
+      <template #footer>
+        <div class="customize">自定义</div>
+      </template>
+    </nut-card>
+  </view>
+</template>
+
+<script lang="ts">
+import { reactive } from '@vue/reactivity';
+
+export default {
+  setup() {
+    const state = reactive({
+      imgUrl:
+        '//img10.360buyimg.com/n2/s240x240_jfs/t1/210890/22/4728/163829/6163a590Eb7c6f4b5/6390526d49791cb9.jpg!q70.jpg',
+      title: '活蟹】湖塘煙雨 阳澄湖大闸蟹公4.5两 母3.5两 4对8只 鲜活生鲜螃蟹现货水产礼盒海鲜水',
+      price: '388',
+      vipPrice: '378',
+      shopDesc: '自营',
+      delivery: '厂商配送',
+      shopName: '阳澄湖大闸蟹自营店>'
+    });
+    return {
+      state
+    };
+  }
+};
+</script>
+
+<style lang="scss">
+.search_prolist_attr {
+  margin: 3px 0 1px;
+  height: 15px;
+  overflow: hidden;
+  > span {
+    float: left;
+    padding: 0 5px;
+    border-radius: 1px;
+    font-size: 10px;
+    height: 15px;
+    line-height: 15px;
+    color: #999;
+    background-color: #f2f2f7;
+    margin-right: 5px;
+  }
+}
+.tag {
+  display: inline-block;
+  vertical-align: middle;
+  margin-right: 5px;
+  margin-left: 2px;
+  height: 14px;
+  width: 28px;
+}
+.customize {
+  font-size: 12px;
+}
+</style>