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);
}
};
</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>
上面是页面初始化时候创建一个定时器setTimeout,只在1秒后执行一次方法。
定时器需要在页面销毁的时候清除掉,不然会一直存在!!!