1. 程式人生 > 程式設計 >解決vue.js中settimeout遇到的問題(時間引數短效果不穩定)

解決vue.js中settimeout遇到的問題(時間引數短效果不穩定)

先看效果圖,這是彈窗效果,要求就是彈窗出現和消失時候不是很突兀,要有過渡效果。

解決vue.js中settimeout遇到的問題(時間引數短效果不穩定)

首先看彈窗出現的實現思路,先加一個beforeActive類,再加一個active類。我們看審查元素,一開始display:none;

解決vue.js中settimeout遇到的問題(時間引數短效果不穩定)

在beforeActive中display:block;只是background: transparent;然後在一定時間後再加上active類。問題就來了,在開啟彈窗程式碼中,如下圖,settimeout第二個引數小於60ms效果就會不穩定,有時候有過渡效果,有時候沒有過渡效果。

//      openbtn(){
//        let _this=this;
//        _this.show =true;
//        _this.isbeforeActive=true;
//        setTimeout(function(){
//          _this.isactive=true;
//        },60)
//      },

想了很久也沒明白,後來終於明白,原來是vue渲染是有生命週期的,本來是先渲染befeactive,再渲染active,如果間隔時間太短就一次拿出來渲染了,所以沒有效果。

在退出彈框時候這個時間小於600ms就顯得特快,200ms的退出時間顯得比60ms的進入還要急促很多,是因為退出等動畫執行完畢才可以,而一個動畫的執行需要300多,所以要用600ms

close_class(){
        let _this=this;
        _this.isactive=false;
        setTimeout(function(){
          _this.isbeforeActive=false;
          _this.show =false;
        },600)
      },

以下是完整程式碼

<template>
  <div>
    <button @click="openbtn">顯示</button>

    <div v-show="show">
      <div class="shenfenPop-page" v-bind:class="{beforeActive:isbeforeActive,active:isactive}" @click="cancel_all">
        <div class="pop-wrap" @click.stop="stop">
          <div class="pop-title">選擇您的身份
            <div class="pop-sure" id="pop-sure" @click="decision_click">確定</div>
            <div class="pop-cancel" id="pop-cancel" @click="close_click">取消</div>
          </div>
          <div class="pop-list">
            <ul>
              <li shenfen-id="jsptpl-style" v-for="(option,index) in options" @click.stop="add_class(index)" v-bind:class="{active:index==current}">
                <div class="pop-info">{{option.text}}</div>
                <div class="pop-desc">{{option.value}}</div>
                <div class="pop-arrow"></div>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>

  </div>
</template>

<script>
  export default {
    name: 'app',data() {
      return {
        show: false,current:1,isbeforeActive:false,isactive:false,options: [
          {"text": "房東","value": "房屋所有者,具備認證房本資質"},{"text": "轉租","value": "轉讓自己承租的房子"},{"text": "經紀人","value": "房產中介,擁有專業的展示空間"},{"text": "職業房東","value": "公寓經營者/多房源管理者"}
        ],};
    },mounted() {
    },computed: {},methods: {
      add_class(index){
        this.current=index;
      },stop(){

      },openbtn(){
        let _this=this;
        _this.show =true;
        _this.isbeforeActive=true;
        setTimeout(function(){
          _this.isactive=true;
        },60)
      },close_class(){
        let _this=this;
        _this.isactive=false;
        setTimeout(function(){
          _this.isbeforeActive=false;
          _this.show =false;
        },decision_click(){
        this.close_class();
      },close_click() {
        this.close_class();
      },cancel_all(){
        this.close_class();
      },},watch: {},};
</script>

<style lang="scss" type="text/scss">
  @import "../../../common/css/mixin";

  * {
    margin: 0px;
    padding: 0px;
    list-style: none
  }


  .shenfenPop-page {
    width: 100%;
    height: 100%;
    position: fixed;
    top: 0px;
    transition: all 0.4s ease;
  }

  .shenfenPop-page .pop-wrap {
    transition: all 0.4s ease;
    position: absolute;
    width: 100%;
    bottom: 0px;
    background: #ffffff;
  }

  .shenfenPop-page .pop-title {
    height: 1.2rem;
    background: #f9fafc;
    text-align: center;
    font-size: 0.37333rem;
    color: #999999;
    line-height: 1.2rem;
    position: relative;
  }

  .shenfenPop-page .pop-title:after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    border: 1px solid #e3e3e4;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    width: 200%;
    height: 200%;
    -webkit-transform: scale(0.5);
    transform: scale(0.5);
    -webkit-transform-origin: left top;
    transform-origin: left top;
  }

  .shenfenPop-page .pop-title .pop-sure,.shenfenPop-page .pop-title .pop-cancel {
    position: absolute;
    z-index: 1;
    width: 1.6rem;
    height: 1.2rem;
    line-height: 1.22667rem;
    color: #ff552e;
    top: 0px;
    right: 0px;
  }

  .shenfenPop-page .pop-title .pop-sure.pop-cancel,.shenfenPop-page .pop-title .pop-cancel.pop-cancel {
    right: auto;
    left: 0px;
    color: #7b7b7b;
  }

  .shenfenPop-page .pop-list {
    widtH: 100%;
  }

  .shenfenPop-page .pop-list ul {
    width: 9.33333rem;
    margin: 0 auto;
  }

  .shenfenPop-page .pop-list ul li {
    width: 100%;
    height: 1.86667rem;
    position: relative;
  }

  .shenfenPop-page .pop-list ul li:after {
    border-radius: 0px;
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    z-index: -1;
    border-bottom: 1px solid #f1f1f1;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    width: 200%;
    height: 200%;
    -webkit-transform: scale(0.5);
    transform: scale(0.5);
    -webkit-transform-origin: left top;
    transform-origin: left top;
  }

  .shenfenPop-page .pop-list ul li .pop-info {
    position: absolute;
    top: 0.4rem;
    font-size: 0.45333rem;
    color: #333333;
    left: 0.06667rem;
  }

  .shenfenPop-page .pop-list ul li .pop-desc {
    font-size: 0.32rem;
    position: absolute;
    left: 0.06667rem;
    top: 0.98667rem;
    color: #7b7b7b;
  }

  .shenfenPop-page .pop-list ul li .pop-arrow {
    position: absolute;
    right: 0.26667rem;
    width: 22px;
    height: 22px;
    top: 50%;
    margin-top: -11px;
    background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAASFBMVEUAAADHx87IyM7IyM7Kys/IyM7Jyc/IyNHKytHW1tb////Hx87IyM3IyM3IyM7IyM3Jyc7IyM7Jyc7Ly9HIyNPHx83IyM3Hx81MCBRBAAAAF3RSTlMA8qt/QttXOCQMAennw7+ZjYNtLBf2kCIzlTUAAAEGSURBVDjLjJFbbsMwDAQpUpIl+R07mfvftEBdFE7ih+ZzMSB2QfmgNLMOwbkw6NwUucKPHTu60Z+qTQ+EKfqUc/JxCkDfHKpJobVlHy3WgqaDBg5n+TPN5nBfXR6gqxywKjzeoxfYyfZi8Hq/+4xySnzub3uIckGE/97JYXKJ4ZJsKFqu5aLo3y9wq9ywOrbv9JjcYvTbujbfy7n93ThiUoExipSOpUZe6Io0BKki0MjMVCdPzKLEOjmiMuDrZM8ggVQnJ4I4cp2ccT+V1TkBAAAIxDD/rqMhOwPP0VZxtVED1urqKHXuCtJEtMI/b1UPOygoyAy+BoyD3IH5aGIE1Gp7aZaOAVpkFMUoYaaBAAAAAElFTkSuQmCC");
    background-size: cover;
  }

  .shenfenPop-page .pop-list ul li.active .pop-arrow {
    background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAAPFBMVEUAAAD/VS7/VjH/VzL/VS7/Vi//VS7/VS//VS//VS7/VS7/Vi//Vy//WjX/VS7/VS7/Yz//4tv/////m4Tfv1CvAAAAD3RSTlMA8UQ459nDv62lmYNtIpDE1s/TAAAA6klEQVQ4y53VS5KDMAwEUPmP7ZAmk/vfdRaZcoKITDO95ZWqjGVJdEKvJTmXSu1BpvEt4iOxeZOGjEPy9/Lrgq9Z1qP1Dkac1/aGSW57e8c0d7auru1xGj/+gzvHbv3DC4gsLxtA5XU7mcP5/HTbc3fGNrWPn6GbiMS5fWyjB0UCa4EgnbboUmmLKoW2KJJoiySOtnAf+Llpe8Bp2PHZsEhSFLAtilQobVpU6VDatOgSoPTO6o6OSps2jhZ9a8uijeZ/a2XVA897bdl8/cHyo4AfMtfHFz8Y+ZHLD/Ora4JfQPxq+//S5NfxLzPrWEC1LMpOAAAAAElFTkSuQmCC");
  }

  .shenfenPop-page.beforeActive {
    display: block;
    background: transparent;
  }

  .shenfenPop-page.beforeActive .pop-wrap {
    transform: translateY(100%);
  }

  .shenfenPop-page.active {
    /*background: rgba(0,0.7);*/
  }

  .shenfenPop-page.active .pop-wrap {
    transform: translateY(0);

  }

</style>

補充知識:setTimeout在vue中的正確使用

如下所示:

 mounted(){
  setTimeout(this.tishi(),5000) 
 },

這樣寫,發現直接就執行了tishi函式,而不是5s之後執行

修改為:

mounted(){
  let _this = this;
  setTimeout(() => {
   _this.tishi()
  },

以上這篇解決vue.js中settimeout遇到的問題(時間引數短效果不穩定)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。