使用vue制作探探滑动堆叠组件的实例代码


Posted in Javascript onMarch 07, 2018

效果图如下所示:

使用vue制作探探滑动堆叠组件的实例代码 

前言

嗨,说起探探想必各位程序汪都不陌生(毕竟妹子很多),能在上面丝滑的翻牌子,探探的的堆叠滑动组件起到了关键的作用,下面就来看看如何用vue写一个探探的堆叠组件

一. 功能分析

简单使用下探探会发现,堆叠滑动的功能很简单,用一张图概括就是:

使用vue制作探探滑动堆叠组件的实例代码 

简单归纳下里面包含的基本功能点:

  • 图片的堆叠
  • 图片第一张的滑动
  • 条件成功后的滑出,条件失败后的回弹
  • 滑出后下一张图片堆叠到顶部
  • 体验优化
  • 根据触摸点的不同,滑动时首图有不同角度偏移
  • 偏移面积判定是否成功滑出

二. 具体实现

有了归纳好的功能点,我们实现组件的思路会更清晰

1. 堆叠效果

堆叠图片效果在网上有大量的实例,实现的方法大同小异,主要通过在父层设定perspective 及perspective-origin ,来实现子层的透视,子层设定好translate3d Z轴数值即可模拟出堆叠效果,具体代码如下

// 图片堆叠dom
 <!--opacity: 0 隐藏我们不想看到的stack-item层级-->
 <!--z-index: -1 调整stack-item层级"-->
<ul class="stack">
 <li class="stack-item" style="transform: translate3d(0px, 0px, 0px);opacity: 1;z-index: 10;"><img src="1.png" alt="01"></li>
 <li class="stack-item" style="transform: translate3d(0px, 0px, -60px);opacity: 1;z-index: 1"><img src="2.png" alt="02"></li>
 <li class="stack-item" style="transform: translate3d(0px, 0px, -120px);opacity: 1;z-index: 1"><img src="3.png" alt="03"></li>
 <li class="stack-item" style="transform: translate3d(0px, 0px, -180px);opacity: 0;z-index: -1"><img src="4.png" alt="04"></li>
 <li class="stack-item" style="transform: translate3d(0px, 0px, -180px);opacity: 0;z-index: -1"><img src="5.png" alt="05"></li>
</ul>
<style>
.stack {
 width: 100%;
 height: 100%;
 position: relative;
 perspective: 1000px; //子元素视距
 perspective-origin: 50% 150%; //子元素透视位置
 -webkit-perspective: 1000px;
 -webkit-perspective-origin: 50% 150%;
 margin: 0;
 padding: 0;
 }
 .stack-item{
 background: #fff;
 height: 100%;
 width: 100%;
 border-radius: 4px;
 text-align: center;
 overflow: hidden;
 }
 .stack-item img {
 width: 100%;
 display: block;
 pointer-events: none;
 }
</style>

上面只是一组静态代码,我们希望得到的是vue组件,所以需要先建立一个组件模板stack.vue,在模板中我们可以使用v-for,遍历出stack节点,使用:style 来修改各个item的style,代码如下

<template>
 <ul class="stack">
  <li class="stack-item" v-for="(item, index) in pages" :style="[transform(index)]">
  <img :src="item.src">
  </li>
 </ul>
</template>
<script>
export default {
 props: {
 // pages数据包含基础的图片数据
 pages: {
  type: Array,
  default: []
 }
 },
 data () {
 return {
  // basicdata数据包含组件基本数据
  basicdata: {
  currentPage: 0 // 默认首图的序列
  },
  // temporaryData数据包含组件临时数据
  temporaryData: {
  opacity: 1, // 记录opacity
  zIndex: 10, // 记录zIndex
  visible: 3 // 记录默认显示堆叠数visible
  }
 }
 },
 methods: {
 // 遍历样式
 transform (index) {
  if (index >= this.basicdata.currentPage) {
  let style = {}
  let visible = this.temporaryData.visible
  let perIndex = index - this.basicdata.currentPage
  // visible可见数量前滑块的样式
  if (index <= this.basicdata.currentPage + visible - 1) {
   style['opacity'] = '1'
   style['transform'] = 'translate3D(0,0,' + -1 * perIndex * 60 + 'px' + ')'
   style['zIndex'] = visible - index + this.basicdata.currentPage
   style['transitionTimingFunction'] = 'ease'
   style['transitionDuration'] = 300 + 'ms'
  } else {
   style['zIndex'] = '-1'
   style['transform'] = 'translate3D(0,0,' + -1 * visible * 60 + 'px' + ')'
  }
  return style
  }
 }
 }
}
</script>

关键点

:style 可以绑定对象的同时,也可以绑定数组和函数,这在遍历的时候很有用
最基本的dom结构已经构建完毕,下一步是让首张图片“动”起来

2. 图片滑动

图片滑动效果,在很多场景中都有出现,其原理无非是监听touchs事件,得到位移,再通过translate3D改变目标位移,因此我们要实现的步骤如下

  • 对stack进行touchs事件的绑定
  • 监听并储存手势位置变化的数值
  • 改变首图css属性中translate3D的x,y值

#### 具体实现

在vue框架中,不建议直接操作节点,而是通过指令v-on对元素进行绑定,因此我们将绑定都写在v-for遍历里,通过index进行判断其是否是首图,再使用:style修改首页的样式,具体代码如下:

<template>
 <ul class="stack">
  <li class="stack-item" v-for="(item, index) in pages"
  :style="[transformIndex(index),transform(index)]"
  @touchstart.stop.capture="touchstart"
  @touchmove.stop.capture="touchmove"
  @touchend.stop.capture="touchend"
  @mousedown.stop.capture="touchstart"
  @mouseup.stop.capture="touchend"
  @mousemove.stop.capture="touchmove">
  <img :src="item.src">
  </li>
 </ul>
</template>
<script>
export default {
 props: {
 // pages数据包含基础的图片数据
 pages: {
  type: Array,
  default: []
 }
 },
 data () {
 return {
  // basicdata数据包含组件基本数据
  basicdata: {
  start: {}, // 记录起始位置
  end: {}, // 记录终点位置
  currentPage: 0 // 默认首图的序列
  },
  // temporaryData数据包含组件临时数据
  temporaryData: {
  poswidth: '', // 记录位移
  posheight: '', // 记录位移
  tracking: false // 是否在滑动,防止多次操作,影响体验
  }
 }
 },
 methods: {
 touchstart (e) {
  if (this.temporaryData.tracking) {
  return
  }
  // 是否为touch
  if (e.type === 'touchstart') {
  if (e.touches.length > 1) {
   this.temporaryData.tracking = false
   return
  } else {
   // 记录起始位置
   this.basicdata.start.t = new Date().getTime()
   this.basicdata.start.x = e.targetTouches[0].clientX
   this.basicdata.start.y = e.targetTouches[0].clientY
   this.basicdata.end.x = e.targetTouches[0].clientX
   this.basicdata.end.y = e.targetTouches[0].clientY
  }
  // pc操作
  } else {
  this.basicdata.start.t = new Date().getTime()
  this.basicdata.start.x = e.clientX
  this.basicdata.start.y = e.clientY
  this.basicdata.end.x = e.clientX
  this.basicdata.end.y = e.clientY
  }
  this.temporaryData.tracking = true
 },
 touchmove (e) {
  // 记录滑动位置
  if (this.temporaryData.tracking && !this.temporaryData.animation) {
  if (e.type === 'touchmove') {
   this.basicdata.end.x = e.targetTouches[0].clientX
   this.basicdata.end.y = e.targetTouches[0].clientY
  } else {
   this.basicdata.end.x = e.clientX
   this.basicdata.end.y = e.clientY
  }
  // 计算滑动值
  this.temporaryData.poswidth = this.basicdata.end.x - this.basicdata.start.x
  this.temporaryData.posheight = this.basicdata.end.y - this.basicdata.start.y
  }
 },
 touchend (e) {
  this.temporaryData.tracking = false
  // 滑动结束,触发判断
 },
 // 非首页样式切换
 transform (index) {
  if (index > this.basicdata.currentPage) {
  let style = {}
  let visible = 3
  let perIndex = index - this.basicdata.currentPage
  // visible可见数量前滑块的样式
  if (index <= this.basicdata.currentPage + visible - 1) {
   style['opacity'] = '1'
   style['transform'] = 'translate3D(0,0,' + -1 * perIndex * 60 + 'px' + ')'
   style['zIndex'] = visible - index + this.basicdata.currentPage
   style['transitionTimingFunction'] = 'ease'
   style['transitionDuration'] = 300 + 'ms'
  } else {
   style['zIndex'] = '-1'
   style['transform'] = 'translate3D(0,0,' + -1 * visible * 60 + 'px' + ')'
  }
  return style
  }
 },
 // 首页样式切换
 transformIndex (index) {
  // 处理3D效果
  if (index === this.basicdata.currentPage) {
  let style = {}
  style['transform'] = 'translate3D(' + this.temporaryData.poswidth + 'px' + ',' + this.temporaryData.posheight + 'px' + ',0px)'
  style['opacity'] = 1
  style['zIndex'] = 10
  return style
  }
 }
 }
}
</script>

3. 条件成功后的滑出,条件失败后的回弹

条件的触发判断是在touchend/mouseup后进行,在这里我们先用简单的条件进行判定,同时给予首图弹出及回弹的效果,代码如下

<template>
 <ul class="stack">
  <li class="stack-item" v-for="(item, index) in pages"
  :style="[transformIndex(index),transform(index)]"
  @touchmove.stop.capture="touchmove"
  @touchstart.stop.capture="touchstart"
  @touchend.stop.capture="touchend"
  @mousedown.stop.capture="touchstart"
  @mouseup.stop.capture="touchend"
  @mousemove.stop.capture="touchmove">
  <img :src="item.src">
  </li>
 </ul>
</template>
<script>
export default {
 props: {
  // pages数据包含基础的图片数据
 pages: {
  type: Array,
  default: []
 }
 },
 data () {
 return {
  // basicdata数据包含组件基本数据
  basicdata: {
  start: {}, // 记录起始位置
  end: {}, // 记录终点位置
  currentPage: 0 // 默认首图的序列
  },
  // temporaryData数据包含组件临时数据
  temporaryData: {
  poswidth: '', // 记录位移
  posheight: '', // 记录位移
  tracking: false, // 是否在滑动,防止多次操作,影响体验
  animation: false, // 首图是否启用动画效果,默认为否
  opacity: 1 // 记录首图透明度
  }
 }
 },
 methods: {
 touchstart (e) {
  if (this.temporaryData.tracking) {
  return
  }
  // 是否为touch
  if (e.type === 'touchstart') {
  if (e.touches.length > 1) {
   this.temporaryData.tracking = false
   return
  } else {
   // 记录起始位置
   this.basicdata.start.t = new Date().getTime()
   this.basicdata.start.x = e.targetTouches[0].clientX
   this.basicdata.start.y = e.targetTouches[0].clientY
   this.basicdata.end.x = e.targetTouches[0].clientX
   this.basicdata.end.y = e.targetTouches[0].clientY
  }
  // pc操作
  } else {
  this.basicdata.start.t = new Date().getTime()
  this.basicdata.start.x = e.clientX
  this.basicdata.start.y = e.clientY
  this.basicdata.end.x = e.clientX
  this.basicdata.end.y = e.clientY
  }
  this.temporaryData.tracking = true
  this.temporaryData.animation = false
 },
 touchmove (e) {
  // 记录滑动位置
  if (this.temporaryData.tracking && !this.temporaryData.animation) {
  if (e.type === 'touchmove') {
   this.basicdata.end.x = e.targetTouches[0].clientX
   this.basicdata.end.y = e.targetTouches[0].clientY
  } else {
   this.basicdata.end.x = e.clientX
   this.basicdata.end.y = e.clientY
  }
  // 计算滑动值
  this.temporaryData.poswidth = this.basicdata.end.x - this.basicdata.start.x
  this.temporaryData.posheight = this.basicdata.end.y - this.basicdata.start.y
  }
 },
 touchend (e) {
  this.temporaryData.tracking = false
  this.temporaryData.animation = true
  // 滑动结束,触发判断
  // 简单判断滑动宽度超出100像素时触发滑出
  if (Math.abs(this.temporaryData.poswidth) >= 100) {
  // 最终位移简单设定为x轴200像素的偏移
  let ratio = Math.abs(this.temporaryData.posheight / this.temporaryData.poswidth)
  this.temporaryData.poswidth = this.temporaryData.poswidth >= 0 ? this.temporaryData.poswidth + 200 : this.temporaryData.poswidth - 200
  this.temporaryData.posheight = this.temporaryData.posheight >= 0 ? Math.abs(this.temporaryData.poswidth * ratio) : -Math.abs(this.temporaryData.poswidth * ratio)
  this.temporaryData.opacity = 0
  // 不满足条件则滑入
  } else {
  this.temporaryData.poswidth = 0
  this.temporaryData.posheight = 0
  }
 },
 // 非首页样式切换
 transform (index) {
  if (index > this.basicdata.currentPage) {
  let style = {}
  let visible = 3
  let perIndex = index - this.basicdata.currentPage
  // visible可见数量前滑块的样式
  if (index <= this.basicdata.currentPage + visible - 1) {
   style['opacity'] = '1'
   style['transform'] = 'translate3D(0,0,' + -1 * perIndex * 60 + 'px' + ')'
   style['zIndex'] = visible - index + this.basicdata.currentPage
   style['transitionTimingFunction'] = 'ease'
   style['transitionDuration'] = 300 + 'ms'
  } else {
   style['zIndex'] = '-1'
   style['transform'] = 'translate3D(0,0,' + -1 * visible * 60 + 'px' + ')'
  }
  return style
  }
 },
 // 首页样式切换
 transformIndex (index) {
  // 处理3D效果
  if (index === this.basicdata.currentPage) {
  let style = {}
  style['transform'] = 'translate3D(' + this.temporaryData.poswidth + 'px' + ',' + this.temporaryData.posheight + 'px' + ',0px)'
  style['opacity'] = this.temporaryData.opacity
  style['zIndex'] = 10
  if (this.temporaryData.animation) {
   style['transitionTimingFunction'] = 'ease'
   style['transitionDuration'] = 300 + 'ms'
  }
  return style
  }
 }
 }
}
</script>

4. 滑出后下一张图片堆叠到顶部

重新堆叠是组件最后一个功能,同时也是最重要和复杂的功能。在我们的代码里,stack-item的排序依赖绑定:style的transformIndex和transform函数,函数里判定的条件是currentPage,那是不是改变currentPage,让其+1,即可完成重新堆叠呢?

答案没有那么简单,因为我们滑出是动画效果,会进行300ms的时间,而currentPage变化引起的重排,会立即变化,打断动画的进行。因此我们需要先修改transform函数的排序条件,后改变currentPage。

#### 具体实现

  • 修改transform函数排序条件
  • 让currentPage+1
  • 添加onTransitionEnd事件,在滑出结束后,重新放置stack列表中

代码如下:

<template>
 <ul class="stack">
  <li class="stack-item" v-for="(item, index) in pages"
  :style="[transformIndex(index),transform(index)]"
  @touchmove.stop.capture="touchmove"
  @touchstart.stop.capture="touchstart"
  @touchend.stop.capture="touchend"
  @mousedown.stop.capture="touchstart"
  @mouseup.stop.capture="touchend"
  @mousemove.stop.capture="touchmove"
  @webkit-transition-end="onTransitionEnd"
  @transitionend="onTransitionEnd"
  >
  <img :src="item.src">
  </li>
 </ul>
</template>
<script>
export default {
 props: {
 // pages数据包含基础的图片数据
 pages: {
  type: Array,
  default: []
 }
 },
 data () {
 return {
  // basicdata数据包含组件基本数据
  basicdata: {
  start: {}, // 记录起始位置
  end: {}, // 记录终点位置
  currentPage: 0 // 默认首图的序列
  },
  // temporaryData数据包含组件临时数据
  temporaryData: {
  poswidth: '', // 记录位移
  posheight: '', // 记录位移
  lastPosWidth: '', // 记录上次最终位移
  lastPosHeight: '', // 记录上次最终位移
  tracking: false, // 是否在滑动,防止多次操作,影响体验
  animation: false, // 首图是否启用动画效果,默认为否
  opacity: 1, // 记录首图透明度
  swipe: false // onTransition判定条件
  }
 }
 },
 methods: {
 touchstart (e) {
  if (this.temporaryData.tracking) {
  return
  }
  // 是否为touch
  if (e.type === 'touchstart') {
  if (e.touches.length > 1) {
   this.temporaryData.tracking = false
   return
  } else {
   // 记录起始位置
   this.basicdata.start.t = new Date().getTime()
   this.basicdata.start.x = e.targetTouches[0].clientX
   this.basicdata.start.y = e.targetTouches[0].clientY
   this.basicdata.end.x = e.targetTouches[0].clientX
   this.basicdata.end.y = e.targetTouches[0].clientY
  }
  // pc操作
  } else {
  this.basicdata.start.t = new Date().getTime()
  this.basicdata.start.x = e.clientX
  this.basicdata.start.y = e.clientY
  this.basicdata.end.x = e.clientX
  this.basicdata.end.y = e.clientY
  }
  this.temporaryData.tracking = true
  this.temporaryData.animation = false
 },
 touchmove (e) {
  // 记录滑动位置
  if (this.temporaryData.tracking && !this.temporaryData.animation) {
  if (e.type === 'touchmove') {
   this.basicdata.end.x = e.targetTouches[0].clientX
   this.basicdata.end.y = e.targetTouches[0].clientY
  } else {
   this.basicdata.end.x = e.clientX
   this.basicdata.end.y = e.clientY
  }
  // 计算滑动值
  this.temporaryData.poswidth = this.basicdata.end.x - this.basicdata.start.x
  this.temporaryData.posheight = this.basicdata.end.y - this.basicdata.start.y
  }
 },
 touchend (e) {
  this.temporaryData.tracking = false
  this.temporaryData.animation = true
  // 滑动结束,触发判断
  // 简单判断滑动宽度超出100像素时触发滑出
  if (Math.abs(this.temporaryData.poswidth) >= 100) {
  // 最终位移简单设定为x轴200像素的偏移
  let ratio = Math.abs(this.temporaryData.posheight / this.temporaryData.poswidth)
  this.temporaryData.poswidth = this.temporaryData.poswidth >= 0 ? this.temporaryData.poswidth + 200 : this.temporaryData.poswidth - 200
  this.temporaryData.posheight = this.temporaryData.posheight >= 0 ? Math.abs(this.temporaryData.poswidth * ratio) : -Math.abs(this.temporaryData.poswidth * ratio)
  this.temporaryData.opacity = 0
  this.temporaryData.swipe = true
  // 记录最终滑动距离
  this.temporaryData.lastPosWidth = this.temporaryData.poswidth
  this.temporaryData.lastPosHeight = this.temporaryData.posheight
  // currentPage+1 引发排序变化
  this.basicdata.currentPage += 1
  // currentPage切换,整体dom进行变化,把第一层滑动置零
  this.$nextTick(() => {
   this.temporaryData.poswidth = 0
   this.temporaryData.posheight = 0
   this.temporaryData.opacity = 1
  })
  // 不满足条件则滑入
  } else {
  this.temporaryData.poswidth = 0
  this.temporaryData.posheight = 0
  this.temporaryData.swipe = false
  }
 },
 onTransitionEnd (index) {
  // dom发生变化后,正在执行的动画滑动序列已经变为上一层
  if (this.temporaryData.swipe && index === this.basicdata.currentPage - 1) {
  this.temporaryData.animation = true
  this.temporaryData.lastPosWidth = 0
  this.temporaryData.lastPosHeight = 0
  this.temporaryData.swipe = false
  }
 },
 // 非首页样式切换
 transform (index) {
  if (index > this.basicdata.currentPage) {
  let style = {}
  let visible = 3
  let perIndex = index - this.basicdata.currentPage
  // visible可见数量前滑块的样式
  if (index <= this.basicdata.currentPage + visible - 1) {
   style['opacity'] = '1'
   style['transform'] = 'translate3D(0,0,' + -1 * perIndex * 60 + 'px' + ')'
   style['zIndex'] = visible - index + this.basicdata.currentPage
   style['transitionTimingFunction'] = 'ease'
   style['transitionDuration'] = 300 + 'ms'
  } else {
   style['zIndex'] = '-1'
   style['transform'] = 'translate3D(0,0,' + -1 * visible * 60 + 'px' + ')'
  }
  return style
  // 已滑动模块释放后
  } else if (index === this.basicdata.currentPage - 1) {
  let style = {}
  // 继续执行动画
  style['transform'] = 'translate3D(' + this.temporaryData.lastPosWidth + 'px' + ',' + this.temporaryData.lastPosHeight + 'px' + ',0px)'
  style['opacity'] = '0'
  style['zIndex'] = '-1'
  style['transitionTimingFunction'] = 'ease'
  style['transitionDuration'] = 300 + 'ms'
  return style
  }
 },
 // 首页样式切换
 transformIndex (index) {
  // 处理3D效果
  if (index === this.basicdata.currentPage) {
  let style = {}
  style['transform'] = 'translate3D(' + this.temporaryData.poswidth + 'px' + ',' + this.temporaryData.posheight + 'px' + ',0px)'
  style['opacity'] = this.temporaryData.opacity
  style['zIndex'] = 10
  if (this.temporaryData.animation) {
   style['transitionTimingFunction'] = 'ease'
   style['transitionDuration'] = 300 + 'ms'
  }
  return style
  }
 }
 }
}
</script>

ok~ 完成了上面的四步,堆叠组件的基本功能就已经实现,快来看看效果吧

使用vue制作探探滑动堆叠组件的实例代码 

堆叠滑动效果已经出来了,但是探探在体验上,还增加了触碰角度偏移,以及判定滑出面积比例

角度偏移的原理,是在用户每次进行touch时,记录用户触碰位置,计算出最大的偏移角度,在滑动出现位移时,线性增加角度以至最大的偏移角度。

使用在stack中具体要做的是:

  • touchmove中计算出所需角度和方向
  • touchend及onTransitionEnd中将角度至零

判定滑出面积比例,主要通过偏移量计算出偏移面积,从而得到面积比例,完成判断

完整的代码和demo可以在 github 上查看源码,这里就不贴出来了

谢谢大家看完这篇文章,喜欢可以在github上给个:star:️ ,最后祝大家在探探上都能找到前女友:green_heart:

总结

以上所述是小编给大家介绍的使用vue制作探探滑动组件的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
javascript使用eval或者new Function进行语法检查
Oct 16 Javascript
根据身份证号自动输出相关信息(籍贯,出身日期,性别)
Nov 15 Javascript
jQuery中outerWidth()方法用法实例
Jan 19 Javascript
js实现鼠标经过时图片滚动停止的方法
Feb 16 Javascript
javascript函数特点实例分析
May 14 Javascript
基于dropdown.js实现的两款美观大气的二级导航菜单
Sep 02 Javascript
ES6 javascript中class类的get与set用法实例分析
Oct 30 Javascript
讲解vue-router之什么是动态路由
May 28 Javascript
在Bootstrap开发框架中使用dataTable直接录入表格行数据的方法
Oct 25 Javascript
vue实现路由监听和参数监听
Oct 29 Javascript
ES2020 已定稿,真实场景案例分析
May 25 Javascript
利用promise及参数解构封装ajax请求的方法
Mar 24 Javascript
基于vue-cli 打包时抽离项目相关配置文件详解
Mar 07 #Javascript
关于Vue的路由权限管理的示例代码
Mar 06 #Javascript
vue.js在标签属性中插入变量参数的方法
Mar 06 #Javascript
基于Vue中点击组件外关闭组件的实现方法
Mar 06 #Javascript
解决vue build打包之后首页白屏的问题
Mar 06 #Javascript
vue2.0 路由不显示router-view的解决方法
Mar 06 #Javascript
解决vue-router进行build无法正常显示路由页面的问题
Mar 06 #Javascript
You might like
PHP动态变静态原理
2006/11/25 PHP
php中sprintf与printf函数用法区别解析
2014/02/17 PHP
php正则匹配html中带class的div并选取其中内容的方法
2015/01/13 PHP
使用WordPress发送电子邮件的相关PHP函数用法解析
2015/12/15 PHP
PHP filter_var() 函数, 验证判断EMAIL,URL等
2021/03/09 PHP
新浪刚打开页面出来的全屏广告代码
2007/04/02 Javascript
JavaScript和JQuery实用代码片段(一)
2010/04/07 Javascript
防止页面被iframe(兼容IE,Firefox火狐)
2010/07/04 Javascript
用C/C++来实现 Node.js 的模块(一)
2014/09/24 Javascript
用vuex写了一个购物车H5页面的示例代码
2018/12/04 Javascript
[33:33]完美世界DOTA2联赛PWL S2 FTD.C vs SZ 第二场 11.27
2020/11/30 DOTA
Python lxml模块安装教程
2015/06/02 Python
Python的shutil模块中文件的复制操作函数详解
2016/07/05 Python
Python读取sqlite数据库文件的方法分析
2017/08/07 Python
python中利用h5py模块读取h5文件中的主键方法
2018/06/05 Python
Python面向对象类的继承实例详解
2018/06/27 Python
python学生信息管理系统(初级版)
2018/10/17 Python
解决python中 f.write写入中文出错的问题
2018/10/31 Python
Python设计模式之建造者模式实例详解
2019/01/17 Python
在Python中将函数作为另一个函数的参数传入并调用的方法
2019/01/22 Python
基于pytorch 预训练的词向量用法详解
2020/01/06 Python
在django admin详情表单显示中添加自定义控件的实现
2020/03/11 Python
详解基于Facecognition+Opencv快速搭建人脸识别及跟踪应用
2021/01/21 Python
html5在移动端的屏幕适应问题示例探讨
2014/06/15 HTML / CSS
HTML5 拖放(Drag 和 Drop)详解与实例代码
2017/09/14 HTML / CSS
怀旧香味蜡烛:Homesick
2019/11/02 全球购物
娇韵诗香港官网:Clarins香港
2020/08/13 全球购物
药学职务聘任书
2014/03/29 职场文书
《路旁的橡树》教学反思
2014/04/07 职场文书
爱心活动计划书
2014/04/26 职场文书
学生无故旷课检讨书
2014/09/20 职场文书
我们的节日元宵节活动总结
2015/02/06 职场文书
廉洁自律心得体会2016
2016/01/13 职场文书
写自招自荐信的绝招!
2019/04/19 职场文书
Python Matplotlib绘制动画的代码详解
2022/05/30 Python
Python如何加载模型并查看网络
2022/07/15 Python