Vue 自定义hook函数

news/2024/7/9 23:48:31 标签: vue

文章目录

  • 定义
  • 使用
  • 封装发ajax请求的hook函数(ts版本)

定义

什么是hook?
。本质是一个函数,把 setup 函数中使用的 Composition API (组合API)进行了封装
。类似于 vue2.x 中的 mixin

自定义 hook 的优势
。复用代码,让 setup 中的逻辑更清楚易懂

使用

首先我们做一个功能,鼠标点击屏幕,获取坐标
在这里插入图片描述

<template>
  <h2>当前鼠标的坐标是:x:{{ point.x }},y:{{ point.y }}</h2>
</template>

<script>
import {onMounted, onBeforeUnmount,reactive} from 'vue'

export default {
  name: 'Demo',
  setup() {
    let point = reactive({
      x: 0,
      y: 0
    })

    function savePoint(event) {
      point.x = event.pageX;
      point.y = event.pageY;
    }
    onMounted(() => {
      window.addEventListener("click",savePoint)
    })

    onBeforeUnmount(()=>{
      window.removeEventListener("click",savePoint)
    })

    return {
      point,
    }
  },
}
</script>

然后改用使用 hooks,在 src 下新建 hooks 文件夹,增加 usePoint.js

import {onBeforeUnmount, onMounted, reactive} from "vue/dist/vue";

function savePoint() {
    let point = reactive({
        x: 0,
        y: 0
    })

    function savePoint(event) {
        point.x = event.pageX;
        point.y = event.pageY;
    }
    onMounted(() => {
        window.addEventListener("click",savePoint)
    })

    onBeforeUnmount(()=>{
        window.removeEventListener("click",savePoint)
    })
    return point
}

export default savePoint;

或者简写:

......
export default function() {
    ......
}

在 Demo.vue 中使用

<template>
  <h2>当前鼠标的坐标是:x:{{ point.x }},y:{{ point.y }}</h2>
</template>

<script>
import usePoint from "@/hooks/usePoint";

export default {
  name: 'Demo',
  setup() {
    let point = usePoint()

    return {
      point
    }
  },
}
</script>

封装发ajax请求的hook函数(ts版本)

hooks 下新建 useRequest.ts

由于用到了 axios,所以安装axios:npm install axios

import {ref} from "vue";
import axios from "axios";

export default function <T>(url: string) {
    const loading = ref(true);
    const data = ref<T | null>(null);
    const errorMsg = ref('');

    axios.get(url).then(response => {
        loading.value = false
        data.value = response.data
    }).catch(error => {
        loading.value = false
        errorMsg.value = error.message || '未知错误'
    })

    return {
        loading,
        data,
        errorMsg
    }
}

App.vue

<template>
  <h3 v-if="loading">加载中...</h3>
  <h3 v-else-if="errorMsg">错误信息:{{errorMsg}}</h3>
  <!-- 对象 -->
  <ul v-else>
    <li>{{data.name}}</li>
    <li>{{data.address}}</li>
    <li>{{data.distance}}</li>
  </ul>
  <!-- 数组 -->
  <ul v-for="item in data" :key="item.name">
    <li>{{item.name}}</li>
    <li>{{item.address}}</li>
    <li>{{item.distance}}</li>
  </ul>
</template>

<script lang="ts">
import {defineComponent, watch} from 'vue';
import useRequest from "@/hooks/useRequest";

export default defineComponent({
  setup() {
    // 定义接口
    interface IAddress{
      name:string,
      address:string,
      distance:string
    }

    //const {loading,data,errorMsg} = useRequest<IAddress>("./address.json")//获取对象数据
    const {loading,data,errorMsg} = useRequest<IAddress[]>("./addressList.json")//获取对象数据
    watch(data, () => {
      if (data.value) {
        console.log(data.value.length)
      }
    })
    return {
      loading,
      data,
      errorMsg
    }
  }
});
</script>

测试数据有对象类型的 address.json

{
  "name": "家",
  "address": "开发区人民路22号",
  "distance": "100km"
}

还有数组类型的 addressList.json

[ {
  "name": "家",
  "address": "开发区人民路22号",
  "distance": "100km"
  },
  {
    "name": "公司",
    "address": "海港区建国路01号",
    "distance": "3km"
  }
]

在这里插入图片描述


http://www.niftyadmin.cn/n/1816681.html

相关文章

js获取数组中的最大值最小值

遍历方法&#xff1a; var tmp [1,12,8,5];var max tmp[0];for(var i1;i<tmp.length;i){ if(max<tmp[i])maxtmp[i];}console.log(max); 使用apply方法&#xff1a; var a [1,2,3,5];console.log(Math.max.apply(null, a));//最大值console.log(Math.min.apply(null, a…

征求意见,什么主题的论坛比较吸引人?

我自己有几个论坛&#xff0c;访问量一直上不去&#xff0c;而SEO也基本上做的差不多了。可是总觉得定位不太好&#xff0c;主题也不是太明确&#xff0c;这是不是一直没法吸引人的原因呢&#xff1f;现在想征求一下各位高人的意见&#xff0c;什么主题的论坛更能吸引人气呢&am…

Vue3 toRef、toRefs

toRef 作用&#xff1a;创建一个 ref 对象&#xff0c;其 value 值指向另一个对象中的某个属性。 语法&#xff1a;const name toRef(person, name ) 应用&#xff1a;要将响应式对象中的某个属性单独提供给外部使用时 扩展&#xff1a;toRefs 与 toRef 功能一致&#xff0c…

EasyX图形库__C语言__贪吃蛇核心代码

EasyX图形库__C语言__贪吃蛇核心代码 前言&#xff1a;&#xff08;第一次博客啊&#xff0c;格式不太会&#xff09; 简介&#xff1a; 1.虽然用的是EasyX的图形库&#xff0c;但其实EGE应该也可以&#xff0c;函数功能好多都是相通的&#xff1b; 2.去掉注释&#xff0c;代…

ip的正则表达式 完美版

IP地址的长度为32位2进制&#xff0c;分为4段&#xff0c;每段8位&#xff0c;用十进制数字表示&#xff0c;每段数字范围为0~255&#xff0c;段与段之间用英文句点“.”隔开。例如&#xff1a;IP地址为10.0.0.100。 分析IP地址的每组数特点&#xff1a;百位&#xff0c;十位&…

推荐一款2D游戏引擎:HGE

Haafs Game Engine 目前已经是1.81版了。目前已完全遵循zlib/libpng许可开源的&#xff0c;即时您是商业使用&#xff0c;也是免费的哦&#xff01; 官方网站&#xff1a;http://www.relishgames.com/ HGE中文社区&#xff1a;http://www.hgechina.com 引用官方的话&#xff1a…

Vue3 其他Composition API

文章目录shallowReactive 和 shallowRefreadonly 与 shallowReadonlytoRaw 和 markRawCustomRefprovide 和 inject响应式数据的判断Composition API的优势shallowReactive 和 shallowRef 作用 shallowReactive&#xff1a;只处理对象最外层属性的响应式&#xff08;浅响应式) …

DevCpp和VS2019安装armadillo库

DevCpp中 点这里下载armadillo 然后解压出来一个文件夹"armadillo-10.4.0", 找到include 看到这两项&#xff0c;就是我们要copy的 找到你DevCpp安装的位置 这里我装的是MinGW&#xff0c;如果你的是TDM-GCC同理 点开编译器的include文件夹 把我们解压出来…