本集定位:
这套ui组件我原本是先从button作的, 可是我发现每一个组件都要用到icon这个组件, 若是没有他, 不少组件无法扩展, 并且icon自己不依赖其余组件, 因此仍是先把它做为本篇文章的重点吧.
icon组件
读过element-ui源码的同窗都知道, 他们选择的是字体图标的方式来作icon组件的, 而个人这套ui在写法与用法上参考了他们的作法, 但组件自己是靠svg来书写的,其中的区别仍是简单阐述一下把.
icon font 与 svgcss
行动起来
上一集基本环境已经搭建好了, 这里咱们采用'bem'的思想, 来构建组件的样式, 全部的样式抽离在一个文件夹里面, 作到组件自己没有样式代码,咱们来先书写组件的代码.结构以下:html
index.js文件里面是导出这个组件:vue
import Icon from './main/icon.vue' // 明白vue.use方法原理的同窗都能明白这段代码的意义 // 当被use的时候, 进行icon组件的渲染 Icon.install = function(Vue) { Vue.component(Icon.name, Icon); }; export default Icon
这样单抽出来作一个文件的好处是,更好的工程化, 保证职能的单一性.git
main文件夹
为何main文件夹里面只有一个文件还要单独抽成一个文件夹??, 缘由是有的组件可能要配合本身独有的容器组件一块儿使用, 好比一个button的包裹容器, 他可让内部的每一个button有相同的上下左右距离, 相同的圆角等等...github
icon.vue文件面试
// 使用方法以下: <svg class="icon"> // 把名字写在下面的'xxx'处,就能够正常显示图标了; <use xlink:href="#icon-xxx"></use> </svg>
第四步: 开始正式书写组件.npm
<template> <div class='cc-icon' }"> <svg :style="{fill:color}"> <use :xlink:href='`#icon-${name}`'></use> </svg> </div> </template> <script> export default { name: "ccIcon", props: { color: String, name: { type: String, required: true } } }; </script>
props: {// 接受一个size属性 size: { // 由于用户可能传带单位的与不带单位的 type: [Number, String], default: "1em" } }, computed: { // 计算属性里面对这个值进行操做, 类型若是是数字, 就咱们来给他加上单位吧,也就是默认单位是'px' iconSize() { if (typeof this.size === "number") return this.size + "px"; else return this.size; } }
<template> <div class='cc-icon' height: iconSize, // 在此使用 width: iconSize, // 在此使用 }"> <svg :style="{fill:color}"> <use :xlink:href='`#icon-${name}`'></use> </svg> </div> </template>
<svg :style="{fill:color}" :class="[ 'cc-icon-'+name, { //icon-loading这个class名, 只有在icon的name属性里面有load字段的时候加上, 这个属性名里面的属性就是旋转.'~'位运算符是很高效的书写方式, 也就是对位求反,1变0,0变1,也就是求二进制的反码, 这里不懂的话, 先看犀牛书, 简单的说就是把-1转成0了, 变成了布尔中的false; 'icon-loading':~name.indexOf('load') } ]"> <use :xlink:href='`#icon-${name}`'></use> </svg>
<div class='cc-icon' :style="{ display: 'inline-flex', height: iconSize, width: iconSize, }">
<svg :style="{fill:color}" :class="[ 'cc-icon-'+name, { 'icon-loading':~name.indexOf('load'), 'is-disabled':disabled // 在这里进行了定义 } ]"> <use :xlink:href='`#icon-${name}`'></use> </svg> props: { disabled: Boolean // 固然是布尔类型 },
小知识点: props里面定义了默认类型是布尔,则用户能够直接在标签上写属性名, 不给属性值也是能够表明true的, 可是默认不是布尔, 不给属性值的话, 组件里面获得的就是undefined;element-ui
icon.scss文件 1:disabled状态时禁止点击 2:icon-loading 时旋转 @import './common/mixin.scss'; @import "./common/animation.scss"; @include b(icon) { .#{$state-prefix}disabled { cursor: not-allowed; fill: $--color-disabled; } .icon-loading { animation: rotating 1s infinite linear; } }
mixin.scss文件里面的b方法浏览器
抽象出$namespace方便管理 @mixin b($block) { $B: $namespace+'-'+$block !global; .#{$B} { @content; } }
animation.scss文件svg
@keyframes rotating { 0% { transform: rotateZ(0deg); } 100% { transform: rotateZ(360deg); } }
var.scss文件
// lulu的美工很差, 只是想作出点不一样样子的东西玩玩 // 基本色 $--color-black:#000000 !default; $--color-white:#FFFFFF !default; // 基本色鲜艳 $--color-nomal:#409EFF !default; $--color-success:#7CCD7C !default; $--color-warning:#FFB90F !default; $--color-danger: #FF0000 !default; $--color-disabled: #bbbbbb !default; $--color-difference: #F5F7FA !default; // 字体 $--size-big: 16px; $--size-nomal: 15px; $--size-small: 14px; // 输入框 $--color-input-placeholder:#aaa
点击下载到本地
取出js文件, 让在本地
用index.js文件引用这个js文件就完成了!!
结束
icon组件是最小的组件, 其余组件的代码量与难道都大的多, 详细code与用法能够访问下面的地址, npm同步更新!
下一期是关于button的,咱们一块儿交流吧