vue中实现dom-observe自定义指令

  • 邢毅彪
  • 9 Minutes
  • 2019年10月14日

前言

一般情况下, 我们需要获得某dom元素的大小,并且希望该dom元素大小因为窗口大小或其他原因而改变大小之后重新获取,此时最常用的是在window.onresize中注册回调。但是在复杂布局,或者其他原因导致window.resize事件触发时,需要监听的dom元素并没有改变大小,此时获得的大小还是改变之前的问题。此时可以解除ResizeObserver这个API来实现。基于此背景, 为了方便操作,将该API封装成vue的指令,以便更方便的使用

实现

实现的话,就比较简单,可以借助MSDN的例子实现。借助polyfill可以兼容至IE9
Build Status
具体实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// vue-dom-observe.directive.ts
import ResizeObserver from 'resize-observer-polyfill';
import { DirectiveOptions } from 'vue';

const directive: DirectiveOptions = {
inserted(el, binding) {
const $domObserve = new ResizeObserver((entries) => {
entries.forEach((entry) => {
if (typeof binding.value === 'function') {
binding.value(entry.contentRect);
}
});
});
$domObserve.observe(el);
// eslint-disable-next-line no-param-reassign
(el as any).$domObserve = $domObserve;
},
unbind(el) {
((el as any).$domObserve as ResizeObserver).unobserve(el);
},
};

export default directive;

1
2
3
4
5
6
7
8
// index.ts
import { VueConstructor } from 'vue';
import DomObserve from './vue-dom-observe.directive';


export default function install(Vue: VueConstructor) {
Vue.directive('dom-observe', DomObserve);
}

用法

此包已经发布至npm,可以直接下载安装使用即可

1
npm install --save vue-dom-observe

1
2
3
4
// main.js
import domObserve from 'vue-dom-observe';

Vue.use(domObserve);
1
2
3
4
5
6
7
8
9
10
11
12
<template>
<div v-dom-observe="handlerSizeChange"></div>
</template>
<script>
export defalut {
methods: {
handlerSizeChange(e) {
console.log(e)
}
}
}
</script>

写在最后

实现这个指令本身还是比较简单的,打包选择的是rollup,非常适合作为库的打包器。配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import typescript from 'rollup-plugin-typescript2';

export default {
input: './src/index.ts',
output: {
name: 'umd',
file: './dist/index.js',
format: 'umd',
},
plugins: [
typescript({ compilerOptions: { declaration: true } })
],
extends: ['vue']
}

访问量