20190225 vue的定时任务信息整理

1.Vue定时任务setInterval

使用时,只需要加上  setInterval  即可,如下:

mounted() {
            this.getElevatorList();
            setInterval(this.getElevatorList, 15000);

        }

在mounted()函数里边使用setInterval(),       getElevatorList()这个方法在methods里边写,在mounted钩子函数里边调用就可以,刚开始先调用一遍,加载。然后使用setInterval(),第一个参数,调用方法的时候,不加括号,第二个参数是时间。

 

2.实例:

<template lang="html">
  <div v-loading="isLoading">
    <div class="div-a">
      <el-row>
        <el-col :span="12" v-for="(item, index) in dataList" :key="index">
          <div class="image" :style="'height:' + itemBlockHeight + 'px'">
            <div class="item-tag">
              <span><b>创建时间:</b>{{item.createTime | TimeFormat}}</span>
              <span><b>上传用户:</b>{{item.userName}}</span>
            </div>
            <div class="video-container" v-if="item.type == 2">
              <video controls="controls" autoplay="autoplay" muted>
                <source :src="item.fileUrl" type="video/ogg">
                <source :src="item.fileUrl" type="video/mp4">
                Your browser does not support the video tag.
              </video>
            </div>
            <div class="image-container" v-else>
              <img :src="item.fileUrl" @click="handleImagePreview(item.imgMap.colour)">
            </div>
          </div>
        </el-col>
      </el-row>
      <div class="alert-container" v-if="showAlertContainer">
        <el-button v-if="contentType == 'history' " size="small" class="history-btn" type="warning" @click="handleSwitch('current')">当前报警</el-button>
        <el-button v-else size="small" class="history-btn" type="warning" @click="handleSwitch('history')">历史报警</el-button>
        <el-button :loading="isClosing" size="small" class="history-btn second" type="danger" @click="handleCloseAlert()">关闭当前报警</el-button>
        <img class="close-btn" src="../../../assets/close.png" @click="closeAlertModal()" />
        <div class="alert-content" v-if="contentType == 'current' ">
          <div class="mobile">
            <div class="item-tag">
              <span><b>区域:</b>{{WarningCondition.areaInfoName}}</span>
              <span><b>报警信息名称:</b>{{WarningCondition.name}}</span>
              <span><b>报警时间:</b>{{WarningCondition.createTime | TimeFormat}}</span>
              <span>
                <b>报警触发条件:</b> {{WarningCondition.type==1?'人员':'车辆'}} 大于 {{ WarningCondition.threshold }}
              </span>
            </div>
            <div class="video-container" v-if="alertInfo.type == 2">
              <video controls="controls" autoplay="autoplay" muted>
                <source :src="alertInfo.fileUrl" type="video/ogg">
                <source :src="alertInfo.fileUrl" type="video/mp4">
                Your browser does not support the video tag.
              </video>
            </div>
            <div class="image-container" v-else>
              <img :src="alertInfo.fileUrl">
            </div>
          </div>
        </div>
        <div class="alert-content" v-else>
          <el-row style="padding: 30px 0;">
            <el-col :span="20" :offset="2">
              <el-table
                :data="alertHistoryData"
                border
                v-loading.body="isTableLoading"
                style="width: 100%">
                <el-table-column
                  label="报警名称">
                  <template scope="scope">
                    <span style="margin-left: 10px">{{ scope.row.warningCondition.name }}</span>
                  </template>
                </el-table-column>
                <el-table-column
                  label="报警位置">
                  <template scope="scope">
                    <span style="margin-left: 10px">{{ scope.row.address }}</span>
                  </template>
                </el-table-column>
                <el-table-column
                  label="报警区域">
                  <template scope="scope">
                    <span style="margin-left: 10px">{{ scope.row.areaInfoName }}</span>
                  </template>
                </el-table-column>
                <el-table-column
                  label="报警级别">
                  <template scope="scope">
                    <span style="margin-left: 10px">{{ scope.row.hazardLevel }} 级</span>
                  </template>
                </el-table-column>
                <el-table-column
                  label="报警类型">
                  <template scope="scope">
                    <el-tag v-if=" scope.row.warningCondition.type == 1 " type="success">人员</el-tag>
                    <el-tag v-if=" scope.row.warningCondition.type == 2 " type="primary">车辆</el-tag>
                  </template>
                </el-table-column>
                <el-table-column
                  label="报警数值">
                  <template scope="scope">
                    <el-tag type="warning">{{scope.row.warningCondition.threshold}}</el-tag>
                  </template>
                </el-table-column>
                <el-table-column
                  label="创建时间">
                  <template scope="scope">
                    <span style="margin-left: 10px">{{ scope.row.createTime | TimeFormat }}</span>
                  </template>
                </el-table-column>
              </el-table>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24" style="text-align:center">
              <el-pagination
                style="text-align:center;"
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                :current-page="alertHistoryPageNum"
                :page-sizes="[5, 10, 20, 50]"
                :page-size="alertHistoryPageSize"
                layout="total, sizes, prev, pager, next, jumper"
                :total="alertHistoryTotalCount">
              </el-pagination>
            </el-col>
          </el-row>
        </div>
      </div>

    </div>

    <div class="div-b">
      <div class="wrapper" >
        <!--<div class="btn-ground">
          <a href="javascript:;">圆形</a>
          <a href="javascript:;">正方形</a>
          <a href="javascript:;">点</a>
          <a href="javascript:;">直线</a>
        </div>-->
        <div class="div1"></div>
      </div>
    </div>
  </div>
</template>

<script>

import { mapActions } from 'vuex'
import eventHub from '@/eventHub'
import VideoBox from '@/components/common/VideoBox'
import Promise from 'bluebird'
import _ from 'lodash'
/*鼠标画图*/
//声明变量
var wId = "w";
var index = 0;
var startX = 0,startY = 0;
var flag = false;
var retcLeft = "0px", retcTop = "0px", retcHeight = "0px", retcWidth = "0px";

var $ = function(id){
  return document.getElementById(id);
}

export default {
  data(){
    let height = document.body.clientHeight;
    let itemBlockHeight = height / 2;
    return {
      isStoping:false,
      dataList: [],
      pageSize: 4,
      pageNum: 1,
      totalCount:0,
      isLoading: false,
      carouselTime: 10,
      carouselIndex: null,
      itemBlockHeight: itemBlockHeight,
      showAlertContainer:false,
      checkAlertCarousel:null,
      alertInfo:{},
      isClosing:false,
      alertHistoryData: [],
      contentType:'current',
      alertHistoryPageSize: 10,
      alertHistoryPageNum: 1,
      alertHistoryTotalCount:0,
      isTableLoading:false,
      WarningCondition:{}
    }
  },
  components:{
    VideoBox
  },
  mounted(){
    this.isLoading = true;
    Promise.all([
      this.getResource({
        pageSize: this.pageSize,
        pageNum: this.pageNum
      }),
      this.getAlertHistory({
        type:4,
        pageSize:this.alertHistoryPageSize,
        pageNum:this.alertHistoryPageNum
      })
    ])
    .spread((result, alertHistory)=>{

      this.alertHistoryData = alertHistory.resultData;
      this.alertHistoryTotalCount = alertHistory.totalCount;


      this.totalCount = result.totalCount;
      this.dataList = result.resultData;
      this.isLoading = false;
      if(result.resultData.length == 4){
        this.carousel();
      }
    },()=>{
      this.isLoading = false;
      this.$message.error('数据加载失败!');
    });

    this.checkAlertCarousel = setInterval(()=>{
      // 1 摄像头; 2:无人机; 3卫星; 4移动端
      this.checkAlertStatus({deviceType:4})
      .then((result)=>{
        if(result.data){
          this.alertInfo = result.data;
          this.WarningCondition = result.WarningCondition;
          this.showAlertContainer = true;
        }
        if(result.warningDeviceType){
          this.isStoping = true;
          clearInterval(this.carouselIndex)
        }else{
          if(this.isStoping) {
            this.carousel();
          }
          this.isStoping = false;
        }
      },()=>{})
    },5000);

    /*鼠标画图*/
    const vm = this;
    let dom = document.querySelector(".div1");
    //鼠标按下时发生的事件
    document.onmousedown = function(e){
      flag = true;
      try{
        var evt = window.event || e;
        var scrollTop = (document.body.scrollTop || document.documentElement.scrollTop);//上边 设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离
        var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;//左边 获取对象相对于版面或由 offsetParent 属性指定的父坐标的计算左侧位置
        startX = evt.clientX + scrollLeft;
        startY = evt.clientY + scrollTop;
        index++;
        //开始创建div,设置div的各种属性
        var div = document.createElement("div");
        div.id = wId + index;
        div.className = "div";
        div.style.marginLeft = startX + "px";
        div.style.marginTop = (evt.clientY-120) + "px";
        dom.appendChild(div);
      }catch(e){
      }
    }

    //鼠标放开事件
    document.onmouseup = function(){
      try{
        dom.removeChild($(wId + index));
        var div = document.createElement("div");
        div.className = "retc";
        div.style.marginLeft = retcLeft;
        div.style.marginTop = (parseInt(retcTop)-120)+"px";
        div.style.width = retcWidth;
        div.style.height = retcHeight;
        dom.appendChild(div);
        var w = parseInt(retcWidth.substring(0,retcWidth.length-2));
        var h = parseInt(retcHeight.substring(0,retcHeight.length-2));
        var x1 = parseInt(retcLeft.substring(0,retcLeft.length-2));
        var y1 = parseInt(retcTop.substring(0,retcTop.length-2));
        var x2 = x1+w;
        var y3 = y1+h;
        console.log("顶点("+x1+","+y1+")");
        console.log("宽"+w);
        console.log("高"+h);
        console.log("p2("+x2+","+y1+")");
        console.log("p3("+x1+","+y3+")");
        console.log("p4("+x2+","+y3+")");
      }catch(e){
        //alert(e);
      }
      flag = false;
    }
    //鼠标移动时
    document.onmousemove = function(e){
      if(flag){
        try{
          var evt = window.event || e;
          var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
          var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
          retcLeft = (startX - evt.clientX - scrollLeft > 0 ? evt.clientX + scrollLeft : startX) + "px";
          retcTop = (startY - evt.clientY - scrollTop > 0 ? (evt.clientY + scrollTo) : startY) + "px";
          retcHeight = Math.abs(startY - evt.clientY - scrollTop) + "px";
          retcWidth = Math.abs(startX - evt.clientX - scrollLeft) + "px";
          $(wId + index).style.marginLeft = retcLeft;
          $(wId + index).style.marginTop = (parseInt(retcTop)-120)+"px";
          $(wId + index).style.width = retcWidth;
          $(wId + index).style.height = retcHeight;
        }catch(e){
          //alert(e);
        }
      }
    }
  },

  beforeRouteLeave(to, from, next) {
    clearInterval(this.carouselIndex)
    clearInterval(this.checkAlertCarousel)
    next()
  },
  methods:{
    ...mapActions([
      'closeAlert',
      'getResource',
      'getAlertHistory',
      'checkAlertStatus'
    ]),
    carousel(){
      this.carouselIndex = setInterval(this.loadMore, 1000 * this.carouselTime);
    },
    handleSwitch(type){
      this.contentType = type;
    },
    handleCloseAlert(){
      this.isClosing = true;
      this.closeAlert()
      .then(()=>{
        this.isClosing = false;
        this.showAlertContainer = false;
        eventHub.$emit('show-videobox');
        this.$message({
          message: '报警关闭成功',
          type: 'success'
        });
        this.alertInfo = {};
      },()=>{
        this.isClosing = false;
        this.$message({
          message: '报警关闭失败',
          type: 'error'
        });
      })
    },
    closeAlertModal(){
      this.closeAlert();
      this.showAlertContainer = false;
    },
    loadMore(){
      this.pageNum = this.pageNum + 1;
      this.getResource({
        pageSize: this.pageSize,
        pageNum: this.pageNum
      })
      .then((result) => {
        if(result.resultData.length > 0) this.dataList = _.concat(result.resultData, _.slice(this.dataList, 0, 4 - result.resultData.length));
        if(this.pageSize * this.pageNum >= this.totalCount) this.pageNum = 0;
      }, () => {
        this.$message.error('数据加载失败!');
      })
    },
    handleSizeChange(pageSize){
      this.alertHistoryPageSize = pageSize;
      this.alertHistoryPageNum = 1;
      this.isTableLoading = true;
      this.getAlertHistory({
        type:2,
        pageSize:this.alertHistoryPageSize,
        pageNum:this.alertHistoryPageNum
      })
      .then((result) => {
        this.isTableLoading = false;
        this.alertHistoryTotalCount = result.totalCount;
        this.alertHistoryData = result.resultData;
      }, () => {
        this.isTableLoading = false;
        this.$message.error('列表加载失败!');
      })
    },
    handleCurrentChange(pageNum){
      this.alertHistoryPageNum = pageNum;
      this.isTableLoading = true;
      this.getAlertHistory({
        type:2,
        pageSize:this.alertHistoryPageSize,
        pageNum:this.alertHistoryPageNum
      })
      .then((result) => {
        this.isTableLoading = false;
        this.alertHistoryTotalCount = result.totalCount;
        this.alertHistoryData = result.resultData;
      }, () => {
        this.isTableLoading = false;
        this.$message.error('列表加载失败!');
      })
    }
  }
}


</script>

<style lang="less" scoped>
.image{
  height:100%;
  overflow:hidden;
  position:relative;
  overflow:hidden;
  padding-top:30px;
  box-sizing:border-box;
  .item-tag{
    display:flex;
    padding:0 10px;
    justify-content:space-between;
    align-items:center;
    color:#ffffff;
    position:absolute;
    left:0;
    right:0;
    top:0;
    height:30px;
    background-color:rgba(0,0,0,0.5);
  }
  .video-container{
    position:absolute;
    left:0;
    right:0;
    top:30px;
    bottom:0;
    video{
      width: 100%;
      height:100%;
      // background-color: #000;
    }
  }
  .image-container{
    position:absolute;
    left:0;
    right:0;
    top: 30px;
    bottom:0;
    text-align:center;
    img{
      width: 100%;
      height: 100%;
    }
  }
}
.div-a{ position:absolute; left:0px; width:100%; height:100%;}
.div-b{ position:absolute; left:0px; width:100%; height:100%;}

/* body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{margin:0;padding:0} */
/* html{color:#000;overflow-y:scoll;overflow:-moz-scrollbars-vertical} */

</style>
<style>
  .wrapper{position: relative;width: 100%;height: 90%;margin-top: 60px}
  .btn-ground{position: absolute;top: 0;left: 0;right: 0;width: 100%;height:50px;padding-left: 20px;line-height: 50px;text-align: left;z-index:99;}
  .btn-ground a{display: inline-block;margin-left: 10px;height: 30px;border-radius: 10px;line-height: 30px;
    text-align: center;padding: 0 0px;color:white;background-color:#049ff1;text-decoration: none;}
  .div{position:absolute; border:1px dashed blue;left:0px; top:0; overflow:hidden;z-index: 9;margin: 0px}
  .retc{position:absolute; border:2px solid darkred; overflow:hidden;cursor: crosshair;}
</style>

3.vue 定时器的问题

在项目中,我们经常会使用到定时器setInterval(),可是很多时候我们会发现,即使我退出当前页面,定时器依然在工作,非常消耗内存,所以我们要进行手动清理:

将定时器保存在变量中,退出页面时清除变量

1.定义空的变量

data: function (){

  return {

    timer: null

  }

}

2.定义定时器

methods: {

  setTimer: function () {

    this.timer = setInterval( () => {

        .....  

      }, 1000)

  }

}

3.进入和退出时清除定时器

mounted() {

  clearInterval(this.timer)

},

distroyed: function () {

  clearInterval(this.timer)

}

4.Vue中使用定时器setInterval和setTimeout

参考链接:https://www.cnblogs.com/jin-zhe/p/10001236.html 

js中定时器有两种,一个是循环执行setInterval,另一个是定时执行setTimeout

一、循环执行(setInterval)

顾名思义,循环执行就是设置一个时间间隔,每过一段时间都会执行一次这个方法,直到这个定时器被销毁掉

用法是setInterval(“方法名或方法”,“延时”), 第一个参数为方法名或者方法,注意为方法名的时候不要加括号,第二个参数为时间间隔

<template>
  <section>
    <h1>hello world~</h1>
  </section>
</template>
<script>
  export default {
    data() {
      return {
        timer: '',
        value: 0
      };
    },
    methods: {
      get() {
        this.value ++;
        console.log(this.value);
      }
    },
    mounted() {
      this.timer = setInterval(this.get, 1000);
    },

    beforeDestroy() {
      clearInterval(this.timer);
    }

  };20190225 vue的定时任务信息整理
</script>

上面的例子就是页面初始化的时候创建了一个定时器setInterval,时间间隔为1秒,每一秒都会调用一次函数get,从而使value的值加一。

二、定时执行 (setTimeout)

定时执行setTimeout是设置一个时间,等待时间到达的时候只执行一次,但是执行完以后定时器还在,只是没有运行

用法是setTimeout(“方法名或方法”, “延时”); 第一个参数为方法名或者方法,注意为方法名的时候不要加括号,第二个参数为时间间隔

<template>
  <section>
    <h1>hello world~</h1>
  </section>
</template>
<script>
  export default {
    data() {
      return {
        timer: '',
        value: 0
      };
    },
    methods: {
      get() {
        this.value ++;
        console.log(this.value);
      }
    },
    mounted() {
      this.timer = setTimeout(this.get, 1000);
    },
    beforeDestroy() {
      clearTimeout(this.timer);
    }
  };

</script>

20190225 vue的定时任务信息整理

上面是页面初始化时候创建一个定时器setTimeout,只在1秒后执行一次方法。

定时器需要在页面销毁的时候清除掉,不然会一直存在!!!