欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

mpvue小程序仿qq左滑置顶删除组件

程序员文章站 2022-03-10 21:09:15
背景: 前几天,公司的一个小程序项目开发的时候,遇到了一点点问题。设计师这狗币要让我在小程序上实现类似qq左滑置顶删除的操作,心里mmp,我就是一个刚来公司三天的小小前端...

背景:

前几天,公司的一个小程序项目开发的时候,遇到了一点点问题。设计师这狗币要让我在小程序上实现类似qq左滑置顶删除的操作,心里mmp,我就是一个刚来公司三天的小小前端实习生而已,我想学习....当然刚刚来就被公司委以重任,也能看出本人技术过人,尤其是作为一个大二刚刚结束的学生来说。废话不多说,对于这个功能,第一反应就是百度,不百度不得了,一百度吓一跳。前辈们也来都做过。“那我不是直接照搬就行,开心”。开开心心的用mpvue上手之后,心里mmp,mpvue的坑这么多。。。。还不如自己动手撸一个,效率还更快。

我们先来看看效果图,有图有真相:

效果图:

mpvue小程序仿qq左滑置顶删除组件

实现:

1,上面说过mpvue的坑,比如里面的每一个的元素都是overflow:hidden,并且似乎都继承了display:block。(看小程序开发工具是这样的,具体源码没看,就只能猜猜)。所以主要解决是让元素overflow:scroll,这个主要是看效果的时候会用到

2,左滑和右滑,这又是一个坑。本以为mpvue的滑动事件会和vue的一模一样。开开心心的按着原来想法撸,发现怎么滑都滑不动,果断打印一波数据,发现滑动事件大有奥妙!

3,布局方面我采用的是rpx+flex。

4,点击时候置顶与取消置顶是通过json数据的top实现的。删除是用数组的splice()方法。

5,滑动效果是css动画控制的。

下面直接贴代码:如果看不懂可以嫌麻烦可以去我的github:https://github.com/jb-chen/mpvue-slide

程序员大佬们,觉得可以就给个star,以资鼓励一下!

html代码:

主要的html代码:

<template>
 <div class="container">
  <!-- 头部 -->
  <div class="head">
   <img class="userinfo-avatar" v-if="userinfo.avatarurl" :src="userinfo.avatarurl" background-size="cover"/>
   <span class="head-info">消息</span>
  </div>
  <!-- 搜索 -->
  <div class="search">
   <input type="search"/>
   <span>搜索</span>
  </div>
  <!-- 内容 -->
  <div class="infoall" v-for="(item,index) in commitinfo" :key="index">
   <ul v-if="item.top">
    <li @touchstart="touchstart($event)" @touchend="touchend($event,index)" :data-type="item.type" style="background-color:#edfbfe;">
     <div class="imginfo" @click="recover(index)">
      <img :src="item.img">
     </div>
     <div class="centerinfo">
      <div class="name">
        <span>{{item.name}}</span>
      </div>
      <div class="sonname">
       <span>{{item.sonname}}</span>
       </div>
     </div>
     <div class="timeinfo" @click="recover(index)">
      <div class="time">
       <text>{{item.time}}</text>
      </div>
      <div class="infonum" style="">
        <text style="font-size:12px;">{{item.infonum}}</text> 
      </div>
     </div>
     <div class="top" @click="top(index)" style="width:30%">
      取消置顶
     </div>
    </li> 
   </ul>
  </div>
  <div class="infoall" v-for="(item,index) in commitinfo" :key="index">
   <!-- {{item.img}} -->
   <ul v-if="!item.top">
    <li @touchstart="touchstart($event)" @touchend="touchend($event,index)" :data-type="item.type">
     <div class="imginfo" @click="recover(index)">
      <img :src="item.img">
     </div>
     <div class="centerinfo">
      <div class="name">
        <span>{{item.name}}</span>
      </div>
      <div class="sonname">
       <span>{{item.sonname}}</span>
       </div>
     </div>
     <div class="timeinfo" @click="recover(index)">
      <div class="time">
       <text>{{item.time}}</text>
      </div>
      <div class="infonum" style="">
        <text style="font-size:12px;">{{item.infonum}}</text> 
      </div>
     </div>
     <div class="top" @click="top(index)">
      置顶
     </div>
     <div class="delect" @click="delect(index)">
      删除
     </div>
    </li> 
   </ul>
  </div>
 </div>
</template>

css代码:

// 头部
*{
  margin:0px;
  padding: 0px;
}
.head {
  width: 100%;
  height:130rpx;
  background-color: #38a7fa;
  margin-top:-195rpx;
  display: flex;
  align-items: center;
  .head-info{
    color: #fff;
    font-size:30rpx;
    margin-left: 30%;
    margin-top:20rpx;
    letter-spacing: 4rpx;
   }
   .userinfo-avatar {
    width: 80rpx;
    height: 80rpx;
    margin: 20rpx;
    border-radius: 50%;
    margin-top:30rpx;
   }
 }
 .search{
   width: 90%;
   margin-top:20rpx;
   margin-bottom: 20rpx;
   input{
     width: 100%;
     height: 20rpx;
     background-color: #f3f3f3;
     border-radius: 5rpx;
     z-index: 0;
   }
   span{
     position: absolute;
     color: #b5b5b5;
     font-size: 24rpx;
     margin-top:-44rpx;
     z-index: 999;
     margin-left: 42%;
     text-align: center;
   }
 }
 .infoall{
   width: 100%;
   ul{
    width: 100%;
    // overflow-x: scroll;
     li{
      -webkit-transition: all 0.2s;
      transition: all 0.2s;
       width: 1100rpx;
       height: 150rpx;
      //  background-color: red;
       line-height: 150rpx;
       border-bottom: 1px solid #e0eef1;
      //  垂直居中, // 子div水平排列
       display:flex;
      //  justify-content:center;
       align-items:center;
       .imginfo{
        width: 100rpx;
        height: 100rpx;
        border-radius: 50%;
        background-color: #38a7fa;
        margin-left: 2%;
        img{
          width: 100rpx;
          height: 100rpx;
          border-radius: 50%;
          overflow: hidden;
        }
       }
       .centerinfo{
        width: 40%;
        height: 150rpx;
        margin-left: 2%;
        .name{
          margin-top:-20rpx;
          span{
            font-size: 35rpx;
          }
        }
        .sonname{
          margin-top:-110rpx;
          span{
            font-size: 24rpx;
            color: #7c8489;
          }
        }
       }
       .timeinfo{
        width: 15%;
        height: 150rpx;
        margin-left: 6%;
        .time{
          margin-top:-20rpx;
          color: #92a0a1;
          font-size: 25rpx;
          position: absolute;
        }
        .infonum{
          width:50rpx;
          display:flex;
          align-items:center;
          justify-content:center;
          height: 30rpx;
          border-radius: 10rpx;
          background-color: #93d5ed;
          margin-left: 10rpx;
          margin-top: 70rpx;
        }
       }
       .top{
         width: 15%;
         height: 150rpx;
         background-color: #c4c7cd;
         color: #fff;
         font-size: 34rpx;
         text-align:center
       }
       .delect{
        width: 15%;
        height: 150rpx;
        background-color: #ff3b32;
        color: #fff;
        font-size: 34rpx;
        text-align:center
       }
     }
   }
 }
li[data-type="0"]{
  transform: translate3d(0,0,0);
}
li[data-type="1"]{
  transform: translate3d(-400rpx,0,0);
}

js主要代码:

<script>
import card from '@/components/card'
export default {
 data () {
  return {
   userinfo: {},
   commitinfo:[
    {
     img:"http://img3.imgtn.bdimg.com/it/u=3067730600,935028889&fm=27&gp=0.jpg",
     name:"旺财",
     sonname:"今晚去吃饭吗?",
     time:"19:08",
     infonum:"9",
     top:false,
     type:0
    },
    {
     img:"http://img1.imgtn.bdimg.com/it/u=1257196754,3171363795&fm=27&gp=0.jpg",
     name:"前端学习群",
     sonname:"hanber:异步与同步的问题",
     time:"02:08",
     infonum:"99+",
     top:false,
     type:0
    },
    {
     img:"https://ss3.bdstatic.com/70cfv8sh_q1ynxgkpowk1hf6hhy/it/u=1672209094,624238697&fm=27&gp=0.jpg",
     name:"小学同学",
     sonname:"好久不见,最近好吗?",
     time:"02:08",
     infonum:"9",
     top:false,
     type:0
    },
     {
     img:"https://ss0.bdstatic.com/70cfuhsh_q1ynxgkpowk1hf6hhy/it/u=1312347818,1612941824&fm=200&gp=0.jpg",
     name:"老妈",
     sonname:"啥时候回家一趟呀?",
     time:"23:08",
     infonum:"1",
     top:false,
     type:0
    },
    {
     img:"http://img2.imgtn.bdimg.com/it/u=1093392508,3329264726&fm=27&gp=0.jpg",
     name:"ad动漫群",
     sonname:"ghost:《你的名字》求资源",
     time:"02:08",
     infonum:"99+",
     top:false,
     type:0
    }
   ]
  }
 },
 components: {
  card
 },
 methods: {
 // 滑动开始
  touchstart(e){
   // 获取移动距离,可以通过打印出e,然后分析e的值得出
    this.startx = e.mp.changedtouches[0].clientx;
  },
  // 滑动结束
  touchend(e,index){
    // 获取移动距离
    this.endx = e.mp.changedtouches[0].clientx; 
    if(this.startx-this.endx > 10){
      for(let i=0;i<this.commitinfo.length;i++){
         this.commitinfo[i].type = 0
      }
      this.commitinfo[index].type = 1
    }
    else if(this.startx-this.endx < -10){
      for(let i=0;i<this.commitinfo.length;i++){
         this.commitinfo[i].type = 0
      }
    }
  },
  // 点击回复原状
  recover(index){
     this.commitinfo[index].type = 0
  },
  getuserinfo () {
   // 调用登录接口
   wx.login({
    success: () => {
     wx.getuserinfo({
      success: (res) => {
       this.userinfo = res.userinfo
      }
     })
    }
   })
  },
  // 置顶
  top(index){
   this.commitinfo[index].top = !this.commitinfo[index].top;
   this. recover(index);
  },
  // 删除
  delect(index){
   this.commitinfo.splice(index,1);
  }
 },
 created () {
  // 调用应用实例的方法获取全局数据
  this.getuserinfo()
 }
}
</script>

总结

以上所述是小编给大家介绍的mpvue小程序仿qq左滑置顶删除组件,希望对大家有所帮助