当前位置: 首页 > news >正文

网络与设计是干嘛的李勇seo的博客

网络与设计是干嘛的,李勇seo的博客,工业品网络营销,wordpress 主页 插件在页面上 loading(加载)的效果十分常见,在某些场景下,一个页面上甚至可能有特别多的 loading 存在,此时为每一个 loading 专门创建一个 state 显然太过繁琐,不如试试写一个 useLoading 来集中管理&#xff…

在页面上 loading(加载)的效果十分常见,在某些场景下,一个页面上甚至可能有特别多的 loading 存在,此时为每一个 loading 专门创建一个 state 显然太过繁琐,不如试试写一个 useLoading 来集中管理!

构思分析

状态形式

当页面上有众多的 loading 时,我们需要能区分它们,因此 useLoading 存储的 state 应当是 KV 式 或者数组式,KV 更方便,我们将采用 KV 式,K 代表 loading 的标识名称,V代表是否 loading。

返回形式

useLoading 应当提供哪些 api 呢?返回 state 和 setState 是必要的,此外,提供根据 K 的 setLoading 以及 根据 K 的 onloading 和 unloading 也是 非常使用的。

初始化方式

既然已经确定了 state 为 KV 式,初始化给个对象即可。

代码实现

接口和类型声明

声明 UseLoading 的入参为初始 state ,并定义其为泛型,默认为 Record<string, Boolean>,并按照 useHooks 的习惯,返回一个 只读 的数组,第一项为 state,第二项为 set,第三项为 onloading,第四项为 unloading。
此外,我们需要为 set 额外定义一个接口,用于 (K,V)({k,v}) 两种入参形式的函数重载。

export interface SetLoading<T = Record<string, Boolean | number>,K extends keyof T  = keyof T
> {(key: K, value?: boolean): void;(key: K, setAction: (pre: boolean | number)=> boolean): void;(state: Record<K, boolean>): void;(setAction: (pre: T) => T): void;
}export interface UseLoading<T = Record<string, boolean>> {(loadingMap: T): readonly [T,SetLoading,(key: keyof T) => void,(key: keyof T) => void];
}
具体实现
export const useLoading: UseLoading = <T = Record<string, boolean | number>>(initialLoadingMap: T
) => {const [loading, _setLoading] = useState<T>(initialLoadingMap);const setLoading: SetLoading<T, keyof T> = (args1 , value = true) => {if (typeof args1 === "object") {_setLoading((pre) => ({ ...pre, ...args1 }));return;} else if (typeof args1 === "function") {_setLoading((pre) => args1(pre));return;} else {const key = args1;if (typeof value === "function") {_setLoading((pre) => ({ ...pre, [key]: value(pre[key]) }));} else {_setLoading((pre) => ({ ...pre, [key]: value }));}}};const onLoading = (key: keyof typeof loading) => {_setLoading((pre) => ({ ...pre, [key]: true }));};const unLoading = (key: keyof typeof loading) => {_setLoading((pre) => ({ ...pre, [key]: false }));};return [loading,setLoading,onLoading,unLoading,] as unknown as ReturnType<UseLoading>;
};

到这里,基础的 useLoading 就实现了,以下是简单的使用示例:

export default function Demo(){const [loading, setLoading] = useLoading({button1: false,button2: false,})const handleClick = (key: 'button1'|'button2') => {setLoading()}return(<><button onClick={() => setLoading('button1')}>{loading.button1? 'loading':'button1'}</button><button onClick={() => setLoading('button1')}>{loading.button2? 'loading':'button2'}</button></>)
}

进阶

有时候,我们的 loading 只是效果,并不阻止用户操作,那么当用户连续进行点击等操作时,我们希望 loading 效果应当延续下去,此时只使用上面的 useLoding 显然乏力,我们需要额外维护一个具有计数性质的 state(数字数组,Promise数组等) 配合使用,这将使代码变得异常臃肿。

换位思考一下,我们需要计数的特性,useLoding 使用的 state 是 Boolean,那么有没有办法可以同时兼备布尔值和数字的特性呢?在 JS/TS 中,boolean 本身就支持加减操作,加减后会隐式转换为数字,答案已经呼之欲出了!允许我们的 useLodng 使用数字作为每个 loading 的值,即可完美的升级 useLoading,并完全兼容基础版的 useLoading,我们只需要做一些小小的改变:

接口和类型声明

在这里,将 boolean 都替换为 boolean | number 即可。
其次,我们提供了2个额外的 api:plusminus,即递增和递减。
此外,我还为 useLoading 新加了一个 returnType 入参的重载,因为有些人可能更偏爱对象而不是数组,比如笔者自己。

export interface UseLoading<T = Record<string, boolean | number>> {(loadingMap: T): readonly [T,SetLoading,(key: keyof T) => void,(key: keyof T) => void,(key: keyof T) => void,(key: keyof T) => void];(loadingMap: T, returnType: "object"): Readonly<{values: T;set: SetLoading;on: (key: keyof T) => void;un: (key: keyof T) => void;plus: (key: keyof T) => void;minus: (key: keyof T) => void;}>;
}export interface SetLoading<T = Record<string, boolean | number>,K extends keyof T = keyof T
> {(key: K, value?: boolean | number): void;(key: K, setAction: (pre: boolean | number) => boolean | number): void;(state: Record<K, boolean | number>): void;(setAction: (pre: T) => T): void;
}
代码实现

在这里,实现上与 基础的 useLoading 几乎完全相同,只是多了几个新的返回和一套对象形式的返回。

// @ts-ignore
export const useLoading: UseLoading = <T = Record<string, boolean | number>>(loadingMap: T,returnType: "array" | "object" = "array"
) => {const [loading, _setLoading] = useState(loadingMap);const setLoading: SetLoading<T, keyof T> = (args1, value = true) => {if (typeof args1 === "object") {_setLoading((pre) => ({ ...pre, ...args1 }));return;} else if (typeof args1 === "function") {_setLoading((pre) => args1(pre));return;} else {const key = args1;if (typeof value === "function") {_setLoading((pre) => ({ ...pre, [key]: value(pre[key]) }));} else {_setLoading((pre) => ({ ...pre, [key]: value }));}}};const onLoading = (key: keyof typeof loading) => {_setLoading((pre) => ({ ...pre, [key]: 1 }));};const unLoading = (key: keyof typeof loading) => {_setLoading((pre) => ({ ...pre, [key]: 0 }));};const plusLoading = (key: keyof typeof loading) => {_setLoading((pre) => ({ ...pre, [key]: (pre[key] as number) + 1 }));};const minusLoading = (key: keyof typeof loading) => {_setLoading((pre) => ({ ...pre, [key]: (pre[key] as number) - 1 }));};if (returnType === "array") {return [loading,setLoading,onLoading,unLoading,plusLoading,minusLoading,] as const;} else {return {values: loading,set: setLoading,on: onLoading,un: unLoading,plus: plusLoading,minus: minusLoading,} as const;}
};

现在,一个进阶版的 useLoading 就完成了,你完全可以把它当作普通的 useLoading 穿 boolean 用,如果有计数的需要你就可以把它当数字用:

function sleep<T>(time: number) {return new Promise<void>(function (resolve) {setTimeout(() => {resolve();}, time);});
}export default function Demo(){const { values: loading, plus, minus } = useLoading({ button1: false }, 'object');const click = async () => {plus('button1')await sleep(1000);minus('button1')}
}return(<><button onClick={click}>{loading.button1? 'loading':'button1'}</button></>)
}
http://www.hkea.cn/news/67790/

相关文章:

  • 服务佳的小企业网站建设ip子域名大全
  • 网页与制作唐山seo推广公司
  • 自己做的网站怎么弄到网上在线网页制作
  • 电商网站 设计方案百度的排名规则详解
  • 福建省建设厅网站余外链链接平台
  • 广告营销网站市场推广方案
  • 徐州企业做网站软文是什么文章
  • 网站代码备份如何优化seo
  • 百度网站公司信息推广怎么做天津做网站的网络公司
  • wordpress在线pdfseo百度站长工具查询
  • 太仓网站建设有限公司网站设计公司怎么样
  • 网站去哪做在线crm软件
  • 做360手机网站快速汕头seo排名收费
  • 网站建设总做总结宜兴百度推广公司
  • 做毕业网站的周记外贸建站优化
  • 南昌市住房和城乡建设局网站百度官网推广平台电话
  • 真人做视频网站百度怎么发布广告
  • 网站页面优化包括怎么给网站做优化
  • 哪个网站用帝国cms做的软文素材网
  • 网站建设需要的资料深圳精准网络营销推广
  • 客户网站建设公司网站排名提升软件
  • 网站建设与维护试卷论文怎么在百度上做广告
  • 做博客网站要什么技术百度网站网址是多少
  • 河北建设厅官方网站八大员考试站长工具查询
  • 大连 做网站公司爱站工具包的主要功能
  • ps做简洁大气网站必应bing国内版
  • 做公司标志用哪个网站营销自动化
  • wordpress5.0.3厦门百度seo
  • 网站开发 企业 定制系统优化大师安卓版
  • 网站内链符号seo百度站长工具