本集定位:
为何要叫1那, 由于我感受这个组件细节比较多, 应该会讲不少内容, 因此先把基础功能在这一集实现, 下集去作拓展.
button组件
这是一个基本上每一个工程都会用到的组件, 传统的button千篇一概的样式, 仿佛按钮不作的同样就无法用似的, 我偏要加一些别人没加过的样式来玩, 作过项目的小伙伴都会遇到一个问题, 防抖与节流, 而这么主要的功能居然没有ui组件库的按钮来集成, 此次我就把这两个功能集成到按钮式搞一搞, 😁开始行动吧.
建立组件基本结构
继续秉承bem的思想, button整体结构以下:css
index.js文件 仍是老套路, 组件的name属性很重要.vue
import Button from './main/button.vue' Button.install = function(Vue) { Vue.component(Button.name, Button); }; export default Button
button.vuegit
<template> <button class="cc-button"> <slot /> </button> </template>
载体选用button原生标签, 不选择div标签去模拟, 由于button自己有不少原生属性, 并且语义化也要好过div. slot标签固然是为了接到用户在button中间输入的信息.github
按钮第一条, 固然是先分个类型开开胃数组
<template> <button class="cc-button" :class="[ type ? 'cc-button--' + type : '' ]" :type="nativeType" <slot /> </button> </template> <script> export default { name: "ccButton", props: { type: String, // 类型 nativeType: String, // 原生的类型仍是要给的 } }; </script>
1: vue的class属性很强大的, 他能够数组的形式, 字符串的形式, 对象的形式, 而我采用的是 数组套一切的形式, 接下来对象类型也会在这个class数组里面使用.
2: 原生的type也要接受, 由于用户会有这样的需求的, 我把它命名为nativeType,跟element同样.
3: 定义几种相应的type样式, 这个type属性没作校验, 由于就算用户不按照我给出的范围传值, 无非就是样式没变化, 没有其余影响的, 接下来就是定义按钮的type样式了.sass
Button.scss框架
@import './common/var.scss'; // 引入定义的全部变量 @import './common/mixin.scss'; // 引入全部的函数 @import './common/extend.scss'; // 引入公共样式 @include b(button) { cursor: pointer; // 鼠标变小手 align-items: center; // 轴对齐 display: inline-flex; // 开启flex模式, 因为还要保持行的特性, 因此是inline-flex vertical-align: middle; // 中对齐, 为了之后的icon准备的 justify-content: center; // 居中 background-color: white; // 白色 outline: 0; // 去掉聚焦时的轮廓 border-radius: 6px; // 感受圆角6仍是挺友好的, 没有作成可配置 transition: all 0.1s; // 动画固然要有, 交互体验很重要 &:active { // 点击的时候 box-shadow: none; // 嘿嘿这个是个人ui组件独有的风格 opacity: 0.7; // 微微一暗, 以示点击到了 transform: translateX(2px) translateY(2px) scale(0.9); // 会有个小小的位移 } &:hover { // 悬停变色 background-color:rgba(0,0,0,0.06) } @include commonShadow($--color-black); // 这个下面会说👇 @at-root { @include commonType(cc-button--) // 这个下面会说👇 }; }
var.scss文件,本项目采用的基本配色, 毕竟不是专业的你们见谅😁函数
// 基本色 $--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
!default;这个东西的意思是优先级最低, 能够被其余的顶掉.字体
mixin.scssflex
@mixin commonShadow($color) { @if $color== 'success' { $color: $--color-success; } @if $color== 'warning' { $color: $--color-warning; } @if $color== 'danger' { $color: $--color-danger; } @if $color== 'disabled' { cursor: not-allowed; $color: $--color-disabled; } color: $color; border: 1px solid $color; box-shadow: 2px 2px $color; } @mixin commonType($name) { @each $type in (success, warning, danger) { .#{$name}#{$type} { @include commonShadow($type); } } }
1: 先说commonShadow这个函数吧, 这个是本套ui框架的特点样式(惨不忍睹) , 就是想作点样子不同的, 这个函数很简单, 会根据传进来的不一样$color值来进行样式的返回, 只要使用这个函数就会为元素加上阴影效果, 注意@if后面不要习惯性的协商小括号
2: 因为样式不止一个, commonType函数应运而生, 他把我定义的几种样式类型以数组的形式进行循环,@each后面接的是每次循环出来的item, in 后面的()里面的是要被循环的量
3: .#{$name}#{$type}就是传进来的量与item的拼接, #{}就能够在sass里面进行拼接, 并非id的意思, 我传入的是 'cc-button--' 因此这个函数定义了 'cc-button--success', 'cc-button--warning','cc-button--danger' 三种样式加上了对应颜色的阴影效果, 如图
点击等更多效果能够来个人博客查看 哈哈😁;
@at-root
这个关键词没有使用过的小伙伴注意了
1: 这个关键词做用是, 使样式跳出{}大括号范围, 好比我在 cc-button这个class名下写的样式, 而后我用以下写法:
.cc-button{ .cc-button--success{} }
以上写法的意思是, .cc-button里面有个class为.cc-button--success的元素, 为这个元素赋予相应属性, 这显然不是我想要的,
.cc-button{ @at-root { .cc-button--success{} } }
至关于
.cc-button{ } .cc-button--success{ }
因此我说他至关与跳出{}大括号.
点击与disabled禁用属性
我把这个属性排在第二位来写, 由于有点击就有不可点击与其相对, 这属于的最基本的功能.
<button class="cc-button" @touchstart='touchstart($event)' :class="[ type ? 'cc-button--' + type : '', { 'is-disabled':disabled, }]" :type="nativeType" @click="$emit("click")"> <slot /> </button>
disabled: Boolean
禁用样式的属性Button.scss改装
&:not(.is-disabled) { &:active { box-shadow: none; opacity: 0.7; transform: translateX(2px) translateY(2px) scale(0.9); } &:hover { background-color:rgba(0,0,0,0.06) } } @include when(disabled) { @include commonShadow(disabled); }
1: 只有在不是禁用状态的时候, 才有点击效果, 悬停效果
2: 当disabled时, 才显示disabled的专属皮肤
when函数
@mixin when($state) { @at-root { &.#{$state-prefix + $state} { @content; } } }
1: 见名知意, 当什么什么的时候, 用到了@at-root 属性, 忘了的去上面看下, @content;表示的是类里面的样式内容,很神奇吧!
.box{ color:red; }
1: 上面的color:red; 就是@content;
2: 因此说这个函数就是一个命名函数, 能够抽象出前缀, 并且是在{}外的平级样式.
3: 禁用状态有cursor: not-allowed;属性, 让鼠标呈现禁用状态
左中右按钮 (文章字数写多了好卡)
<template> <button class="cc-button" @touchstart='touchstart($event)' :class="[ type ? 'cc-button--' + type : '', { 'is-left':left, 'is-right':right, 'is-centre':centre, 'is-disabled':disabled, }]" :type="nativeType" @click="click"> <slot /> </button> </template>
样式:
@include when(left) { border-radius: 16px 0 0 16px; } ; @include when(right) { border-radius: 0 16px 16px 0; } ; @include when(centre) { border-radius: 0; }
无非是调了一下圆角, 可是特别好玩
效果以下⬇️
按钮大小
这个不少ui库都有时间, 那我也实现一下吧, 感受通常般.
:class="[ sizeType, // 新加一个属性 type ? 'cc-button--' + type : '', { 'is-left':left, 'is-right':right, 'is-centre':centre, 'is-disabled':disabled, }]" props: { size: { typr: String, default: "normal" } } computed: { sizeType() { let sizeList = ["big", "small"]; if (sizeList.includes(this.size)) return "size-" + this.size; return "size-normal"; } }
&.size-big { font-size: $--size-big; padding: 6px 11px; } &.size-normal { font-size: $--size-nomal; padding: 4px 8px; } &.size-small { font-size: $--size-small; padding: 2px 6px; }
未完待续