# 1. 目录结构

directory_structure

# 2. 封装案例

# useCounter

vue
// hooks/useCounter.js
import { ref, computed } from "vue"
export default function () {
  const counter = ref(0)
  const doubleCounter = computed(() => counter.value * 2);
  const increment = ()=>counter.value++
  const decrement = ()=>counter.value--
  return {
    counter,
    doubleCounter,
    increment,
    decrement
  }
}

# useLocalStorage

vue
// hooks/useLocalStorage.js
import { ref,watch } from "vue"
export default function (key, value) {
  const data = ref(value)
  if (value) {
    window.localStorage.setItem(key,JSON.stringify(value))
  } else {
    window.localStorage.getItem(key,JSON.parse(value))
  }
  watch(data, () => {
    window.localStorage.setItem(key,JSON.stringify(value))
  })
  return data
}

# useMousePosition

vue
// hooks/useMousePosition.js
import { ref } from 'vue';
export default function() {
  const mouseX = ref(0);
  const mouseY = ref(0);
  window.addEventListener("mousemove", (event) => {
    mouseX.value = event.pageX;
    mouseY.value = event.pageY;
  });
  return {
    mouseX,
    mouseY
  }
}

# useScrollPosition

vue
// hooks/useScrollPosition.js
import { ref } from "vue"
export default function () {
    const scrollX = ref(0);
    const scrollY = ref(0);
    document.addEventListener("scroll", () => {
    scrollX.value = Math.floor(window.scrollX);
    scrollY.value = Math.floor(window.scrollY);
    });
  return {
      scrollX,
      scrollY,
    }
}

# useTitle

vue
// hooks/useTitle.js
import { ref, watch } from "vue"
export default function (title = "默认值") {
  const titleRef = ref(title)
  watch(titleRef, (newValue, oldValue) => {
    // console.log(newValue,"new");
    // console.log(oldValue,"old");
    document.title = newValue
  }, {
    immediate:true
  })
  return {
    titleRef,
  }
}

# index

vue
// index.js  统一导出
import useCounter from './useCounter';
import useTitle from './useTitle';
import useScrollPosition from './useScrollPosition';
import useMousePosition from './useMousePosition';
import useLocalStorage from './useLocalStorage';
// 全面引入 index.js文件 再统一导出
export {
  useCounter,
  useTitle,
  useScrollPosition,
  useMousePosition,
  useLocalStorage
}

# App

vue
<template>
  <div>
    <!-- ---------- 计数 ---------- -->
    <h2>当前计数:</h2>
    <h2>计数*2:</h2>
    <button @click="increment">counter+1</button>
    <button @click="decrement">counter-1</button>
  </div>
  <div style="color: red">title:</div>
  <!-- localStorage -->
  <h2 style="color: pink">localStorage:--</h2>
  <p class="content"></p>
  <!-- ---------- 鼠标位置 ---------- -->
  <div class="scroll">
    <div class="scroll-x">scrollX:</div>
    <div class="scroll-y">scrollY:</div>
  </div>
  <!-- ---------- 滚动位置 ---------- -->
  <div class="mouse">
    <div class="mouse-x">mouseX:</div>
    <div class="mouse-y">mouseY:</div>
  </div>
</template>
<script>
import { ref } from "vue";
import {
  useCounter,
  useTitle,
  useScrollPosition,
  useMousePosition,
  useLocalStorage,
} from "./hooks/index";
export default {
  setup() {
    // title
    const { titleRef } = useTitle("Nekoaimer");
    setTimeout(() => {
      titleRef.value = "aimer";
    }, 2000);
    // 滚动位置
    const { scrollX, scrollY } = useScrollPosition();
    // 鼠标位置
    const { mouseX, mouseY } = useMousePosition();
    // localStorage
    const data = useLocalStorage("info", { name: "aimer", age: 18 });
    return {
      ...useCounter(), // 解构写法,阅读性较差但简洁
      titleRef,
      scrollX,
      scrollY,
      mouseX,
      mouseY,
      data,
    };
  },
};
</script>
<style  scoped>
.content {
  width: 100vw;
  height: 1000px;
  background-color: antiquewhite;
}
.scroll {
  position: fixed;
  right: 120px;
  bottom: 30px;
}
.mouse {
  position: fixed;
  right: 120px;
  bottom: 80px;
}
</style>

参考结果:

Encapsulation