vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > Vue实现卡片翻转

Vue自定义指令实现卡片翻转功能

作者:傑丶

这篇文章主要给大家介绍了Vue自定义指令实现卡片翻转功能的代码示例,文章通过代码示例讲解的非常详细,对大家的学习或工作有一定的参帮助,需要的朋友可以参考下

效果预览

1 原理介绍

1.1 前置知识

backface-visibility

backface-visibility 是一个用于控制元素的背面是否可见的 CSS 属性。该属性通常用于在进行 3D 转换时,控制元素背面的可见性。

当元素进行 3D 转换时,其背面可能会变得可见,backface-visibility 属性就是用来控制这种可见性的。属性有两个可能的值:

如果设置了 backface-visibility: hidden; 盒子背面将不可见,把盒子绕 y 轴进行3d 旋转 180° 后,我们将看到盒子的背面。

backface-visibility 主要用于处理 3D 转换的情况,如果没有使用 3D 转换,该属性的效果可能不会显著。

transform-style: preserve-3d

transform-style: preserve-3d 主要用于配合 CSS 3D 变换,它告诉浏览器在进行 3D 变换时应该如何处理子元素。当给父元素应用 transform-style: preserve-3d 时,其子元素将以三维的方式定位,而不是被扁平化到同一个平面。

必须在父盒子上加上这个属性,因为这里是父盒子翻转带动子盒子,如果不加上这个属性,子盒子中的back背面将显示不出来!

1.2 步骤分析

首先你需要一个大盒子,里面包含两个小盒子,这里第一个小盒子为正面内容,第二个小盒子为反面内容。结构如下:

    <div class="card">
      <div class="front">front</div>
      <div class="back">back</div>
    </div>
      .card {
        height: 270px;
        width: 270px;
        margin: 40px auto;
        border: 1px solid #f00;
        position: relative;
      }
      .front,.back {
        width: 100%;
        height: 100%;
      }

      .front {
        background-image: url(./imgs/youli.png);
        background-repeat: no-repeat;
        background-size: cover;
      }

      .back {
        background-image: url(./imgs/erha.jpg);
        background-repeat: no-repeat;
        background-size: cover;
      }

加上上面样式后得到如下效果:

上面的效果显然不满足翻转卡片的前置条件,思考一下我们想要达到的效果:

完整代码如下:

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>卡片旋转效果</title>
    <style>

      .card {
        height: 270px;
        width: 270px;
        margin: 40px auto;
        border: 1px solid #f00;
        position: relative;

        transform-style: preserve-3d;
        transition: transform 0.5s;
        perspective: 0px;
      }

      .card.flipped {
        transform: rotateY(180deg);
      }

      .front,.back {
        width: 100%;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
      }

      .front {
        background-image: url(./imgs/youli.png);
        background-repeat: no-repeat;
        background-size: cover;

        backface-visibility: hidden;
        transform: rotateY(0deg);
      }

      .back {
        background-image: url(./imgs/erha.jpg);
        background-repeat: no-repeat;
        background-size: cover;

        transform: rotateY(180deg);
        backface-visibility: hidden;
      }
    </style>
  </head>
  <body>
    <div class="card">
      <div class="front">front</div>
      <div class="back">back</div>
    </div>

    <script>
      const card = document.querySelector('.card')
      card.addEventListener('click', function() {
        this.classList.toggle('flipped')
 
      })
    </script>
  </body>
</html>

2 用 Vue 自定义指令实现卡片翻转

这里自定义指令的用法就不再介绍了,直接贴上实现代码:

Vue.directive('flip', {
    bind: function (el, binding) {
        // console.log('bind', el.children.length, binding.value)
        el.style.position = 'relative'
        el.style.transformStyle = 'preserve-3d'
        el.style.transition = 'transform 0.5s'

        el.initChidren = (el, binding) => {
          // console.log(el.children.length)
          if (el.children.length !== 2) {
            return
          }

          if (binding.value) {
            el.style.transform = 'rotateY(180deg)'
          } else {
            el.style.transform = 'rotateY(0deg)'
          }

          for (let i = 0; i < el.children.length; i++) {
            const element = el.children[i]
            element.style.position = 'absolute'
            element.style.position = 'absolute'
            element.style.width = '100%'
            element.style.height = '100%'
            element.style.left = 0
            element.style.top = 0
            if (i === 0) {
              element.style.backfaceVisibility = 'hidden'
              element.style.transform = 'rotateY(0deg)'
            }
            if (i === 1) {
              element.style.backfaceVisibility = 'hidden'
              element.style.transform = 'rotateY(180deg)'
            }
          }
        }

        el.initChidren(el, binding)
      },

      // inserted: function (el, binding) {
      //   console.log('inserted', el, binding.value)
      // },

      // update: function (el, binding) {
        // console.log('update', el, binding)
      // },

      componentUpdated: function (el, binding) {
        // console.log('componentUpdated', el, binding.value)
        console.log(el.children.length)

        // el.innerHTML 更新之后先重置子元素css属性,再初始化
        for (let i = 0; i < el.children.length; i++) {
          const element = el.children[i]
          element.style.backfaceVisibility = 'visible'
          element.style.transform = 'rotateY(0deg)'
        }

        el.initChidren(el, binding)
      },

      // unbind(el) {
        // 在解绑时移除事件
      // },
    
})

组件中使用(注意 html 结构必须如下):

<template>
    <div class="flipped_card" v-flip="isFlipped" @click="handleFlippedClick">
        <div class="front">front</div>
        <div class="back">back</div>
    </div>
</template>
<script>
  data() {
    return {
      isFlipped: false,
    }
  },
  
  methods: {
    handleFlippedClick() {
      if (!this.isFlipped) {
        this.isFlipped = true
      } else {
        this.isFlipped = false
      }
    },
  }    
</script>

以上就是Vue自定义指令实现卡片翻转功能的详细内容,更多关于Vue实现卡片翻转的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文