本篇文章记录一下,仿写一个el-card组件,有助于大家更好了解,饿了么ui的轮子具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在github上,大家能够拉下来,npm start运行跑起来,联合正文有助于更好的了解。github仓库地址如下:https://github.com/shuirongsh...
集体愚见
对于卡片card
组件,个别在应用中,次要还是card
的交互成果,比方暗影成果。饿了么官网提供的card
组件除了通过传参管制暗影呈现的机会,额定还提供了一个卡片头部插槽。好是好,不过个别用不到,因为卡片内容基本上都是本人写的,如果还应用头部插槽,可能须要多一些/deep/
去管制款式,倒不如本人改写封装一个
自己看了饿了么el-card
组件当前,也封装了一个my-card
组件,没有退出原有的头部插槽#header,不过多加了一些交互成果,整体有以下成果:
暗影呈现的机会(原有性能)
- 鼠标悬浮呈现
- 总是呈现
- 不呈现
- 鼠标悬浮卡片稍微上移
- 鼠标悬浮卡片放大一些
- 鼠标悬浮卡片反转(即多了一个
slot="back"
的插槽用于传递反面的内容) - 以及管制侧面、反面的款式变量
cardStyle
和backCardStyle
咱们先看一下效果图
效果图
大家有什么好的录制gif软件能够分享我一下哦。我的这个软件录制进去的gif成果不太好。
组件中所用到的低频知识点
perspective
属性:示意咱们看到的与z=0立体的间隔,能够做三维地位变换透视成果
官网:https://developer.mozilla.org...
backface-visibility:hidden
属性:指定当元素反面朝向观察者时藏起来
官网:https://developer.mozilla.org...
实现思路就是将两个要展现的div利用定位重叠在一起,其中一个首先围绕Y轴旋转肯定角度,而后搭配backface-visibility:hidden
先藏起啦。鼠标悬浮的时候,整个旋转,就呈现不可见到可见的一个成果啦,翻转动画就有喽
this.$slots
属性:寄存插槽的对象,能够存命名插槽、或者default一般插槽。
比方外界传递<div slot="back">反面的内容</div>
那么console.log("this.$slots", this.$slots);
就能够看到是否传递进来插槽了。本例中可用于判断是否开启翻转卡片模式,而后通过:class
的数组用法来动静增加类名,即可实现上述效果图
大家打印一下就明确,这个很简略。
应用组件的代码
<template> <div class="box"> <my-card class="cardClass" shadow="hover">悬浮出暗影</my-card> <my-card class="cardClass" shadow="always">始终出暗影</my-card> <my-card class="cardClass" shadow="none">没有暗影</my-card> <my-card class="cardClass" shadow="hover" isHoverUp>悬浮出暗影上移</my-card> <my-card class="cardClass" shadow="always" isHoverUp>始终出暗影上移</my-card> <my-card class="cardClass" shadow="none" isHoverUp>没有暗影上移</my-card> <my-card class="cardClass" shadow="hover" zoomCard>悬浮出暗影放大</my-card> <my-card class="cardClass" shadow="always" zoomCard>始终出暗影放大</my-card> <my-card class="cardClass" shadow="none" zoomCard>没有暗影放大</my-card> <my-card class="cardClass" :cardStyle="{ padding: 0 }" shadow="hover" >应用cardStyle去管制款式,比方这里革除内边距</my-card > <my-card class="cardClass cardClass2" :cardStyle="{ background: 'pink' }" :backCardStyle="{ background: '#baf' }" >悬浮卡片翻转(侧面) <!-- 当有命名插槽back的时候,主动开启翻转模式 --> <div slot="back">反面的内容</div> </my-card> </div></template><style lang='less' scoped>.box { display: flex; flex-wrap: wrap; box-sizing: border-box; padding: 24px; .cardClass { width: 240px; margin-right: 24px; margin-bottom: 24px; } .cardClass2 { height: 180px; }}</style>
封装的组件代码
<template> <div :class="[ 'card-box', this.$slots.back ? 'card-reverse' : '', zoomCard ? 'card-box-zoom' : '', ]" > <div class="card-content"> <!-- 当有back命名插槽时,加上frontReverse类名并移除front-side类名,才有反转成果 --> <div :style="cardStyle" :class="[ this.$slots.back ? 'frontReverse' : 'front-side', shadow, isHoverUp ? 'isHoverUp' : '', ]" > <!-- 失常状况下一般插槽显示内容即可 --> <slot></slot> </div> <div :style="backCardStyle" class="backReverse" v-if="this.$slots.back"> <!-- 有命名插槽就显示命名插槽内容,并做类名移除和新增,开启翻转成果 --> <slot name="back" /> </div> </div> </div></template><script>const shadowArr = ["hover", "always", "none"]; // shadow="none"不传递也行的export default { name: "myCard", props: { cardStyle: {}, // 管制卡片(侧面的款式) backCardStyle: {}, // 管制反面卡片的款式 shadow: { // 暗影呈现机会:鼠标悬浮呈现、始终呈现、或不呈现 type: String, validator(val) { // 校验 if (shadowArr.includes(val)) return true; return false; }, }, isHoverUp: Boolean, // 是否悬浮往上平移一点 zoomCard: Boolean, // 是否放大卡片(hover时) }, mounted() { console.log("this.$slots", this.$slots); },};</script><style lang="less" scoped>.card-box { // background-color: #fff; /* 留神卡片盒子不能加背景色,会挡住旋转款式成果 */ color: #333; perspective: 1000; transform-style: preserve-3d; transition: all 0.4s;}// 加card-box-zoom类名,就整体放大1.08倍.card-box-zoom:hover { transform: scale(1.08);}// 直达的用于定位的容器盒子.card-content { position: relative; width: 100%; height: 100%; transition: 0.75s; transform-style: preserve-3d;}/* 应用front-side类名管制一般状态时的款式 */.front-side { box-sizing: border-box; padding: 18px; border-radius: 4px; border: 1px solid #e9e9e9; transition: 0.3s;}// 有hover类名时,在hover时,就加暗影.hover:hover { box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);}// 有isHoverUp类名时,就在hover时往上挪动一点.isHoverUp:hover { transform: translateY(-3px);}// 有always类名时,就加暗影.always { box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);}/* 应用frontReverse和backReverse类名专门管制卡片反转状态时的款式 */.frontReverse, // 利用定位使前前面重叠.backReverse { position: absolute; top: 0; left: 0; right: 0; bottom: 0; backface-visibility: hidden; transform-style: preserve-3d; box-sizing: border-box; padding: 18px; border-radius: 4px; border: 1px solid #e9e9e9; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);}.frontReverse { z-index: 2; // 后面层级贬低}.backReverse { transform: rotateY(-180deg); // 前面旋转不可见}.card-reverse:hover .card-content { // hover时候,旋转容器,就会呈现,不可见到可见的过程了,翻转动画就有了 transform: rotateY(180deg);}</style>
至于css兼容性的话,大家能够本人加上浏览器厂商的后缀呗
总结
- 复制粘贴,即可呈现成果。
- 如果对您有一点点帮忙,欢送github给个star哦
- 因为是系列文章,您的激励是咱创作的能源
^_^