vue 实现许愿墙便利贴功能

本文介绍了一种使用Vue.js实现的动态卡片布局方法,并包含了卡片拖动、过渡动画及点赞动画效果。通过随机生成卡片位置和背景颜色,实现了美观且交互丰富的页面布局。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<template>
  <div class="message-board">
    <transition-group name="fade" appear mode="out-in"  >
      <div
        class="card"
        v-drag
        v-for="(item, index) in list"
        :key="index"
        :style="{
          top: item.top,
          left: item.left,
          zIndex: item.zIndex,
          border: item.border,
          backgroundColor:item.bgl,
          width:item.content.length<30?'230px':item.content.length<50?'250px':'300px',
          height:item.content.length<30?'250px':item.content.length<50?'270px':'320px',
        }"
        :title="item.text"
        @mouseenter="mouseenter(item, index)"
      >
        <span style="font-size:14px"> {{ item.content }}</span>
        <div class="svg_icon" >
            <i  :class="{'el-icon-goblet-square-full':true,zan_succsee:item.isLike}" @click="methodDZ(item)"/>
            <i  v-if="item.isZan"  class="el-icon-goblet-square-full animate" />
            <span :class="{zan_succsee:item.isLike}">{{item.count}}</span>
        </div>
        
      </div>
        
    </transition-group>
      <div class="input">
        <el-input
          type="text"
          placeholder="随便说说吧。。。按回车发布"
          @keyup.enter.native="handleLogin"
          v-model.trim="inputValue"
          key="input"
          v-if="isInput"
        />
        <i class="el-icon-remove-outline"  v-if="isInput" @click="isInput = false"></i>
      </div>
        <i class="el-icon-circle-plus-outline add" @click="isInput = true"></i>
  </div>
</template>

<script>
export default {
  name: "Login",
  data() {
    return {
        isInput:false,
      inputValue: "",
      list: [
           {
            top:'',
            left:'',
            bgl:'',
            zIndex:0,
            border:'',
            isZan:false,
            content:'qeqweqeq'
                }
      ],
      loading: false,
      // 验证码开关
      captchaOnOff: true,
      // 注册开关
      register: false,
      redirect: undefined,
      color: [
        "rgb(205, 196, 155,.8)",
        "rgb(55, 160, 149,.8)",
        "rgb(255, 139, 139,.8)",
        "rgb(110, 234, 112,.8)",
        "rgb(178, 44, 45,.8)",
        "rgb(111, 33, 1,.8)",
        "rgb(217, 167, 12,.8)",
        "rgb(123, 111, 211,.8)",
        "rgb(15, 111, 33,.8)",
        "rgb(133, 110,213,.8)",
        "rgb(56, 154, 222,.8)",
      ],
    };
  },
  created() {
      this.getList()
  },
  mounted() {
    
  },
  directives: {
    drag(el, bindings) {
      el.onmousedown = function (e) {
        var disx = e.pageX - el.offsetLeft;
        var disy = e.pageY - el.offsetTop;
        document.onmousemove = function (e) {
          el.style.left = e.pageX - disx + "px";
          el.style.top = e.pageY - disy + "px";
        };
        document.onmouseup = function () {
          document.onmousemove = document.onmouseup = null;
        };
      };
    },
  },
  methods: {
      getList(){
              this.list.forEach((item) => {
                this.$set(item,'top',this.getTop())
                this.$set(item,'left',this.getLeft())
                this.$set(item,'bgl',this.getBgl())
                this.$set(item,'zIndex',0)
                this.$set(item,'border','')
                this.$set(item,'isZan',false)
            });
      },
  
    mouseenter(item) {
      this.list.forEach((item) => {
        item.zIndex = 0;
        item.border = "";
      });
      item.zIndex = 1;
      item.border = "2px dashed #ccc";
    },
    handleLogin() {
      if (this.inputValue) {
               this.list.forEach((item) => {
                  item.zIndex = 0;
                  item.border = "";
                });
               this.list.push({
                    zIndex: 0,
                    top: this.getTop(),
                    left: this.getLeft(),
                    border: "2px dashed #ccc",
                    isLike:null,
                    bgl:this.getBgl(),
                    isZan : false,
                    content:this.inputValue
               })
                this.inputValue = "";
                this.isInput = false
      }
    },
    getTop() {
      return Math.floor(Math.random() * (document.body.clientHeight - 330)) + "px"
    },
    getLeft() {
      return   Math.floor(Math.random() * (document.body.clientWidth - 300)) + "px"
      
    },
    getBgl() {
      return   this.color[Math.floor(Math.random() * 11)];;
    },
    methodDZ(item){
        if(item.isLike) return this.$message.warning('已经点过赞了!!!')
            item.isLike = true
            item.count =item.count?item.count+1:1
            item.isZan= true
            setTimeout(()=>{
                  item.isZan= false
            },1000)
    },
  }
};
</script>

<style rel="stylesheet/scss" lang="scss">
.message-board {
  //   display: flex;
  height: 100%;
  width: 100%;
  overflow: hidden;
  background-color: #d4ffc4;
  position: relative;
  text-align: center;
  .add{
      position: fixed;
      left: 0;
      bottom: 0;
      font-size: 80px;
      color: #00a8ff;
      z-index: 100;
  }
  .input{
    position: fixed;
     bottom: 20px;
      left: 80px;
    z-index: 100;
  }
  .el-input {
    width: 300px;
    height: 30px;
  }
  .card {
    display: inline;
    float: left;
    position: absolute;
   
    text-align: left;
    padding: 20px 50px;
    box-sizing: border-box;
    background-size:100%;
    background-repeat:no-repeat;
    background-position: 60% 60%;
     align-items:center;
     display: flex;
     align-items: center;
    // border-radius: 0 0 70px 0;
    // border-bottom-right-radius:500px 30px;
    span {
      word-break: break-all;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 5;
      overflow: hidden;
      flex: 1;
      text-align: center;
    }
    .zan_succsee{
        color: #00a8ff;
    }
    .svg_icon{
        position: absolute;
        right: 50%;
        transform: translate(50%,50%);
        bottom: 50px;
        font-size: 25px;
        cursor: pointer;
        text-align: center;
        span{
            font-size: 16px;
        }
        .animate {
            position: absolute;
            left: 0;
            animation: ClickLikeAni 1s ease-in-out;
        }
    }
    .close {
      position: absolute;
      right: 0;
      top: 0;
      color: brown;
      display: none;
      cursor: pointer;
    }
    &:hover {
      .close {
        display: inline;
      }
    }
  }
  
  @keyframes ClickLikeAni {
    0% {
        top:0px; 
    }
    10% {
        top:-3px; 
    }
    20% {
        top:-6px; 
    }
    30% {
        top:-9px; 
    }
    40% {
        top:-12px; 
        transform: rotate(6deg);
    }
    50% {
        top:-15px; 
        transform: rotate(12deg);
    }
    60% {
        top:-18px; 
        transform: rotate(6deg);
    }
    70% {
        top:-21px;
        transform: rotate(0deg);
    }
    80% {
        top:-24px;
        transform: rotate(-6deg);
    }
    90% {
        top:-27px;
        transform: rotate(-12deg);
    }
    100% {
        top:-30px;
        transform: rotate(-6deg);
    }
}
}
</style>

效果图

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值