directive全局定义侦听window.resize,局部绑定侦听宽高的变化

创建文件:/src/directive/winresize/winresize.js

定义directive事件,创建侦听事件返回元素宽高


// 实时监测窗口变化,返回当前元素的宽度和高度
// 调用方式 v-winresize="自定义接收函数"
const winresize = {
  bind: (el, binding, vnode) => {
    // bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作。
    function documentHandler(e) {
      if (binding.expression) {
        //返回当前元素的宽度和高度
        binding.value(el.offsetWidth, el.offsetHeight)
      }
    }
    // 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听
    el.__vueWindowsResize__ = documentHandler
    window.addEventListener('resize', documentHandler)
  },
  inserted: () => {
    // inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
  },
  update: () => {
    // update: 被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
  },
  componentUpdated: () => {
    // componentUpdated: 被绑定元素所在模板完成一次更新周期时调用。
  },
  unbind: (el, binding) => {
    // unbind: 只调用一次, 指令与元素解绑时调用。
    window.removeEventListener('onresize', el.__vueWindowsResize__)
    delete el.__vueWindowsResize__
  }
}
export default winresize

问题点:这种directive创建的侦听事件是全局定义的,如果多个元素同时绑定的时候,会被同步执行,特别注意在侦听点击事件的时候,任意一个被点击,其它的元素也会响应点击事件,这里需要在定义的侦听事件里做如下处理:判断点击的元素是否是本身,不是本身,则返回

    function documentHandler(e) {
      // 这里判断点击的元素是否是本身,不是本身,则返回
      if (!el.contains(e.target)) {
        return false
      }
      // 判断指令中是否绑定了函数
      if (binding.expression) {
        // 如果绑定了函数 则调用那个函数,此处binding.value就是handleClose方法
        binding.value(e)
      }
    }
    // 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听
    el.__vueClickOutside__ = documentHandler
    document.addEventListener('mouseup', el.__vueClickOutside__)

创建文件:/src/directive/winresize/index.js

绑定全局directive,通用的定义方式,方便后期扩展功能:

import Vue from 'vue'
// 加载文件
import winresize from './winresize'
// 绑定directive
Vue.directive('winresize', winresize)

编辑文件:/src/main.js

加入下面代码就完成了全局的定义,任意页面都可以对元素设置 v-winresize=""

import '@/directive/winresize'

实际调用代码如下:

<template>
    <div ref="mapwin" style="width: 100%; height: 100%;" v-winresize="setmapmainsize">
        <div style="width: 200px; height: 100%;">固定宽度的部分</div>
        <div :style="styledata">需要占满剩余空间的部分</div>
    </div>
</template>
<script>
export default {
  name: 'map',
  data() {
    return {
      winWidth: 0,
      winHeight: 0,
      styledata: {width:'', height: '100%'}
    }
  },
  methods: {
    setmapmainsize(_w, _h) {
      this.winWidth = _w
      this.winHeight = _h
      this.styledata = {
        width: this.winWidth + 'px',
        eight: '100%'
      }
    }
  },
  mounted: function () {
    // mounted 挂载结束状态
    // 设置元素的宽度和高度,一定要在挂载完成后来执行
    this.setmapmainsize(this.$refs.mapwin.offsetWidth, this.$refs.mapwin.offsetHeight) 
  }
}
</script>

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值