Vue

VUE3之Composition API(三)

案例

开发中经常将一个逻辑的模块单独抽取到一个js文件中:

useCounter

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
    }
}

useTitle

// useTitle
import { ref,watch } from "vue";
export default function(title = "默认title"){
    const titleRef =ref(title);
    watch(titleRef,(newValue)=>{
        document.title=newValue;
    },{
        immediate:true
    });

    return titleRef;
}

useScrollPosition

import { ref } from 'vue';
export default function(){
    const scrollX=ref(0);
    const scrollY=ref(0);
    document.addEventListener("scroll",()=>{
        scrollX.value=window.scrollX;
        scrollY.value=window.scrollY;
    });
    return {
        scrollX,
        scrollY
    }
}

useMousePosition

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
    }
}

useLocalStorage

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

// 一个参数:取值
// const data = useLocalStorage("name");
// 两个参数:保存值
// const data = useLocalStorage("name","sk");
// data.value="shopkeeper";

写一个index.js一次性导入上述的模块:

import useCounter from './useCounter';
import useTitle from './useTitle';
import useScrollPosition from './useScrollPosition';
import useLocalStorage from './useLocalStorage';
import useMousePosition from './useMousePosition';

export {
    useCounter,
    useTitle,
    useScrollPosition,
    useLocalStorage,
    useMousePosition
}

app.vue:

<template>
    <div>
        <h2>计数器值:{{counter}}</h2>
        <h2>计数器值*2:{{doubleCounter}}</h2>
        <button @click="increment">+1</button>
        <button @click="decrement">-1</button>

        <h2>{{data}}</h2>
        <button @click="changeData">change data</button>

        <p class="content"></p>

        <div class="scroll">
            <div class="scroll-x">scroll-x: {{scrollX}}</div>
            <div class="scroll-y">scroll-y: {{scrollY}}</div>
        </div>

        <div class="mouse">
            <div class="mouse-x">mouse-x: {{mouseX}}</div>
            <div class="mouse-y">mouse-y: {{mouseY}}</div>
        </div>
    </div>
</template>

<script>
// import { ref, computed } from 'vue';
import {
    useCounter,
    useTitle,
    useScrollPosition,
    useLocalStorage,
    useMousePosition
} from './hook';
    export default {
        setup(props) {
            // counter
            const { counter, doubleCounter, increment, decrement} = useCounter();
            // title
            const titleRef=useTitle("sk");
            setTimeout(()=>{
                titleRef.value="shopkeeper";
            },3000);
            // 滚动位置
            const { scrollX,scrollY } = useScrollPosition();
            // 鼠标位置
            const { mouseX, mouseY} =useMousePosition();

            // 数据保存
            const data=useLocalStorage("info",{name:"sk",age:18});
            const changeData=()=>{
                data.value="hahaha";
            };

            return {
                counter, doubleCounter, increment, decrement,
                scrollX, scrollY,
                mouseX, mouseY,
                data, changeData
            }
        }
    }
</script>

<style scoped>
    .content{
        width: 3000px;
        height: 5000px;
    }
    .scroll{
        position: fixed;
        right: 30px;
        bottom: 30px;
    }
    .mouse{
        position: fixed;
        right: 30px;
        bottom: 80px;
    }
</style>

发表评论