vue3中Hook使用以及Hook结合自定义指令

 更新时间:2024年08月16日 15:01:10   作者:白臻  
这篇文章主要介绍了vue3中Hook使用以及Hook结合自定义指令方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Vue3的自定义的hook

hook是钩子的意思,看到“钩子”是不是就想到了钩子函数?事实上,hooks 还真是函数的一种写法。

vue3 借鉴 reacthooks 开发出了 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码 到浏览器 可显示图片

手写自定义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

2.进入 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)
}
// vue 插件
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'
// umd 支持amd cmd cjs 全局变量模式
export default defineConfig({
    build: {
        lib: {
            entry: 'src/index.ts',
            name: 'userResize',
        },
        rollupOptions: {
            // 确保外部化处理那些你不想打包进库的依赖
            external: ['vue'],
            output: {
                // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
                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 命令后 打包

6. 在 index.d.ts 编写声明文件

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

export default useResize

7.准备就绪 发布npm 需要配置 package.json

  • 当使用import 、export的时候它会去找对应的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"
  }
}

8.上传npm

如果没有npm 账号

npm adduser

有账号的话 npm login

上传插件 npm publish

9.上传成功后

可以去npm 官网 搜索package.json 定义的 name 名称进行搜索

链接:npm官网地址

10.使用

在项目中安装库

pnpm i v-resize-smy

在文件中引入

一下代码自定义hook 的实例

<template>
    <div id="resize">
        <a href="http://vitejs.dev" rel="external nofollow"  rel="external nofollow"  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>

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

在main.ts 文件中注册

import useResize from “v-resize-smy”
app.use(useResize)

在文件中使用 示例如下

<template>
    <div v-resize="resizeWd" id="resize">
        <a href="http://vitejs.dev" rel="external nofollow"  rel="external nofollow"  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 函数封装, 可以实现组件间共享和复用,提高代码的可重用性和可维护性。

异同点:

  • 表现形式不同:hooks 是在 utils 的基础上再包一层组件级别的东西(钩子函数等);utils一般用于封装相应的逻辑函数,没有组件的东西;
  • 数据是否具有响应式:hooks 中如果涉及到 ref,reactive,computed 这些 api 的数据,是具有响应式的;而utils 只是单纯提取公共方法就不具备响应式;
  • 作用范围不同:hooks 封装,可以将组件的状态和生命周期方法提取出来,并在多个组件之间共享和重用;utils通常是指一些辅助函数或工具方法,用于实现一些常见的操作或提供特定功能。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Vue实现选择城市功能

    Vue实现选择城市功能

    这篇文章主要介绍了Vue实现选择城市功能,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-05-05
  • vue3.0中使用websocket,封装到公共方法的实现

    vue3.0中使用websocket,封装到公共方法的实现

    这篇文章主要介绍了vue3.0中使用websocket,封装到公共方法的实现,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • vue实现输入框自动跳转功能

    vue实现输入框自动跳转功能

    这篇文章主要为大家详细介绍了vue实现输入框自动跳转功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • vue3+ts封装axios实例以及解决跨域问题

    vue3+ts封装axios实例以及解决跨域问题

    在前端开发中,使用axios进行数据请求是常见的做法,封装axios可以统一请求头处理、方便接口管理、配置多拦截器等,提高代码的可维护性和重用性,本文详细记录了axios的封装过程,包括安装、配置跨域处理、接口管理文件的创建等
    2024-09-09
  • Vue基于vuex、axios拦截器实现loading效果及axios的安装配置

    Vue基于vuex、axios拦截器实现loading效果及axios的安装配置

    这篇文章主要介绍了Vue基于vuex、axios拦截器实现loading效果及axios的安装配置,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-04-04
  • 在vue中v-for循环遍历图片不显示错误的解决方案

    在vue中v-for循环遍历图片不显示错误的解决方案

    这篇文章主要介绍了在vue中v-for循环遍历图片不显示错误的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • vue-element-admin 菜单标签失效的解决方式

    vue-element-admin 菜单标签失效的解决方式

    今天小编就为大家分享一篇vue-element-admin 菜单标签失效的解决方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • Vue.js列表渲染绑定jQuery插件的正确姿势

    Vue.js列表渲染绑定jQuery插件的正确姿势

    这篇文章主要为大家详细介绍了Vue.js列表渲染绑定jQuery插件的正确姿势,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • Vue结合Openlayers使用Overlay添加Popup弹窗实现

    Vue结合Openlayers使用Overlay添加Popup弹窗实现

    本文主要介绍了Vue结合Openlayers使用Overlay添加Popup弹窗实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • vue.js初学入门教程(2)

    vue.js初学入门教程(2)

    这篇文章主要为大家详细介绍了vue.js初学入门教程第二篇,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11

最新评论