Vue3 Hooks 用法 scrollTop, mousemoveHandler,useCountDown

三个实例来自 learn_vue: 【教学工程】学习vue2/vue3 (gitee.com)

目录

[1. 何为Hooks](#1. 何为Hooks)

[2. 使用场景](#2. 使用场景)

[3. 常见的 Hooks 函数](#3. 常见的 Hooks 函数)

[4. 实例](#4. 实例)

[4.1简易hook 例子](#4.1简易hook 例子)

[4.2 自定义scrolltop例子](#4.2 自定义scrolltop例子)

[4.3 mousemoveHandler例子](#4.3 mousemoveHandler例子)

[4.4 useCountDown例子](#4.4 useCountDown例子)


1. 何为Hooks

Hooks 是一种函数,用于封装组件中的逻辑。它可以包含状态、计算属性、生命周期钩子等,并且可以在多个组件之间共享和复用。

2. 使用场景

  • 逻辑复用:通过 Hooks,可以将一组相关的逻辑封装在一个函数中,提高代码的可复用性。

  • 代码组织:使得组件逻辑更加清晰,避免大型组件选项过于臃肿。

  • 提高可读性和维护性:将相关逻辑分离成多个小函数,使得每个函数的职责更加清晰,便于理 解和维护。

3. 常见的 Hooks 函数

  • reactive、ref、computed:用于创建响应式数据。

  • watch、watchEffect:用于监听数据变化。

  • onMounted、onUpdated、onUnmounted:用于处理组件的生命周期。

  • 自定义 Hooks:根据业务逻辑封装的自定义函数,例如下述提到的 useCountDown。

4. 实例

4.1简易hook 例子

javascript 复制代码
import { ref } from 'vue';
export default function useCounter() {
  const count = ref(0);

  const increment = () => {
    count.value++;
  };

  return {
    count,
    increment,
  };
}

下述,hooks不是一定要有state

4.2 自定义scrolltop例子

注意 一般hooks里包括一些函数钩子,比如mounted,注意 hooks里重要的是state一般被包裹在函数里面,这样不同组件调用 不会共享state

javascript 复制代码
export default function (target=window,dataRef = null){
    let timer=null
    //一键回到顶部 时间默认1000毫秒
    const toTop=(millis=1000)=>{
    yScrollTo(0,millis)
    }
    const yScrollTo=(y,millis=500)=>{
    if(!timer){
    const offset = target.scrollTop-y
     const frameOffset = Math.abs(offset / (millis / 40));
     timer=setInterval(()=>{
     if(offset>0 && target.scrollTop-y >frameOffset)
     {
      target.scrollTop-=frameOffset
     }
     else if(offset<0 && y-target.scrollTop>0)
     target.scrollTop+=frameOffset
     else{
//这部分让平滑动画,直接赋值
     target.scrollTop=y
     clearInterval(timer)
     timer=null
     }
     },40)
    }
    }
    //响应式数据实时滚动距离
    const scrollTop=ref(0)
    const scrollHandler=(e)=>{
//同步scrolltop
    scrollTop.value = target.scrollTop
    }
    //组件挂载时候添加scrollhandler
    onMounted(()=>{
    target.addEventListener("scroll",scrollHandler)
    })
    //组件卸载时候移除scrollhandler
    onUnmounted(()=>{
target.removeEventListener("scroll", scrollHandler)
    })
    onActivated(()=>{
    if(dataRef){
    //如果存在要恢复的数据
    yScrollTo(dataRef.value)
    console.log("滚动位置已恢复为",dataRef.value)
    }
    })
    onDeactivated(()=>{
    if(dataRef){
    console.log("离开时滚动的位置",scrollTop.value)
    dataRef.value = scrollTop.value
    }
    })
    return scrollTop
}

函数两个参数,第一个参数 target=window,获取目标要滚动到的位置,第二个参数dataRef 如果提供 代表要缓存离开时候 当前滚动到的位置 方便下次回来时候恢复到dataRef的位置

防止同时多次调用滚动动画:

timer为空变送没有正在进行的滚动动画 可以启动一个新的滚动动画

4.3 mousemoveHandler例子

javascript 复制代码
function useMouse(){
const state = reactive({
x:0,
y:0
})
const mousemoveHandler=(e)=>{
//更新实时数据
state.x = e.pageX
state.y  = e.pageY
}
//组件挂载时候建立mousemove事件监听器
onMounted(()=>{
window.addEventListener("mousemove",mousemoveHandler)
})
onUnmounted(()=>{
window.removeEventListener("mousemove",mousemoveHandler)
})
return toRefs(state)
//将state里的属性拆开每个都是响应式数据


}
export default mousemoveHandler

4.4 useCountDown例子

javascript 复制代码
function getTimeDiffer(startDate, endDate){
let timeDiff = endDate-startDate
// 计算过去了多少天
var daysDiffer = parseInt(timeDiffer / (24 * 3600 * 1000));
// console.log(daysDiffer);

// 计算不足一天的时分秒 odd奇数,零头
var oddMillis = timeDiffer % (24 * 3600 * 1000);
var hoursDiffer = parseInt(oddMillis / (3600 * 1000));
// console.log(hoursDiffer);

// 不足一小时的零头毫秒
oddMillis = oddMillis % (3600 * 1000);
var minutesDiffer = parseInt(oddMillis / (60 * 1000));
// console.log(minutesDiffer);

// 计算秒
var secondsDiffer = Math.round((oddMillis % (60 * 1000)) / 1000);
// console.log(secondsDiffer);
return {
daysDiffer,
hoursDiffer,
minutesDiffer,
secondsDiffer,
}

}

const useCountDown = (targetDate)=>{
//targetDate: new Date(2023, 0, 1),
const state = reactive({
days:0,
hours:0,
minutes:0,
seconds:0
})

let timer = null
onMounted(()=>{
timer = setInterval(()=>{
const {daysDiffer,hoursDiffer,minutesDiffer,secondsDiffer}=getTimeDiffer(new Date(),targetDate)
state.days = daysDiffer;
state.hours = hoursDiffer;
state.minutes = minutesDiffer;
state.seconds = secondsDiffer;

},1000)
})
/* 组件卸载时移除定时器 */
onUnmounted(() => {
if (timer) {
clearInterval(timer);
console.log("timer已移除");
}
});

// {days,hours,minutes,seconds}
return toRefs(state);

}
export default useCountDown
相关推荐
baiduopenmap3 分钟前
百度世界2024精选公开课:基于地图智能体的导航出行AI应用创新实践
前端·人工智能·百度地图
loooseFish11 分钟前
小程序webview我爱死你了 小程序webview和H5通讯
前端
小牛itbull15 分钟前
ReactPress vs VuePress vs WordPress
开发语言·javascript·reactpress
请叫我欧皇i23 分钟前
html本地离线引入vant和vue2(详细步骤)
开发语言·前端·javascript
533_26 分钟前
[vue] 深拷贝 lodash cloneDeep
前端·javascript·vue.js
guokanglun32 分钟前
空间数据存储格式GeoJSON
前端
GIS瞧葩菜35 分钟前
局部修改3dtiles子模型的位置。
开发语言·javascript·ecmascript
zhang-zan1 小时前
nodejs操作selenium-webdriver
前端·javascript·selenium
ZBY520311 小时前
【Vue】 npm install amap-js-api-loader指南
javascript·vue.js·npm
猫爪笔记1 小时前
前端:HTML (学习笔记)【2】
前端·笔记·学习·html