vue 2によるアップロード機能の実現


本論文の例では、Vue 2のアップロードを実現するための具体的なコードを共有します。
私たちのプロジェクトの中でスウィートを使ったからです。多くはスライドスイッチですが、またアップロードしなければなりませんので、多くのUIフレームを使っています。全部違ったバグが現れました。しょうがないです。最後に一つ書きました。コードは以下の通りです。

<template>
  <div class="loadmore">
    <slot></slot>
    <slot name="bottom">
    </slot>
  </div>
</template>

<style>
  .loadmore{
    width:100%;
  }
</style>

<script>
  export default {
    name: 'loadmore',
    props: {
      maxDistance: {
        type: Number,
        default: 0
      },
      autoFill: {
        type: Boolean,
        default: true
      },
      distanceIndex: {
        type: Number,
        default: 2
      },
      bottomPullText: {
        type: String,
        default: '    '
      },
      bottomDropText: {
        type: String,
        default: '    '
      },
      bottomLoadingText: {
        type: String,
        default: '   ...'
      },
      bottomDistance: {
        type: Number,
        default: 70
      },
      bottomMethod: {
        type: Function
      },
      bottomAllLoaded: {
        type: Boolean,
        default: false
      },
    },
    data() {
      return {
        //       div   
        translate: 0,
        //            
        scrollEventTarget: null,
        containerFilled: false,
        bottomText: '',
        // class  
        bottomDropped: false,
        //          scrollTop
        bottomReached: false,
        //        down---    ;up---    
        direction: '',
        startY: 0,
        startScrollTop: 0,
        //    clientY  
        currentY: 0,
        topStatus: '',
        //          ''   pull:    
        bottomStatus: '',
      };
    },
    watch: {
      //          
      bottomStatus(val) {
        this.$emit('bottom-status-change', val);
        switch (val) {
          case 'pull':
            this.bottomText = this.bottomPullText;
            break;
          case 'drop':
            this.bottomText = this.bottomDropText;
            break;
          case 'loading':
            this.bottomText = this.bottomLoadingText;
            break;
        }
      }
    },
    methods: {
      onBottomLoaded() {
        this.bottomStatus = 'pull';
        this.bottomDropped = false;
        this.$nextTick(() => {
          if (this.scrollEventTarget === window) {
          document.body.scrollTop += 50;
        } else {
          this.scrollEventTarget.scrollTop += 50;
        }
        this.translate = 0;
      });
        //   
        if (!this.bottomAllLoaded && !this.containerFilled) {
          this.fillContainer();
        }
      },

      getScrollEventTarget(element) {
        let currentNode = element;
        while (currentNode && currentNode.tagName !== 'HTML' &&
        currentNode.tagName !== 'BODY' && currentNode.nodeType === 1) {
          let overflowY = document.defaultView.getComputedStyle(currentNode).overflowY;
          if (overflowY === 'scroll' || overflowY === 'auto') {
            return currentNode;
          }
          currentNode = currentNode.parentNode;
        }
        return window;
      },
      //   scrollTop
      getScrollTop(element) {
        if (element === window) {
          return Math.max(window.pageYOffset || 0, document.documentElement.scrollTop);
        } else {
          return element.scrollTop;
        }
      },
      bindTouchEvents() {
        this.$el.addEventListener('touchstart', this.handleTouchStart);
        this.$el.addEventListener('touchmove', this.handleTouchMove);
        this.$el.addEventListener('touchend', this.handleTouchEnd);
      },
      init() {
        this.bottomStatus = 'pull';
        //            
        this.scrollEventTarget = this.getScrollEventTarget(this.$el);
        if (typeof this.bottomMethod === 'function') {
          // autoFill          
          this.fillContainer();
          //       
          this.bindTouchEvents();
        }
      },
      // autoFill          
      fillContainer() {
        if (this.autoFill) {
          this.$nextTick(() => {
            if (this.scrollEventTarget === window) {
            this.containerFilled = this.$el.getBoundingClientRect().bottom >=
                document.documentElement.getBoundingClientRect().bottom;
          } else {
            this.containerFilled = this.$el.getBoundingClientRect().bottom >=
                this.scrollEventTarget.getBoundingClientRect().bottom;
          }
          if (!this.containerFilled) {
            this.bottomStatus = 'loading';
            this.bottomMethod();
          }
        });
        }
      },
      //          scrollTop
      checkBottomReached() {
        if (this.scrollEventTarget === window) {
          return document.body.scrollTop + document.documentElement.clientHeight >= document.body.scrollHeight;
        } else {
          // getBoundingClientRect             , ,               。 right                ,bottom                。
          return this.$el.getBoundingClientRect().bottom <= this.scrollEventTarget.getBoundingClientRect().bottom + 1;
        }
      },
      // ontouchstart   
      handleTouchStart(event) {
        //      y  
        this.startY = event.touches[0].clientY;
        this.startScrollTop = this.getScrollTop(this.scrollEventTarget);
        this.bottomReached = false;
        if (this.bottomStatus !== 'loading') {
          this.bottomStatus = 'pull';
          this.bottomDropped = false;
        }
      },
      // ontouchmove  
      handleTouchMove(event) {
        if (this.startY < this.$el.getBoundingClientRect().top && this.startY > this.$el.getBoundingClientRect().bottom) {
          //              ,    scroll
          return;
        }
        //    clientY  
        this.currentY = event.touches[0].clientY;
        // distance                 distanceIndex---
        let distance = (this.currentY - this.startY) / this.distanceIndex;
        //    distance                direction down---    ;up---    
        this.direction = distance > 0 ? 'down' : 'up';
        if (this.direction === 'up') {
          //          scrollTop
          this.bottomReached = this.bottomReached || this.checkBottomReached();
        }
        if (typeof this.bottomMethod === 'function' && this.direction === 'up' &&
            this.bottomReached && this.bottomStatus !== 'loading' && !this.bottomAllLoaded) {
          //      ,    ,     ,      ajax,         
          event.preventDefault();
          event.stopPropagation();
          if (this.maxDistance > 0) {
            this.translate = Math.abs(distance) <= this.maxDistance
                ? this.getScrollTop(this.scrollEventTarget) - this.startScrollTop + distance : this.translate;
          } else {
            this.translate = this.getScrollTop(this.scrollEventTarget) - this.startScrollTop + distance;
          }
          if (this.translate > 0) {
            this.translate = 0;
          }
          this.bottomStatus = -this.translate >= this.bottomDistance ? 'drop' : 'pull';
        }
      },
      // ontouchend  
      handleTouchEnd() {
        if (this.direction === 'up' && this.bottomReached && this.translate < 0) {
          this.bottomDropped = true;
          this.bottomReached = false;
          if (this.bottomStatus === 'drop') {
            this.translate = '-50';
            this.bottomStatus = 'loading';
            this.bottomMethod();
          } else {
            this.translate = '0';
            this.bottomStatus = 'pull';
          }
        }
        this.direction = '';
      }
    },
    mounted() {
      this.init();
    }
  };
</script>
どのページが必要ですか?どのページに導入すればいいですか?彼を紹介したいページの書き方は以下の通りです。

<template>
 <section class="finan">
  <!--        -->
  <load-more
  :bottom-method="loadBottom"
  :bottom-all-loaded="allLoaded"
  :bottomPullText='bottomText'
  :auto-fill="false"
  @bottom-status-change="handleBottomChange"
  ref="loadmore">
    <div>
              
    </div>
    <div v-show="loading" slot="bottom" class="loading">   div                 gif 
     <img src="./../../assets/main/uploading.gif">
    </div>
  </load-more>
 </section>
</template>
このページのdata里とmethodsは以下のように設定されています。

  export default {
    name: 'FinancialGroup',
    props:{
 
    },
    data () {
      return {
        //       
        scrollHeight: 0,
        scrollTop: 0,
        containerHeight: 0,
        loading: false,
        allLoaded: false,
        bottomText: '      ...',
        bottomStatus: '',
        pageNo: 1,
        totalCount: '',
      }
    },
    methods: {
    /*      */
    _scroll: function(ev) {
      ev = ev || event;
      this.scrollHeight = this.$refs.innerScroll.scrollHeight;
      this.scrollTop = this.$refs.innerScroll.scrollTop;
      this.containerHeight = this.$refs.innerScroll.offsetHeight;
    },
    loadBottom: function() {
      this.loading = true;
      this.pageNo += 1;  //          
      if (this.pageNo == this.totalGetCount) {
        //  allLoaded = true       
        this.loading = false;
        this.allLoaded = true;
      }
      api.commonApi(    ,    )   api    axios       vue2+vuex+axios    
          .then(res => {
        setTimeout(() => {
                   setTimeout  
         this.$nextTick(() => {
          this.loading = false;
        })
      }, 1000)
     });
    },
    handleBottomChange(status) {
      this.bottomStatus = status;
    },
  }
これで完成です。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。