• Vue3封装自定义指令和hooks,并发布npm包


    需求:封装一个函数要求监听DOM的宽高变化,并且支持自定义指令和hooks两种用法。

    第一步:创建项目文件夹v-resize-xm

    1.在v-resize-xm文件夹里面创建src文件夹

    执行 pnpm init 命令 生成一个package.json文件

    2.安装一下ts

    sudo npm install -g typescript

    3.执行 tsc --init生成一个 tsconfig.json 文件

    4.在v-resize-xm文件夹下新建一个vite.config.ts文件

    5.在v-resize-xm文件夹下新建一个index.d.ts声明文件

    6.安装vue, 执行 pnpm install vue@3.2.47 -D (因为最终使用这个插件的用户他本地有vue)

    7.安装vite, 执行 pnpm install vite@4.2.1 -D   (因为最终使用这个插件的用户他本地有vite)

    编写v-resize-xm\src\index.ts业务文件

    1. import type { App } from 'vue';
    2. // 侦听元素宽高的变化
    3. // Hooks
    4. function useResize (el:HTMLElement, callback:Function) {
    5. let resize = new ResizeObserver((entries) => {
    6. // entries 是数组, 默认监听多个
    7. callback(entries[0].contentRect); // 将框高回传回去
    8. })
    9. resize.observe(el)
    10. }
    11. let app = createApp(); // 创建一个app出来
    12. // vue插件使用如
    13. // app.use(router).use(xxx); // 等
    14. // 这个use实际上就是调用了底层的一个install方法
    15. // vue插件就是要去实现install函数, 他就要就调用, 并且将这个app注入进去, 它的类型就是vue里面引入的App
    16. // 自定义指令
    17. const install = (app:App) => { // 最终给app提供一个install方法
    18. // 拿到这个app之后就可以去创建directive指令了
    19. app.directive('resize', {
    20. // 第一个参数是html元素, 第二个参数是binding对象,这个对象可以要求它传入一个函数
    21. mounted(el, binding) {
    22. // 刚好复用一下useResize
    23. // 指令的挂载
    24. useResize(el, binding.value);
    25. }
    26. })
    27. }
    28. // 将 install 注册到函数上面
    29. useResize.install = install;
    30. export default useResize;

    第二步:在vite.config.ts里面配置一些打包的库

    1. import { defineConfig } from 'vite';
    2. // umd 支持amd cmd cjs 全局变量模式
    3. export default defineConfig({
    4. // 开发vue3库模式文档 https://cn.vitejs.dev/guide/build.html#library-mode
    5. build:{
    6. lib:{
    7. entry:'./src/index.ts', // 入口
    8. name: 'useResize' // name和hooks名称一样就可以了
    9. },
    10. // 透传一些属性给rollup
    11. rollupOptions:{
    12. // 因为这是vue插件,用户本地已经有Vue环境了,此处Vue没必要打到包里面
    13. external:['vue'],
    14. output:{
    15. globals:{
    16. useResize: 'useResize' // 提供一个全局变量给umd库用
    17. }
    18. }
    19. }
    20. }
    21. })

    第三步: 在package.json里面配置一些命令

    "build": "vite build"

    1. {
    2. "name": "v-resize-xm",
    3. "version": "1.0.0",
    4. "description": "",
    5. "main": "index.js",
    6. "scripts": {
    7. "test": "echo \"Error: no test specified\" && exit 1",
    8. "build": "vite build"
    9. },
    10. "keywords": [],
    11. "author": "",
    12. "license": "ISC",
    13. "devDependencies": {
    14. "vue": "3.2.47"
    15. }
    16. }

    执行npm run build构建dist包

    我们看到dist目录打出来两个文件

    v-resize-xm.mjs ES模式

    v-resize-xm.umd.js 其他模式

    第四步:编写ts声明文件 index.d.ts

    1. declare const useResize: {
    2. (el: HTMLElement, callback: Function): void;
    3. install: (app: App) => void;
    4. };
    5. export default useResize;

    第五步:发布npm包

    1.配置package.json的main属性,这个main一般就是require对应的目录

    "main": "dist/v-resize-xm.umd.js",  umd它是支持commonJs规范的

    2.配置package.json的module属性,这个module就是支持ES6的import引入

    "module": "dist/v-resize-xm.mjs",

    3.配置package.json的files数组属性

    这里表示发往npm的目录,我们将dist目录和声明文件发上去

    "files": [ "dist", "index.d.ts"],

    4.修正版本号

    "version": "1.0.1",

    1. {
    2. "name": "v-resize-xm",
    3. "version": "1.0.0",
    4. "description": "",
    5. "main": "dist/v-resize-xm.umd.js",
    6. "module": "dist/v-resize-xm.mjs",
    7. "scripts": {
    8. "test": "echo \"Error: no test specified\" && exit 1",
    9. "build": "vite build"
    10. },
    11. "keywords": [],
    12. "author": "",
    13. "files": [ "dist", "index.d.ts"],
    14. "license": "ISC",
    15. "devDependencies": {
    16. "vue": "3.2.47"
    17. }
    18. }

    5.  注册npm账号

    npm注册地址

    6.执行 npm adduser 命令添加npm账号

    7.执行 npm login  命令登录

    8.执行 npm publish 命令发布

    9. 到npm官网搜索查看

    第六步:测试使用发布的库

    1.  在vue3 项目环境下执行 pnpm install 库名称 -S

    Hooks用法