本篇文章记录一下,仿写一个el-card组件,有助于大家更好了解,饿了么ui的轮子具体工作细节。本文是elementui源码学习仿写系列的又一篇文章,后续闲暇了会不断更新并仿写其余组件。源码在github上,大家能够拉下来,npm start运行跑起来,联合正文有助于更好的了解。github仓库地址如下:https://github.com/shuirongsh...

集体愚见

对于卡片card组件,个别在应用中,次要还是card的交互成果,比方暗影成果。饿了么官网提供的card组件除了通过传参管制暗影呈现的机会,额定还提供了一个卡片头部插槽。好是好,不过个别用不到,因为卡片内容基本上都是本人写的,如果还应用头部插槽,可能须要多一些/deep/ 去管制款式,倒不如本人改写封装一个

自己看了饿了么el-card组件当前,也封装了一个my-card组件,没有退出原有的头部插槽#header,不过多加了一些交互成果,整体有以下成果:

  • 暗影呈现的机会(原有性能)

    • 鼠标悬浮呈现
    • 总是呈现
    • 不呈现
  • 鼠标悬浮卡片稍微上移
  • 鼠标悬浮卡片放大一些
  • 鼠标悬浮卡片反转(即多了一个slot="back"的插槽用于传递反面的内容)
  • 以及管制侧面、反面的款式变量cardStylebackCardStyle

咱们先看一下效果图

效果图

大家有什么好的录制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哦
  • 因为是系列文章,您的激励是咱创作的能源^_^