Vue项目实现web端飘窗

开发背景:项目使用了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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值