基于vue的ui组件库开发—— 02

前言

上一个篇章中我们学习基础的框架搭建,并且实现了一个简单的 button组件,该组件可以在项目中正常使用,那么按照类似的方法可以哦我们呢可以开发其他常用的组件库。

1. icon组件

icon 组件主要用来引用各种图标,在此之前我们需要知道图标是如何引入到我们自己的组件库中的。我们通过@font-face 的 CSS @规则引入图标字体。使用例子如下,需要注意的是字体格式有太多选择(例如:woff 、ttf、svg等等),不幸的是始终没有一个能在所有的浏览器上通用。这意味着我们必须使用多种字体的方案来保持用户跨平台的一致性体验

// 定义图标字体
@font-face {
  font-family: 'askbob-iconfont';
  src: url('fonts/wbs-icon.woff2?t=1566356524042') format('woff2'), 
      url('fonts/wbs-icon.woff?t=1566356524042') format('woff'), 
      url('fonts/wbs-icon.ttf?t=1566356524042') format('truetype'),
      url('fonts/wbs-icon.svg?t=1566356524042#wbs-iconfont') format('svg');
}

// css引用
[class*='askbob-icon-'],
[class^='askbob-icon-'] {
  ...
  font-family: 'askbob-iconfont' !important;
  ...
}

ok,在知晓上面图标引用规则的的前提下,我们再来开发icon 组件,首先是 icon.vue 的开发:

// icon.vue
<template>
  <i :class="currentClass" :style="styles" @click="click"></i>
</template>

<script>
export default {
  name: `askbob-icon`,

  props: {
    type: String,
    color: String,
    size: String,
  },
  computed: {
    currentClass() {
      return this.type ? `askbob-icon-` + this.type : '';
    },
    styles() {
      let stl = ``;
      if (this.color) stl = stl + `color: ${this.color};`;
      if (this.size) stl = stl + `font-size: ${this.size}px;`;
      return stl;
    },
  },
  methods: {
    click(e) {
      this.$emit('click', e);
    },
  },
};
</script>

上述代码中,可以看到icon组件通过透传属性type控制图标的类型;通过透传属性 color控制图标的颜色;通过透传属性 size 控制图标的大小。css代码如下,其中 @icon-size定义了默认的图标大小变量。

// index.less
@import '../style/theme.less';
@font-face {
  font-family: 'askbob-iconfont';
  src: url('fonts/wbs-icon.woff2?t=1566356524042') format('woff2'), 
      url('fonts/wbs-icon.woff?t=1566356524042') format('woff'), 
      url('fonts/wbs-icon.ttf?t=1566356524042') format('truetype'),
      url('fonts/wbs-icon.svg?t=1566356524042#wbs-iconfont') format('svg');
}
// 图标变量
@icon-size: 20px;

[class*='askbob-icon-'],
[class^='askbob-icon-'] {
  font-family: 'askbob-iconfont' !important;
  font-size: @icon-size;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  display: inline-block;
  vertical-align: middle;
}

.askbob-icon-setting:before {
  content: '\e603';
}

.askbob-icon-close:before {
  content: '\e60a';
}

.askbob-icon-back:before {
  content: '\e60b';
}

.askbob-icon-right:before {
  content: '\e60c';
}

.askbob-icon-left:before {
  content: '\e60d';
}

.askbob-icon-up:before {
  content: '\e60e';
}

.askbob-icon-down:before {
  content: '\e60f';
}

.askbob-icon-subtract:before {
  content: '\e612';
}

.askbob-icon-add:before {
  content: '\e613';
}

.askbob-icon-circle:before {
  content: '\e618';
}

.askbob-icon-help:before {
  content: '\e61c';
}

.askbob-icon-wrong:before {
  content: '\e61d';
}

.askbob-icon-info:before {
  content: '\e61e';
}

.askbob-icon-close-circle:before {
  content: '\e61f';
}

.askbob-icon-success:before {
  content: '\e620';
}

.askbob-icon-add-circle:before {
  content: '\e622';
}

.askbob-icon-subtract-circle:before {
  content: '\e623';
}

.askbob-icon-selected:before {
  content: '\e626';
}

.askbob-icon-refresh:before {
  content: '\e628';
}

.askbob-icon-more:before {
  content: '\e629';
}

.askbob-icon-search:before {
  content: '\e62a';
}

.askbob-icon-nav-more:before {
  content: '\e62b';
}

.askbob-icon-delete:before {
  content: '\e62c';
}

.askbob-icon-warning:before {
  content: '\e62e';
}

导出icon 组件,新增 index.js文件:

import Icon from './icon.vue';
export default Icon;
2. 导航栏组件开发

前面的都是相对来说功能单一,简单的组件,此处我们开发一个导航栏组件,导航栏组件是一个相对来说功能较复杂的组件,一般的导航栏包含:返回按钮、标题显示、搜索按钮、分享按钮等小模块,当涉及到如此多的小模块时候,肯定是需要在导航栏组件中设置插槽位置。

如下代码是导航栏组件的代码实现,代码布局整体上可以分为三个模块:

  1. askbob-navbar-left中通过透传的isBack参数控制返回按钮的现实和隐藏,通过isLeftContent控制左侧文字展示或者隐藏;
  2. askbob-navbar-title中通过插槽控标题内容
  3. askbob-navbar-right也是通过具名插槽控制右侧的相关文字或者按钮
// nav-bar.vue
<template>
  <div :class="{ [`askbob-navbar`]: true, [`askbob-navbar-border-bottom`]: borderBottom }">
    <div :class="`askbob-navbar-left`" role="button">
      <div :class="`askbob-navbar-left-icon`" @click="clickBack" v-if="isBack">
        <slot name="icon">
          <Icon type="back"></Icon>
        </slot>
      </div>
      <div :class="{ [`askbob-navbar-left-content`]: true, ml: !isBack }" @click="leftContentlick" v-if="isLeftContent">
        <slot name="leftContent">{{ leftContent }}</slot>
      </div>
    </div>
    <div :class="`askbob-navbar-title`">
      <slot></slot>
    </div>
    <div :class="`askbob-navbar-right`">
      <slot name="rightContent"></slot>
    </div>
  </div>
</template>
<script>
import Icon from '../icon/icon.vue';
export default {
  name: `askbob-nav-bar`,
  components: {
    Icon,
  },
  props: {
    isBack: {
      type: Boolean,
      default: true,
    },
    leftContent: {
      type: String,
    },
    borderBottom: {
      type: Boolean,
      default: false,
    },
  },
  computed: {
    isLeftContent() {
      return this.$slots.leftContent !== undefined || !!this.leftContent;
    },
  },
  methods: {
    clickBack(e) {
      this.$emit('leftClick', e);
    },
    leftContentlick(e) {
      this.$emit('leftContentClick', e);
    },
  }
};
</script>

以下是对应的css代码,其中定义了相关变量参数,例如:@navbar-height、 @navbar-fill、 @navbar-font-size、 @navbar-icon-font-size 等。

// index.less
@import '../style/theme.less';
@import '../style/hairline.less';

// nav bar相关变量
@navbar-height: 44px;
@navbar-fill: #f3f3f3;
@navbar-font-size: 20px;
@navbar-icon-font-size: 15px;

.askbob-navbar {
  position: relative;
  display: flex;
  align-items: center;
  height: @navbar-height;
  background-color: @navbar-fill;
  color: @color-font;

  &-left,
  &-title,
  &-right {
    flex: 1;
    height: 100%;
    display: flex;
    align-items: center;
    i {
      margin-right: @spacing-margin-base;
      &:last-child {
        margin-right: 0;
      }
    }
  }
  &-left {
    &-icon {
      display: flex;
      justify-content: center;
      align-items: center;
      height: @navbar-height;
      width: @navbar-height;
      i {
        font-size: @navbar-icon-font-size;
        // font-weight: bolder;
        display: inherit;
      }
    }
    &-content {
      height: @navbar-height;
      line-height: @navbar-height;
      i {
        font-size: @navbar-icon-font-size;
        // font-weight: bolder;
        display: inherit;
      }
    }
  }
  &-title {
    justify-content: center;
    font-size: @navbar-font-size;
    white-space: nowrap;
  }

  &-right {
    justify-content: flex-end;
    font-size: @navbar-font-size;
    margin-right: @spacing-margin-base;
  }
  // &-border-bottom {
  //   .hairline('bottom');
  // }
  .ml {
    margin-left: @spacing-margin-base;
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值