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
相关推荐
烬头88212 分钟前
React Native鸿蒙跨平台采用了函数式组件的形式,通过 props 接收分类数据,使用 TouchableOpacity实现了点击交互效果
javascript·react native·react.js·ecmascript·交互·harmonyos
Amumu121382 分钟前
Vuex介绍
前端·javascript·vue.js
We་ct3 分钟前
LeetCode 54. 螺旋矩阵:两种解法吃透顺时针遍历逻辑
前端·算法·leetcode·矩阵·typescript
2601_9498095914 分钟前
flutter_for_openharmony家庭相册app实战+相册详情实现
javascript·flutter·ajax
qq_1777673719 分钟前
React Native鸿蒙跨平台通过Animated.Value.interpolate实现滚动距离到动画属性的映射
javascript·react native·react.js·harmonyos
2601_9498333928 分钟前
flutter_for_openharmony口腔护理app实战+饮食记录实现
android·javascript·flutter
2601_9494800636 分钟前
【无标题】
开发语言·前端·javascript
css趣多多41 分钟前
Vue过滤器
前端·javascript·vue.js
理人综艺好会1 小时前
Web学习之用户认证
前端·学习
●VON1 小时前
React Native for OpenHarmony:项目目录结构与跨平台构建流程详解
javascript·学习·react native·react.js·架构·跨平台·von