乱码乱a∨中文字幕,在线免费激情视频,亚洲欧美久久夜夜潮,国产在线网址

  1. <sub id="hjl7n"></sub>

    1. <sub id="hjl7n"></sub>

      <legend id="hjl7n"></legend>

      當(dāng)前位置:首頁 >  站長(zhǎng) >  編程技術(shù) >  正文

      vue swipeCell滑動(dòng)單元格(仿微信)的實(shí)現(xiàn)示例

       2020-10-28 14:07  來源: 腳本之家   我來投稿 撤稿糾錯(cuò)

        阿里云優(yōu)惠券 先領(lǐng)券再下單

      這篇文章主要介紹了vue swipeCell滑動(dòng)單元格(仿微信)的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

      抽離Vant weapp滑動(dòng)單元格代碼改造而成

      帶有拉動(dòng)彈性回彈效果

      demo展示:https://littaotao.github.io/me/index(切換為瀏覽器調(diào)試的手機(jī)模式并且再次刷新一次)

      <template>
       <div
        class="cell_container"
        @touchstart
        v-click-outside="handleClickOutside"
        @click="getClickHandler('cell')">
        <div
         :style="{'transform':
         'translateX('+(offset+(isElastic?elasticX:0))+'px)','transition-duration':dragging?'0s':'0.6s'}">
         <!-- <div ref="cellLeft" class="cell_left" @click="getClickHandler('left', true)">
          <div>收藏</div>
          <div>添加</div>
         </div> -->
         <div
          @touchend="onClick()"
          :class="offset?'cell_content':'cell_content_active'">SwipeCell</div>
         <div ref="cellRight"
          class="cell_right"
          @click="getClickHandler('right', true)">
          <div
           :class="type?'divPostion':''"
           ref="remove"
           :style="{'background':'#ccc','padding-left':'10px','padding-right':10+(isElastic?Math.abs(elasticX/3):0)+'px','transition-duration':dragging?'0s':'0.6s'}">標(biāo)記</div>
          <div
           :class="type?'divPostion':''"
           ref="tag"
           :style="{'transform': type?'translateX('+(-offset*removeWidth/cellRightWidth-(isElastic?elasticX/3:0))+'px)':'','padding-left':'10px','padding-right':10+(isElastic?Math.abs(elasticX/3):0)+'px','transition-duration':dragging?'0s':'0.6s','background':'#000'}">不再關(guān)注</div>
          <div
           :class="type?'divPostion':''"
           :style="{'transform': type?'translateX('+(-offset*(removeWidth+tagWidth)/cellRightWidth-(isElastic?elasticX/3*2:0))+'px)':'','padding-left':'10px','padding-right':10+(isElastic?Math.abs(elasticX/3):0)+'px','transition-duration':dragging?'0s':'0.6s'}">刪除</div>
         </div>
        </div>
       </div>
      </template>
      <script>
      import ClickOutside from 'vue-click-outside';
      import { TouchMixin } from '@/components/mixins/touch';
      export default{
       name:"SwipeCell",
       props: {
        // @deprecated
        // should be removed in next major version, use beforeClose instead
        onClose: Function,
        disabled: Boolean,
        leftWidth: [Number, String],
        rightWidth: [Number, String],
        beforeClose: Function,
        stopPropagation: Boolean,
        name: {
         type: [Number, String],
         default: '',
        },
        //
        type:{
         type:[Number,String],
         default:1 //0 常規(guī) 1 定位
        },
        isElastic:{ //彈性
         type:Boolean,
         default:true
        }
       },
       data(){
        return {
         offset: 0,
         dragging: true,
         //-位移
         elasticX:0,
         removeWidth:0,
         tagWidth:0,
         cellRightWidth:0,
         cellLeftWidth:0
        }
       },
       computed: {
        computedLeftWidth() {
         return +this.leftWidth || this.getWidthByRef('cellLeft');
        },

        computedRightWidth() {
         return +this.rightWidth || this.getWidthByRef('cellRight');
        },
       },
       mounted() {
        //防止彈性效果影響寬度
        this.cellRightWidth = this.getWidthByRef('cellRight');
        this.cellLeftWidth = this.getWidthByRef('cellLeft');
        this.removeWidth = this.getWidthByRef('remove');
        this.tagWidth = this.getWidthByRef('tag');
        this.bindTouchEvent(this.$el);
       },
       mixins: [
        TouchMixin
       ],
       directives: {
        ClickOutside
       },
       methods: {
        getWidthByRef(ref) {
         if (this.$refs[ref]) {
          const rect = this.$refs[ref].getBoundingClientRect();
          //type=1定位時(shí)獲取寬度為0,為此采用獲取子元素寬度之和
          if(!rect.width){
           let childWidth = 0;
           for(const item of this.$refs[ref].children){
            childWidth += item.getBoundingClientRect().width
           }
           return childWidth;
          }
          return rect.width;
         }
         return 0;
        },

        handleClickOutside(e){
         if(this.opened) this.close()
        },

        // @exposed-api
        open(position) {
         const offset =
         position === 'left' ? this.computedLeftWidth : -this.computedRightWidth;

         this.opened = true;
         this.offset = offset;

         this.$emit('open', {
          position,
          name: this.name,
          // @deprecated
          // should be removed in next major version
          detail: this.name,
         });
        },

        // @exposed-api
        close(position) {
         this.offset = 0;

         if (this.opened) {
          this.opened = false;
          this.$emit('close', {
           position,
           name: this.name,
          });
         }
        },

        onTouchStart(event) {
         if (this.disabled) {
          return;
         }
         this.startOffset = this.offset;
         this.touchStart(event);
        },

        range(num, min, max) {
         return Math.min(Math.max(num, min), max);
        },

        preventDefault(event, isStopPropagation) {
         /* istanbul ignore else */
         if (typeof event.cancelable !== 'boolean' || event.cancelable) {
          event.preventDefault();
         }

         if (this.isStopPropagations) {
          stopPropagation(event);
         }
        },

        stopPropagations(event) {
         event.stopPropagation();
        },

        onTouchMove(event) {
         if (this.disabled) {
          return;
         }
         this.touchMove(event);
         if (this.direction === 'horizontal') {
          this.dragging = true;
          this.lockClick = true;
          const isPrevent = !this.opened || this.deltaX * this.startOffset < 0;
          if (isPrevent) {
           this.preventDefault(event, this.stopPropagation);
          }
          
          this.offset = this.range(
           this.deltaX + this.startOffset,
           -this.computedRightWidth,
           this.computedLeftWidth
          );
          //增加彈性
          if(this.computedRightWidth && this.offset === -this.computedRightWidth || this.computedLeftWidth && this.offset === this.computedLeftWidth){
           //
           this.preventDefault(event, this.stopPropagation);
           //彈性系數(shù)
           this.elasticX = (this.deltaX + this.startOffset - this.offset)/4;
          }
         }else{
          //上下滑動(dòng)后取消close
          this.dragging = true;
          this.lockClick = true;
         }
        },

        onTouchEnd() {
         if (this.disabled) {
          return;
         }
         //回彈
         this.elasticX = 0
         if (this.dragging) {
          this.toggle(this.offset > 0 ? 'left' : 'right');
          this.dragging = false;
          // compatible with desktop scenario
          setTimeout(() => {
           this.lockClick = false;
          }, 0);
         }
        },

        toggle(direction) {
         const offset = Math.abs(this.offset);
         const THRESHOLD = 0.15;
         const threshold = this.opened ? 1 - THRESHOLD : THRESHOLD;
         const { computedLeftWidth, computedRightWidth } = this;

         if (
         computedRightWidth &&
         direction === 'right' &&
         offset > computedRightWidth * threshold
         ) {
          this.open('right');
         } else if (
         computedLeftWidth &&
         direction === 'left' &&
         offset > computedLeftWidth * threshold
         ) {
          this.open('left');
         } else {
          this.close();
         }
        },

        onClick(position = 'outside') {
         this.$emit('click', position);

         if (this.opened && !this.lockClick) {
          if (this.beforeClose) {
           this.beforeClose({
            position,
            name: this.name,
            instance: this,
           });
          } else if (this.onClose) {
           this.onClose(position, this, { name: this.name });
          } else {
           this.close(position);
          }
         }
        },

        getClickHandler(position, stop) {
         return (event) => {
          if (stop) {
           event.stopPropagation();
          }
          this.onClick(position);
         };
        },
       }
      }
      </script>
      <style lang="stylus" scoped>
      .cell_container{
       position: relative;
       overflow: hidden;
       line-height: 68px;
       height:68px;
       div{
        height: 100%;
        .cell_content{
         height: 100%;
         width: 100%;
         text-align: center;
        }
        .cell_content_active{
         height: 100%;
         width: 100%;
         text-align: center;
         &:active{
          background: #e8e8e8;
         }
        }
        .cell_left,.cell_right{
         position: absolute;
         top: 0;
         height: 100%;
         display: flex;
         color: #fff;
         .divPostion{
          position: absolute;
         }
         div{
          white-space:nowrap;
          display: flex;
          align-items: center;
          background: #ccc;
         }
        }
        .cell_left{
         left: 0;
         transform:translateX(-100%);
        }
        .cell_right{
         right: 0;
         transform:translateX(100%);
        }
       }
      }
      </style>

      touch.js

      import Vue from 'vue';
      export const isServer=false;
      const MIN_DISTANCE = 10;
      const TouchMixinData = {
       startX: Number,
       startY: Number,
       deltaX: Number,
       deltaY: Number,
       offsetX: Number,
       offsetY: Number,
       direction: String
      };

      function getDirection(x,y) {
       if (x > y && x > MIN_DISTANCE) {
       return 'horizontal';
       }

       if (y > x && y > MIN_DISTANCE) {
       return 'vertical';
       }

       return '';
      }


      export let supportsPassive = false;

      export function on(
       target,
       event,
       handler,
       passive = false
      ) {
       if (!isServer) {
       target.addEventListener(
        event,
        handler,
        supportsPassive ? { capture: false, passive } : false
       );
       }
      }

      export const TouchMixin = Vue.extend({
       data() {TouchMixinData
       return { direction: '' } ;
       },

       methods: {
       touchStart() {
        this.resetTouchStatus();
        this.startX = event.touches[0].clientX;
        this.startY = event.touches[0].clientY;
       },

       touchMove() {
        const touch = event.touches[0];
        this.deltaX = touch.clientX - this.startX;
        this.deltaY = touch.clientY - this.startY;
        this.offsetX = Math.abs(this.deltaX);
        this.offsetY = Math.abs(this.deltaY);
        this.direction =
        this.direction || getDirection(this.offsetX, this.offsetY);
       },

       resetTouchStatus() {
        this.direction = '';
        this.deltaX = 0;
        this.deltaY = 0;
        this.offsetX = 0;
        this.offsetY = 0;
       },

       // avoid Vue 2.6 event bubble issues by manually binding events
       //https://github.com/youzan/vant/issues/3015

       bindTouchEvent( el ) {

        const { onTouchStart, onTouchMove, onTouchEnd } = this;

        on(el, 'touchstart', onTouchStart);
        on(el, 'touchmove', onTouchMove);

        if (onTouchEnd) {
        on(el, 'touchend', onTouchEnd);
        on(el, 'touchcancel', onTouchEnd);
        }
       },
       },
      });

      引入即可?。?!

      到此這篇關(guān)于vue swipeCell滑動(dòng)單元格(仿微信)的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)vue swipeCell滑動(dòng)單元格內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

      來源:腳本之家

      鏈接:https://www.jb51.net/article/195575.htm

      申請(qǐng)創(chuàng)業(yè)報(bào)道,分享創(chuàng)業(yè)好點(diǎn)子。點(diǎn)擊此處,共同探討創(chuàng)業(yè)新機(jī)遇!

      相關(guān)文章

      熱門排行

      信息推薦