美文网首页
【组件2】对话框 - Dialog

【组件2】对话框 - Dialog

作者: darkTi | 来源:发表于2022-03-31 18:14 被阅读0次

    确定API

    • 要确保你的API和同行的API没有太大不同,否则用户学习成本变高,不利于我们的UI使用;所以我们就可以去copy下同行的API;
    • 提供两种风格:一是标签风格,二是API风格
    • 创建dialog目录;

    搭建Dialog 基本架子

    • <Fragment></Fragment>用于把多个div包起来,但是在页面中却不会渲染出来(有点像<template>),所以经常使用<Fragment></Fragment>来代替<div></div>
    • 我们需要在每个className上都写一遍dui-dialog-,岂不是很麻烦?!所以我们写个函数来统一它吧~
    • 返回函数的函数叫做高阶函数;

    添加CSS

    • 这里一个小问题,index.scss要引入到example.tsx中样式才有效!!!!只引入到index.tsx中在预览例子的时候样式不起作用!!!!(应该跟生产开发环境文件设置的入口有关)
    • 想要svg受外面字体颜色的控制,加上fill: currentColor;
    • 跟字体相关可以用px、em,跟布局宽度相关可以用min-width结合em;
    • 属性选择器[class^=xx]代表所有以xx开头的类;

    添加事件

    1、可以自定义按钮
    • 给dialog一个buttons Props,它是个数组;
    • 所以这时又有个小警告了,因为是个数组,需要给每一项设置key,就用到了React.cloneElement
    • 为什么用React.cloneElement,而不是直接button['key'] = index这样添加属性呢,因为报错啊!!!说不能给只读属性key赋值啊!!!
    2、给组件的props设置默认值
    Dialog.defaultProps = {
      closeonClickMask: false
    }
    
    • 一般设置过默认值后,这个props就是可选的,interface属性那里加上?
    3、ReactDOM.createPortal
    • ReactDOM.createPortal,这是由于层级问题引起的,给dialog的层级越小越好,这样也方便用户自己去改;
    • 一般网站架构师会设定好层级
    • 可以在文档中告诉开发者,你如何写可以覆盖我的层级;


      image.png

    注意:为了禁止遮罩层来回滑动,在对话框出现的时候document.body.style.overflow='hidden'document.body.style.paddingRight = '17px',关闭的时候恢复document.body.style.overflow='auto'document.body.style.paddingRight = '0'

    给Dialog提供便利的API——alert

    • 动态创建组件,即用ReactDOM.render()把组件渲染进div;
    • 关闭组件呢,即还是用ReactDOM.render()渲染组件,只不过是把组件的visible属性变成false;
    • ReactDOM.unmountComponentAtNode()文档
    //创建组件和节点
     const div = document.createElement("div");
      document.body.appendChild(div);
      document.body.style.overflow = 'hidden'
      ReactDOM.render(component, div);
    
    //消除组件和节点
    //第一句:把这个组件的visible改成false
    ReactDOM.render(React.cloneElement(component, {visible: false}), div)
    //第二句:把这个组件从div上卸载下来
    ReactDOM.unmountComponentAtNode(div)
     document.body.style.overflow = 'auto'
    //第三句:清除这个div
    div.remove()
    

    comfirm

    modal

    • ReactElement和ReactNode区别:ReactElement只能是标签元素,ReactNode还可以是字符串;
    • modal return一个函数出来,有点类似于闭包的形式;
    • 下面代码中button调用函数的形式,要写一个箭头函数去调用close(这个close函数是modal()return出来的函数),直接onClick={close}的话是不可以的,因为解析器是从右往左执行的,这样直接写,它找不到你声明的close在哪里,放在箭头函数中就可以的原因是,函数是延迟执行的,只有点击按钮时才调用函数; 所以在声明函数的时候不要直接去调用它本身!!!
    const openModal = () => {
        const close = modal(
          <div>
            <h1>你好</h1>
            <button style={{ color: "purple" }} onClick={() => close()}>
              close
            </button>
          </div>
        );
      };
    

    三者之前的区别

    1、是否有按钮
    • alert只有一个【确认】按钮,按钮没有回调函数;
    • comfirm有【取消】、【确认】按钮,且按钮有各自的回调函数;
    • modal没有按钮;
    2、传的内容
    • alert和comfirm传的内容仅仅是字符串;
    • modal不仅可以传字符串,还可以传元素,但要保证只有一个根元素;

    重构

    image.png
    • 写完代码请立即重构,消除重复的代码;
    • 看上图,抽出每个API中的part,可以看出它们的组成很相近,所以可以把它们写成一个公共的函数;

    总结

    • scopedClass 高阶函数;
    • React.Fragment
    • 使用&&或者三元表达式来做条件判断,一般不用if...else...来写条件判断,有点麻烦;
    • ReactDOM.createPortal传送门,可以使元素脱离当前位置到达你指定的节点位置;
    • 如何动态去生成一个组件;
    • 闭包传API;

    相关文章

      网友评论

          本文标题:【组件2】对话框 - Dialog

          本文链接:https://www.haomeiwen.com/subject/tzszfrtx.html