likes
comments
collection
share

实现一个vue3组件库-src资源文件

作者站长头像
站长
· 阅读数 15

实现一个vue3组件库-src资源文件

前言

也是紧接着上一遍文章:实现一个vue3组件库-项目初始化 - 掘金 (juejin.cn),现在说说项目结构的src目录,这一篇主要是介绍用,不做说明❌

hooks

useFlags

暴露一个响应式的Boolean变量,提供setFalse,setTrue方法

import {Ref} from "vue";
import {ref} from "@vue/runtime-core";

export default function (f:Boolean = false)  {
    const flag:Ref<Boolean> = ref<Boolean>(f);
    const setFalse = function () {
        flag.value = false;
    }
    const setTrue = function () {
        flag.value = true;
    }

    const toggle = function () {
        if (flag.value){
            setFalse();
        }
        else{
            setTrue();
        }
    }

    return {
        flag,
        setTrue,
        setFalse,
        toggle
    }

}

useMark

这个hook用于创建mark(遮罩)元素。 两个参数,target,markType.

  • target是需要运用mark的元素, 将会在这个元素中添加一个mark子节点
  • markType是mark的类型,分为全局遮罩和局部遮罩
import { nextTick, Ref} from "vue";
import getHTMLElement from "../utils/VNode/getHTMLElement";


/**
 * @description 遮罩的类型
 */
type MarkType = 'cover' | 'part';

/**
 * @description 在el中添加一个遮罩元素
 * @param target 需要添加遮罩的元素, 可以是ref实例,也可以是一个html节点
 * @param markType  cover将会覆盖整个视口,part只会覆盖元素本身
 */
export default  function (target:Ref<Element> | HTMLElement, markType:MarkType) {
    let el:HTMLElement;
    const mark:HTMLElement  = createMark(markType);

    if(target instanceof HTMLElement){
        el = target;
        el.appendChild(mark);

    }
    else {
        // ref是ref<Element>时,ref可能未挂载,等待下一个tick
        nextTick().then( () => {
            el = getHTMLElement(target);
            el.appendChild(mark);


        })
    }


    const showMark =  function (){
        const handleAnimationend = function (){
            mark.classList.remove('sss-transition-fadeIn');
            mark.removeEventListener('animationend',handleAnimationend)
        }


        mark.style.display = 'unset';
        mark.classList.add('sss-transition-fadeIn');
        mark.addEventListener('animationend',handleAnimationend)
    }

    const hiddenMark =  function (){
        const handleAnimationend = function (){
            mark.classList.remove('sss-transition-fadeOut');
            mark.removeEventListener('animationend',handleAnimationend)
            mark.style.display = 'none';

        }

        mark.classList.add('sss-transition-fadeOut');
        mark.addEventListener('animationend',handleAnimationend)


    }



    return {
        mark,
        showMark,
        hiddenMark
    }

}

const createMark = function (markType:MarkType){
    const mark = document.createElement('div');
    if (markType === 'cover'){
        mark.classList.add('sss-mark-cover');
        mark.style.zIndex = '-1';

    }else if (markType === 'part') {
        mark.classList.add('sss-mark-part');

    }



    return mark;
}

useLockScroll

此hook用于禁止浏览器的滚动 将会暴露两个函数:

  • lockScroll: 用于禁止滚动
  • unLockScroll: 用于允许滚动

let count = 0;
export default function (){

    const lockScroll = function (){
        if (count === 0){
            document.body.style.overflowY = "hidden"
        }
        count++;
    }
    const unLockScroll = function () {
        count--;
        if (count <= 0) count = 0;
        if (count === 0){
            document.body.style.overflowY = "auto"
        }
    }

    return{
        lockScroll,
        unLockScroll
    }
}

utils

存放工具函数

decorators 装饰器

  • debounce.ts: 防抖装饰器
  • throttle.ts: 节流装饰器

这两个没啥好说的叭

managers 管理器

  • indexManager.ts 用于管理元素的z-index,简单说就是暴露一个函数,这个函数将会返回z-index的值,这个值将会是递增的
    class IndexManager{
        index:number
        constructor(index:number) {
            this.index = index;
        }
        nextIndex(){
            return this.index++;
        }
    }
    
    export default new IndexManager(2000);
    
  • LayoutManager.ts 用于管理元素的布局,比如全局出现的notify,message,alert等这些元素,一般是动态出现在元素的角落,这个管理器将会管理他们的布局。
    export type position = 'down' | 'up';
    
    
    class LayoutManager{
        protected position:position
        protected appList: Array< HTMLElement >
    
        constructor(position:position) {
            this.position = position;
            this.appList = [] as Array< HTMLElement >;
        }
    
        /**
         * @description 在尾部添加一个元素
         * @param el
         */
        push(el: HTMLElement) {
            this.appList.push(el);
            this.update();
        }
    
        /**
         * @description 删除一个元素
         * @param el
         */
        delete(el:HTMLElement) {
            const pos = this.appList.indexOf(el);
            this.appList.splice(pos, 1);
            this.update();
        }
    
        /**
         * @description 下一个元素的位置
         */
        next() {
            let res = 0;
            this.appList.forEach(item => {
                res += parseInt(item.getAttribute('data-space') as string) + item.offsetHeight;
            })
            return res;
        }
    
        /**
         * @description 更新元素位置
         * @protected
         */
        protected update(){
            if (this.position === 'up') {
                this._layoutUp();
            }
            if (this.position === 'down') {
                this._layoutDown();
            }
        }
        protected _layoutUp(){
            let bottom = 0;
            this.appList.forEach(item => {
                bottom += parseInt(item.getAttribute('data-space') as string);
                item.style.bottom = `${bottom}px`;
                bottom += item.offsetHeight;
            })
        }
       protected  _layoutDown() {
           let top = 0;
           this.appList.forEach(item => {
               top += parseInt(item.getAttribute('data-space') as string);
               item.style.top = `${top}px`;
               top += item.offsetHeight;
           })
        }
    
    }
    
    
    export default LayoutManager
    

一些不知道怎么归类的工具

  • delay.ts 用来做延时操作的
    /**
     * @description 延时一段时间
     * @param timeout 延时时间
     */
    export default function (timeout:number) {
        return new Promise(resolve => {
            setTimeout(() => {
                resolve("ok");
            },timeout);
        })
    }
    
  • fnUnion.ts 将函数结合,返回一个新的函数
    /**
     * @description 将函数聚合,不负责返回值
     * @param args 函数体
     */
    export const fnUnion = function (...args:Array<Function>) {
        return function (){
            for (let i = 0; i < args.length; i++) {
                args[i]();
            }
        }
    }
    
  • getHTMLElement.ts 从一个响应式ref对象中获取真实HTMLElement
    import {Ref} from "vue";
    /**
     * @description 用于获取ref引用的真实dom节点, 需要注意调用的时候ref对象时候有值
     */
    const getHTMLElement = function (ref: Ref<Element>) :HTMLElement {
        const tmp: any = ref.value;
        if (tmp instanceof HTMLElement){
             return tmp
        }
        else return tmp.$el
    }
    
    export default getHTMLElement
    

styles

  • variables.less 全局的css变量,目前只是颜色和字体大小两者

    :root {
      --sss-color-default-dark-deep: darken(#eeeff1,5%);
      --sss-color-default-dark: darken(#eeeff1,1%);
      --sss-color-default: #eeeff1;
      --sss-color-default-light: lighten(#eeeff1,1%);
    
      --sss-color-primary-dark: darken(#db5b6c,5%);
      --sss-color-primary: lighten(#db5b6c,5%);
      --sss-color-primary-light: lighten(#db5b6c,12%);
      --sss-color-primary-fade: lighten(#db5b6c,36%);
    
      --sss-color-info-dark:darken(#1BA784,5%);
      --sss-color-info:#1BA784;
      --sss-color-info-light:lighten(#1BA784,6%);
      --sss-color-info-fade:lighten(#1BA784,55%);
    
      --sss-color-warning-dark:darken(#E6A23C,8%);
      --sss-color-warning:lighten(#E6A23C,5%);
      --sss-color-warning-light:lighten(#E6A23C,15%);
      --sss-color-warning-fade:lighten(#E6A23C,40%);
    
      --sss-color-danger-dark:darken(#ff4757,17%);
      --sss-color-danger:#ff4757;
      --sss-color-danger-light:lighten(#ff4757,10%);
      --sss-color-danger-fade:lighten(#ff4757,33%);
    
      --sss-color-success-dark:darken(#badc58,20%);
      --sss-color-success:darken(#badc58,15%);
      --sss-color-success-light:darken(#badc58,10%);
      --sss-color-success-fade:lighten(#badc58,35%);
    
      --sss-color-cyan-dark:darken(#A172D0,5%);
      --sss-color-cyan:darken(#A172D0,-3%);
      --sss-color-cyan-light:lighten(#A172D0,10%);
      --sss-color-cyan-fade:lighten(#A172D0,33%);
    
      --sss-color-black-dark:rgb(23,23,23);
      --sss-color-black:rgb(68,68,68);
      --sss-color-black-light:lighten(rgb(23,23,23),28%);
      --sss-color-black-fade:lighten(rgb(68,68,68),69%);
    
    
      --sss-color-gray:#ced6e0;
      --sss-color-gray-dark:darken(#ced6e0,15%);
      --sss-color-white: #fff;
    
      --sss-font-size-small:10px;
      --sss-font-size-default:15px;
      --sss-font-size-large:20px;
    
    
    }
    
  • global.less 存放一些全局的样式

  • animatie.css 存放一些动画和过渡样式

end

这一篇主要是介绍src里面的一些文件及其作用。

下一篇开始真正的第一个组件:

感谢看到最后💟