目录
[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 mousemoveHandler4.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