开发背景:项目使用了Nuxt.js框架。Nuxt.js 是一个基于 Vue.js 的通用应用框架,具体查看关于 Nuxt.js - NuxtJS | Nuxt.js 中文网
一、封装飘窗组件FloatWindow.vue,放在目录/components下
<template>
<nuxt-link
v-if="visible"
class="float-window"
:style="{
left: `${left}px`,
top: `${top}px`,
width: `${width}px`,
height: `${height}px`
}"
:to="to"
target="_blank"
@mouseenter.native="stop"
@mouseleave.native="start"
>
<div class="float-window-close" @click.prevent="close">
<i></i>
<i></i>
</div>
<img :src="image" alt="">
</nuxt-link>
</template>
<script>
export default {
name: 'FloatWindow',
props: {
image: {
type: String,
required: true
},
width: {
type: Number,
required: true
},
height: {
type: Number,
required: true
},
to: {
type: String,
required: true
},
speed: {
type: Number,
default: 1000 / 60
}
},
data () {
return {
visible: false,
top: 0,
left: 0,
maxX: 0,
maxY: 0,
directionX: -1,
directionY: -1
}
},
mounted () {
this.setup()
this.top = window.innerHeight - this.height
this.left = window.innerWidth - this.width
this.visible = true
window.addEventListener('resize', this.setup)
this.start()
},
destroyed () {
this.close()
},
methods: {
/**
* 配置
*/
setup () {
this.maxX = window.innerWidth - this.width // X轴边界
this.maxY = window.innerHeight - this.height // Y轴边界
},
/**
* 开始移动
*/
start () {
this.timer = setInterval(this.move, this.speed)
},
/**
* 停止移动
*/
stop () {
clearInterval(this.timer)
},
/**
* 移动飘窗
*/
move () {
const rect = this.$el.getBoundingClientRect()
if (rect.x >= this.maxX) {
this.directionX = -1
} else if (rect.x <= 0) {
this.directionX = 1
}
if (rect.y >= this.maxY) {
this.directionY = -1
} else if (rect.y <= 0) {
this.directionY = 1
}
this.left += this.directionX
this.top += this.directionY
},
/**
* 关闭飘窗
*/
close () {
this.visible = false
window.removeEventListener('resize', this.setup)
clearInterval(this.timer)
}
}
}
</script>
<style lang="stylus" scoped>
.float-window
display block
transform translateZ(0)
position fixed
right 0
bottom 0
z-index 99
.float-window-close
position absolute
width 20px
height 20px
top 15px
right 15px
i
display block
width 2px
height 20px
background-color #FFF
border-radius 1px
transition 0.3s box-shadow
i:first-child
position relative
left 10px
transform rotate(-45deg)
i:last-child
position absolute
top 0
left 10px
transform rotate(45deg)
&:hover
i
box-shadow 0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)
img
width 100%
display block
</style>
二、在页面引入使用
1.页面组件引入并挂在到components
import FloatWindow from '@/components/FloatWindow.vue'
components: {
FloatWindow
},
2.页面上使用
<float-window :image="require('~/assets/img/float-ad.png')"
:width="317"
:height="212"
to="/test/index">
</float-window>
记录于2022-2-25