Browse Source

feat: 新增 Tag 组件

wangchunyu11 5 years ago
parent
commit
c08fa76e10

+ 10 - 0
src/config.json

@@ -358,6 +358,16 @@
       "sort": "6",
       "showDemo": true,
       "author": "yangxiaolu"
+    },
+    {
+      "version": "1.0.0",
+      "name": "Tag",
+      "chnName": "标签",
+      "desc": "Tag 标签组件",
+      "type": "component",
+      "sort": "0",
+      "showDemo": true,
+      "author": "ivanwancy"
     }
   ]
 }

+ 4 - 1
src/nutui.js

@@ -74,6 +74,8 @@ import SideNavBarItem from './packages/sidenavbaritem/index.js';
 import './packages/sidenavbaritem/sidenavbaritem.scss';
 import Address from './packages/address/index.js';
 import './packages/address/address.scss';
+import Tag from './packages/tag/index.js';
+import './packages/tag/tag.scss';
 
 const packages = {
   Cell,
@@ -113,7 +115,8 @@ const packages = {
   SideNavBar: SideNavBar,
   SubSideNavBar: SubSideNavBar,
   SideNavBarItem: SideNavBarItem,
-  Address: Address
+  Address: Address,
+  Tag: Tag
 };
 
 const components = {};

+ 93 - 0
src/packages/tag/__test__/tag.spec.js

@@ -0,0 +1,93 @@
+import { shallowMount, mount } from '@vue/test-utils'
+import Tag from '../tag.vue';
+import Vue from 'vue';
+
+describe('Tag.vue', () => {
+    let wrapper = shallowMount(Tag, {
+        slots: {
+            default: '标签'
+        }
+    });
+    it('设置 color 基础样式: blue', () => {
+        wrapper.setProps({
+            color: 'blue'
+        })
+        return Vue.nextTick().then(function () {
+            expect(wrapper.attributes('class')).toContain('blue');
+        })
+    });
+    it('设置 color 基础样式: green', () => {
+        wrapper.setProps({
+            color: 'green'
+        })
+        return Vue.nextTick().then(function () {
+            expect(wrapper.attributes('class')).toContain('green');
+        })
+    });
+    it('设置 color 基础样式: jc-blue', () => {
+        wrapper.setProps({
+            color: 'jc-blue'
+        })
+        return Vue.nextTick().then(function () {
+            expect(wrapper.attributes('class')).toContain('jc-blue');
+        })
+    });
+    it('设置 color 基础样式: orange', () => {
+        wrapper.setProps({
+            color: 'orange'
+        })
+        return Vue.nextTick().then(function () {
+            expect(wrapper.attributes('class')).toContain('orange');
+        })
+    });
+    it('设置slot', () => {
+        return Vue.nextTick().then(function () {
+            expect(wrapper.text()).toBe('标签');
+        })
+    });
+    it('设置disabled', () => {
+        wrapper.setProps({
+            disabled: true
+        })
+        return Vue.nextTick().then(function () {
+            expect(wrapper.text()).toBe('标签');
+            expect(wrapper.attributes('class')).toContain('disabled');
+        })
+    });
+    it('设置circle', () => {
+        wrapper.setProps({
+            circle: true
+        })
+        return Vue.nextTick().then(function () {
+            expect(wrapper.text()).toBe('标签');
+            expect(wrapper.attributes('class')).toContain('circle');
+        })
+    });
+    it('设置hollow', () => {
+        wrapper.setProps({
+            hollow: true
+        })
+        return Vue.nextTick().then(function () {
+            expect(wrapper.text()).toBe('标签');
+            expect(wrapper.attributes('class')).toContain('hollow');
+        })
+    });
+    it('设置 size: big', () => {
+        wrapper.setProps({
+            size: 'big'
+        })
+        return Vue.nextTick().then(function () {
+            expect(wrapper.text()).toBe('标签');
+            expect(wrapper.attributes('class')).toContain('big');
+        })
+    });
+    it('设置 size: middle', () => {
+        wrapper.setProps({
+            size: 'middle'
+        })
+        return Vue.nextTick().then(function () {
+            expect(wrapper.text()).toBe('标签');
+            expect(wrapper.attributes('class')).toContain('middle');
+        })
+    });
+});

+ 83 - 0
src/packages/tag/demo.vue

@@ -0,0 +1,83 @@
+<template>
+  <div>
+    <h4>基础样式</h4>
+    <div class="white-bg">
+      <!-- green, orange, yellow, blue, purple -->
+      <nut-tag>标签</nut-tag>
+      <nut-tag color="jc-blue">标签</nut-tag>
+      <nut-tag color="orange">标签</nut-tag>
+      <nut-tag color="yellow">标签</nut-tag>
+      <nut-tag color="green">标签</nut-tag>
+      <nut-tag color="blue">标签</nut-tag>
+      <nut-tag color="purple">标签</nut-tag>
+      <nut-tag disabled>标签</nut-tag>
+    </div>
+    <h4>圆角样式</h4>
+    <div class="white-bg">
+      <!-- green, orange, yellow, blue, purple -->
+      <nut-tag circle>标签</nut-tag>
+      <nut-tag circle color="jc-blue">标签</nut-tag>
+      <nut-tag circle color="orange">标签</nut-tag>
+      <nut-tag circle color="yellow">标签</nut-tag>
+      <nut-tag circle color="green">标签</nut-tag>
+      <nut-tag circle color="blue">标签</nut-tag>
+      <nut-tag circle color="purple">标签</nut-tag>
+      <nut-tag circle disabled>标签</nut-tag>
+    </div>
+    <h4>自定义颜色</h4>
+    <div class="white-bg">
+      <nut-tag :style="{background: '#FCE9E8', color: '#E1251B'}">标签</nut-tag>
+      <nut-tag :style="{background: '#EBF0FD', color: '#3C6EF0'}">标签</nut-tag>
+      <nut-tag :style="{background: '#FFF0ED', color: '#FF8B70'}">标签</nut-tag>
+      <nut-tag :style="{background: '#FFF8E7', color: '#FFBA12'}">标签</nut-tag>
+      <nut-tag :style="{background: '#E9F6F0', color: '#26A872'}">标签</nut-tag>
+      <nut-tag :style="{background: '#E9F6FC', color: '#2CA6E1'}">标签</nut-tag>
+      <nut-tag :style="{background: '#EFEAFF', color: '#6236FF'}">标签</nut-tag>
+      <nut-tag :style="{background: '#F7F7F7', color: '#7C7A8A'}">标签</nut-tag>
+    </div>
+    <h4>空心样式</h4>
+    <div class="white-bg">
+      <nut-tag hollow>标签</nut-tag>
+      <nut-tag hollow color="jc-blue">标签</nut-tag>
+      <nut-tag hollow color="orange">标签</nut-tag>
+      <nut-tag hollow color="yellow">标签</nut-tag>
+      <nut-tag hollow color="green">标签</nut-tag>
+      <nut-tag hollow color="blue">标签</nut-tag>
+      <nut-tag hollow color="purple">标签</nut-tag>
+      <nut-tag hollow disabled>标签</nut-tag>
+    </div>
+    <h4>标签大小</h4>
+    <div class="white-bg">
+      <nut-tag>标签</nut-tag>
+      <nut-tag size="middle">标签</nut-tag>
+      <nut-tag @click="clickHandler" size="big">标签</nut-tag>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      disabled: false
+    };
+  },
+  methods: {
+    clickHandler(e) {
+      console.log(e, '我点击了标签');
+      this.disabled = true;
+      setTimeout(() => {
+        this.disabled = false;
+      }, 2000);
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.white-bg {
+  padding: 10px;
+  background: #fff;
+  line-height: 1.6;
+}
+</style>

+ 249 - 0
src/packages/tag/doc.md

@@ -0,0 +1,249 @@
+# Tag 按钮
+
+## 基本用法 
+
+常规按钮
+
+```html
+<nut-tag 
+  @click="clickHandler"
+  :disabled='disabled'
+>
+  去结算
+</nut-tag>
+
+<nut-tag 
+  disabled
+>
+  去结算(disabled)
+</nut-tag>
+```
+
+```javascript
+export default {
+    data() {
+        return {
+            disabled: false
+        };
+    },
+    methods: {
+        clickHandler(e) {
+            // alert("我点击了按钮");
+            console.log(e, "我点击了按钮");
+            this.disabled = true;
+            setTimeout(() => {
+                this.disabled = false;
+            }, 2000);
+        }
+    }
+};
+```
+
+常规按钮-小
+
+```html
+<nut-tag 
+  small
+>
+  去结算
+</nut-tag>
+
+<nut-tag 
+  small 
+  disabled
+>
+  去结算(disabled)
+</nut-tag>
+```
+
+
+通栏按钮
+
+```html
+<nut-tag 
+  block
+>
+  登录
+</nut-tag>
+```
+
+通栏按钮-圆角
+
+```html
+<nut-tag 
+  block 
+  shape="circle"
+>
+  登录
+</nut-tag>
+```
+
+圆角按钮-常规Button
+
+```html
+<nut-tag 
+  type="red" 
+  shape="circle" 
+  small
+>
+  确认收货
+</nut-tag>
+
+<nut-tag 
+  type="gray" 
+  shape="circle" 
+  small
+>
+  查看物流
+</nut-tag>
+
+<nut-tag 
+  type="default" 
+  shape="circle" 
+  small
+>
+  再次购买
+</nut-tag>
+
+<nut-tag 
+  type="light" 
+  shape="circle" 
+  small
+>
+  降价通知
+</nut-tag>
+```
+
+圆角按钮-标签Button
+
+```html
+<nut-tag
+  type="primary" 
+  shape="circle" 
+  small
+>
+  京东快递
+</nut-tag>
+
+<nut-tag 
+  type="lightred" 
+  shape="circle" 
+  small
+>
+  好评 6.6万
+</nut-tag>
+
+<nut-tag 
+  type="actived" 
+  shape="circle" 
+  icon="tick" 
+  small
+>
+  全部 100万
+</nut-tag>
+```
+
+图标按钮-小
+
+```html 
+<nut-tag 
+  type="actived" 
+  shape="circle" 
+  icon="tick" 
+  small
+>
+</nut-tag>
+```
+
+图标按钮-大
+
+```html 
+<nut-tag 
+  type="actived" 
+  shape="circle" 
+  icon="tick"
+>
+</nut-tag>
+```
+
+圆角按钮-商品属性选择Button
+
+```html
+<nut-tag 
+  type="actived" 
+  shape="circle" 
+  small
+>
+  象牙白
+</nut-tag>
+
+<nut-tag 
+  type="light" 
+  shape="circle" 
+  small
+>
+  皓月灰
+</nut-tag>
+
+<nut-tag 
+  type="dashed" 
+  shape="circle" 
+  small
+>
+  晶钻蓝
+</nut-tag>
+```
+
+自定义颜色
+
+```html
+<nut-tag 
+  type="actived" 
+  shape="circle" 
+  small 
+  color="#fff"
+>
+  象牙白
+</nut-tag>
+
+<nut-tag 
+  type="primary" 
+  shape="circle" 
+  small 
+  color="rgb(0,0,0)"
+>
+  象牙白
+</nut-tag>
+
+<nut-tag 
+  type="actived" 
+  shape="circle" 
+  icon="tick" 
+  color="rgb(0,0,0)" 
+  small
+>
+</nut-tag>
+
+<nut-tag 
+  type="actived" 
+  shape="circle" 
+  icon="tick" 
+  color="rgb(0,0,0)" 
+  small
+>
+  全部 100万
+</nut-tag>
+      
+```
+
+
+## Prop
+
+| 字段  | 说明                                                                                      | 类型    | 默认值 |
+| ----- | ----------------------------------------------------------------------------------------- | ------- | ------ |
+| type  | 按钮类型,可选类型包含:空、red、gray、light、lightred、primary、default、actived、dashed | String  | -      |
+| block | 是否为通栏                                                                                | Boolean | false  |
+| small | 是否为小号组件                                                                            | Boolean | false  |
+| shape | 形状配置,可选类型:空、circle                                                            | String  | -      |
+| icon  | 按钮前的图标,参考Icon组件                                                                | String  | -      |
+| color | 自定义颜色,包含文字与图片颜色                                                            | String  | -      |

+ 9 - 0
src/packages/tag/index.js

@@ -0,0 +1,9 @@
+import Tag from './tag.vue';
+
+import './tag.scss';
+
+Tag.install = function (Vue) {
+  Vue.component(Tag.name, Tag);
+};
+
+export default Tag;

+ 71 - 0
src/packages/tag/tag.scss

@@ -0,0 +1,71 @@
+
+@mixin tagColor($color, $hollow) {
+  @if ($hollow == true) {
+    border: $border-width-base solid $color;
+    color: $color;
+    background-color: transparent;
+  } @else {
+    background-color: $color;
+    color: #fff;
+  }
+}
+
+$colors: 'orange' 'yellow' 'green' 'blue' 'purple' 'jc-blue';
+$colorlist: $assist-color-orange $assist-color-yellow $assist-color-green $assist-color-blue $assist-color-purple $primary-color-jc-blue;
+
+.nut-tag {
+  cursor: pointer;
+  height: $tag-height-small;
+  padding: 0 9px;
+  font-size: $font-size-small;
+  border: none;
+  outline: none;
+  border-radius: $tag-border-radius;
+  box-sizing: border-box;
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  // min-width: 42px;
+  width: 42px;
+
+  @include text-ellipsis();
+
+  // 默认 京东红
+  @include tagColor($primary-color-jd-red, false);
+
+  &.hollow {
+    @include tagColor($primary-color-jd-red, true);
+  }
+  
+  // 京牛蓝 jc-blue 其它颜色枚举:orange yellow green blue purple
+  @for $i from 1 to length($colors) + 1 {
+    &.#{nth($colors, $i)} {
+      @include tagColor(nth($colorlist, $i), false);
+      &.hollow {
+        @include tagColor(nth($colorlist, $i), true);
+      }
+    }
+  }
+
+  // disabled 状态颜色
+  &.disabled {
+    @include tagColor($assist-color-light-gray, false);
+
+    &.hollow {
+      @include tagColor($assist-color-gray, true);
+    }
+  }
+
+  // size-中号
+  &.middle {
+    height: $tag-height-middle;
+  }
+  // size-大号
+  &.big {
+    height: $tag-height-big;
+  }
+  // circle-圆角
+  &.circle {
+    border-radius: $tag-border-radius-circle;
+  }
+}

+ 50 - 0
src/packages/tag/tag.vue

@@ -0,0 +1,50 @@
+<template>
+  <div :class="clsStyle" @click="clickHandler">
+    <slot></slot>
+  </div>
+</template>
+<script>
+export default {
+  name: 'nut-tag',
+  props: {
+    size: {
+      type: String,
+      default: 'small' // [small, middle, big]
+    },
+    disabled: {
+      type: Boolean,
+      default: false
+    },
+    circle: {
+      type: Boolean,
+      default: false
+    },
+    hollow: {
+      type: Boolean,
+      default: false
+    },
+    color: {
+      type: String,
+      default: 'red' // [red, jc-blue, green, orange, yellow, blue, purple]
+    }
+  },
+  computed: {
+    clsStyle() {
+      let cls = `nut-tag ${this.color} ${this.size}
+            ${this.circle ? ' circle' : ''}
+            ${this.disabled ? ' disabled' : ''}
+            ${this.hollow ? ' hollow' : ''}`;
+      return cls;
+    }
+  },
+  methods: {
+    clickHandler(event) {
+      // 如果是 disabled 就阻止点击
+      if (this.disabled) {
+        return;
+      }
+      this.$emit('click', event);
+    }
+  }
+};
+</script>

+ 8 - 0
src/styles/variable.scss

@@ -117,3 +117,11 @@ $assetsPath: '../../assets' !default;
 $stepper-color: #333 !default;
 $stepperbar-width: 11px !default;
 $stepperbar-color: #333 !default;
+
+// ---- Tag ----
+$tag-height-small: 20px !default;
+$tag-height-middle: 22px !default;
+$tag-height-big: 24px !default;
+$tag-border-radius: 2px !default;
+$tag-border-radius-circle: 10px !default;
+