vue3中 Hook详解 Hook结合自定义指令

22,614次阅读
没有评论

共计 4358 个字符,预计需要花费 11 分钟才能阅读完成。

Vue3 的自定义的 hook

hook 是钩子的意思,看到“钩子”是不是就想到了钩子函数?事实上,hooks 还真是函数的一种写法。vue3 借鉴 react
hooks 开发出了 Composition API,所以也就意味着 Composition API 也能进行自定义封装 hooks。
vue3 中的 hooks
就是函数的一种写法,就是将文件的一些单独功能的 js 代码进行抽离出来,放到单独的 js 文件中,或者说是一些可以复用的公共方法 / 功能。其实
hooks 和 vue2 中的 mixin 有点类似,但是相对 mixins 而言,hooks 更清楚复用功能代码的来源, 更清晰易懂。

Vue3 hook 库: hook 官网

手写自定义 hook 案例一

1. 新建 hooks/iondex.ts 文件 
import { onMounted } from "vue"

type Options = {
    el: string
}
export default function (options: Options): Promise{ baseUrl: string }> {
    return new Promise((resolve) => {
        onMounted(() => {
            let img: HTMLImageElement = document.querySelector(options.el) as HTMLImageElement;
            img.onload = () => {
                resolve({
                    baseUrl: base64(img)
                })
            }
        })
        const base64 = (el: HTMLImageElement) => {
            const canvas = document.createElement('canvas')
            const ctx = canvas.getContext('2d')
            canvas.width = el.width;
            canvas.height = el.height;
            ctx?.drawImage(el, 0, 0, canvas.width, canvas.height)
            return canvas.toDataURL('image/png')
        }
    })


}
2. 在文件中使用
template>
    div>
        img
            id="img"
            width="300"
            height="300"
            src="../../assets/vue.svg"
            alt=""
        />
    /div>
/template>
script setup lang="ts">
import useBase64 from "../hooks/index"
useBase64({
    el: "img",
}).then((res) => {
    console.log(res.baseUrl)
})
/script>
style scoped lang="scss">/style>

3. 展示效果 在控制台显示 然后复制 base64 码 到浏览器 可显示图片

vue3 中 Hook 详解 Hook 结合自定义指令

手写自定义 hook 案例二

vue3 中 Hook 详解 Hook 结合自定义指令

需求:
实现一个函数同事支持 hook 和自定义指令 去监听 dom 宽高的变化 5w3h 八何分析法
1. 如何监听 dom 宽高变化
2. 如何用 vite 打包库
3. 如何发布 npm

  1. 新建工程 V-RESIZE-XM

新建 src/index.ts 文件
– 输入 pnpm init 终端命令 生成 package.json 配置文件
– 输入 tsc –init 终端名称 生成 tsconfig.json 配置文件
– 新建 vite.config.ts 文件
– 新建 index.d.ts 文件
– 安装 两个库 pnpm i vue -D pnpm i vite -D

  1. 进入 src/index.ts 文件中完成 hook

ResizeObserver 主要侦听元素宽高的变化
MutationObserver 主要侦听子集的变化 还有属性的变化 以及 增删改查
interSectionObserver 主要侦听元素是否在视口内


import type { App } from 'vue'
function useResize(el: HTMLElement, callback: Function) {
    let resize = new ResizeObserver((entries) => {
        callback(entries[0].contentRect)
    })
    resize.observe(el)
}

const install = (app: App) => {
    app.directive('resize', {
        mounted(el, binding) {
            useResize(el, binding.value)
        }
    })
}
useResize.install = install
export default useResize

3. 打包 成为一个库
在 vite.config.ts 文件中配置

import { defineConfig } from 'vite'

export default defineConfig({
    build: {
        lib: {
            entry: 'src/index.ts',
            name: 'userResize',
        },
        rollupOptions: {
            
            external: ['vue'],
            output: {
                
                globals: {
                    useResize: 'useResize'
                }
            }
        }
    }
})

4. 修改 package.json 文件

{
  "name": "v-resize-xm",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo"Error: no test specified"&& exit 1",
    "build":"vite build"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "vite": "^5.2.11",
    "vue": "^3.4.26"
  }
}

5.npm run build 命令后 打包
vue3 中 Hook 详解 Hook 结合自定义指令
6. 在 index.d.ts 编写声明文件

declare const useResize: {
    (el: HTMLElement, callback: Function): void;
    install: (app: App) => void
};

export default useResize
  1. 准备就绪 发布 npm 需要配置 package.json
当使用 importexport  的时候 它会去找对应的 module
	当使用 require 的时候 它会去找对应的 main
	然后配置 files 是往 npm 上发布的目录
	修改版本 因为是第一次发布 改成 0.0.1
{
  "name": "v-resize-xm",
  "version": "0.0.1",
  "description": "",
  "main": "dist/v-resize-xm.umd.js",
  "module": "dist/v-resize-xm.mjs",
  "scripts": {
    "test": "echo"Error: no test specified"&& exit 1",
    "build":"vite"
  },
  "keywords": [],
  "author": "",
  "files": [
    "dist",
    "index.d.ts"
  ],
  "license": "ISC",
  "devDependencies": {
    "vite": "^5.2.11",
    "vue": "^3.4.26"
  }
}


3. 上传 npm

  • 如果没有 npm 账号
    1.npm adduser
  • 有账号的话 npm login
  • 上传插件 npm publish

vue3 中 Hook 详解 Hook 结合自定义指令
4. 上传成功后

可以去 npm 官网 搜索 package.json 定义的 name 名称进行搜索
链接: npm 官网地址

5. 使用

1. 在项目中安装库
pnpm i v-resize-smy
2. 在文件中引入
3. 一下代码自定义 hook 的实例

template>
    div id="resize">
        a href="http://vitejs.dev" target="_blank">
            img src="/vite.svg" class="logo" alt="Vite logo" />
        /a>
    /div>
/template>
script setup lang="ts">
import useResize from "v-resize-smy"
import { onMounted } from "vue"
onMounted(() => {
    useResize(document.querySelector("#resize") as HTMLElement, (e: any) => {
        console.log(e)
    })
})
/script>
style scoped lang="scss">
#resize {
    border: 1px solid #ccc;
    resize: both;
    overflow: hidden;
}
img {
    width: 50px;
    height: 50px;
}
/style>

6. 自定义指令 +hook 综合使用案例

  1. 在 main.ts 文件中注册
    import useResize from“v-resize-smy”
    app.use(useResize)
  2. 在文件中使用 示例如下
template>
    div v-resize="resizeWd" id="resize">
        a href="http://vitejs.dev" target="_blank">
            img src="/vite.svg" class="logo" alt="Vite logo" />
        /a>
    /div>
/template>
script setup lang="ts">
const resizeWd = (el: any) => {
    console.log(el)
}
/script>
style scoped lang="scss">
#resize {
    border: 1px solid #ccc;
    resize: both;
    overflow: hidden;
}
img {
    width: 50px;
    height: 50px;
}
/style>

hooks 优点

1.hooks 作为独立逻辑的组件封装,其内部的属性、函数等和外部组件具有响应式依附的作用。
2. 自定义 hook 的作用类似于 vue2 中的 mixin 技术,使用方便,易于上手。
3. 使用 Vue3 的组合 API 封装的可复用,高内聚低耦合。

hooks 和 utils 区别

相同点:

通过 hooks 和 utils 函数封装,可以实现组件间共享和复用,提高代码的可重用性和可维护性。

异同点:

  1. 表现形式不同:hooks 是在 utils 的基础上再包一层组件级别的东西 (钩子函数等);utils
    一般用于封装相应的逻辑函数,没有组件的东西;

  2. 数据是否具有响应式:hooks 中如果涉及到 ref,reactive,computed 这些 api 的数据,是具有响应式的;而
    utils 只是单纯提取公共方法就不具备响应式;

  3. 作用范围不同:hooks 封装,可以将组件的状态和生命周期方法提取出来,并在多个组件之间共享和重用;utils
    通常是指一些辅助函数或工具方法,用于实现一些常见的操作或提供特定功能。

原文地址: vue3 中 Hook 详解 Hook 结合自定义指令

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-11-29发表,共计4358字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)