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

 更新时间:2018年08月03日 11:39:30   作者:JB_Chen666  
最近在做小程序开发的时候,遇到了点问题。最终选择用mpvue来做,谁知这么多坑,下面小编把我遇到的问题分享给大家,如果大家对mpvue小程序仿qq左滑置顶删除组件相关知识感兴趣的朋友一起看看吧

背景:

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

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

效果图:

实现:

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左滑置顶删除组件,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • Vue如何跨组件传递Slot的实现

    Vue如何跨组件传递Slot的实现

    这篇文章主要介绍了Vue如何跨组件传递Slot的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • vue监听scroll的坑的解决方法

    vue监听scroll的坑的解决方法

    这篇文章主要介绍了vue监听scroll的坑的解决方法,现在分享给大家,也给大家做个参考,希望给有同样经历的人帮助
    2017-09-09
  • Element Table行的动态合并及数据编辑示例

    Element Table行的动态合并及数据编辑示例

    这篇文章主要为大家介绍了Element Table行的动态合并及数据编辑示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • vue3获取子组件的DOM元素的方法总结

    vue3获取子组件的DOM元素的方法总结

    在 Vue 3 中,访问子组件的 DOM 元素是一个常见的需求,本文将介绍如何在 Vue 3 中使用不同的方法来获取子组件的 DOM 元素,需要的朋友可以参考下
    2023-08-08
  • 浅析从面向对象思维理解Vue组件

    浅析从面向对象思维理解Vue组件

    用面向对象的思维去理解Vue组件,可以将所有的事物都抽象为对象,而类或者说是组件,都具有属性和操作。这篇文章主要介绍了尝试用面向对象思维理解Vue组件,需要的朋友可以参考下
    2021-07-07
  • vue 解决异步数据更新问题

    vue 解决异步数据更新问题

    今天小编就为大家分享一篇vue 解决异步数据更新问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-10-10
  • Vue+Antv F2实现层叠柱状图

    Vue+Antv F2实现层叠柱状图

    这篇文章主要为大家详细介绍了Vue+Antv F2实现层叠柱状图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • vue3 使用defineAsyncComponent与component标签实现动态渲染组件思路详解

    vue3 使用defineAsyncComponent与component标签实现动态渲染组件思路详解

    这篇文章主要介绍了vue3 使用defineAsyncComponent与component标签实现动态渲染组件,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • vue子传父关于.sync与$emit的实现

    vue子传父关于.sync与$emit的实现

    这篇文章主要介绍了vue子传父关于.sync与$emit的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • nuxt.js写项目时增加错误提示页面操作

    nuxt.js写项目时增加错误提示页面操作

    这篇文章主要介绍了nuxt.js写项目时增加错误提示页面操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11

最新评论