# 1. 目录结构
# 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 |
| } |
| } |
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> |
| |
| <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() { |
| |
| const { titleRef } = useTitle("Nekoaimer"); |
| setTimeout(() => { |
| titleRef.value = "aimer"; |
| }, 2000); |
| |
| const { scrollX, scrollY } = useScrollPosition(); |
| |
| |
| const { mouseX, mouseY } = useMousePosition(); |
| |
| |
| 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> |
参考结果: