zoukankan      html  css  js  c++  java
  • 撸一个简单的前端代码编辑器(初稿)

    react hook 版,第一版写的比较简单

    效果图:

    组件:

    了解更多 <textarea> 标签

    index.jsx 文件

    import React, { useState, useEffect, useRef } from 'react';
    import styles from './index.module.scss';
    import PropTypes from 'prop-types';
    
    const MyEditor = props => {
      // const getYAMLJS = require('yamljs'); // 需先安装插件,转换 .yaml 文件内容的数据类型
      const { value, style, maxRow, onChange } = props;
      const [MyValue, setMyValue] = useState("");
      const [top, setTop] = useState(0);
      const lineNumberBox = useRef();
    
      useEffect(() => {
        if (onChange) {
          setMyValue(value);
        }
      }, [value])
    
      const textareaChange = (ev) => { // 修改内容
        if (onChange) {
          onChange(ev.target.value)
        } else {
          setMyValue(ev.target.value)
        }
      }
    
      const textareaScroll = (ev) => { // 获得滚动的距离
        setTop(ev.target.scrollTop)
      }
    
      const renderList = () => { // 生成行号
        const ary = [];
        for (let i = 1; i <= maxRow; i++) {
          ary.push(<li key={i}>{i}</li>)
        }
        return ary
      }
    
      return (
        <div className={styles.myEditor}>
          <div style={style} className={styles.myEditorBox}>
            <span className={styles.lineNumber}>
              <ul ref={lineNumberBox} style={{ top: `-${top}px` }}>
                {
                  renderList()
                }
              </ul>
            </span>
            <textarea id="textInner"
              className={styles.textInner}
              value={MyValue}
              onChange={textareaChange}
              onScroll={textareaScroll}
              style={{
                resize: style.height || style.width ? "none" : "auto",
                maxHeight: `${maxRow * 24}px`
              }}
            />
          </div>
        </div>
      );
    };
    
    MyEditor.defaultProps = {
      value: "",
      style: {
        height: "240px"
      },
      maxRow: 1000,
    };
    
    MyEditor.propTypes = {
      style: PropTypes.object,
      maxRow: PropTypes.number,
      // 和 input 一样, value 和 onChange 需同时使用,变成可控组件
      value: PropTypes.string, 
      onChange: PropTypes.func,
    };
    
    export default MyEditor;

    index.module.scss 样式文件

    .myEditor {
    
      .myEditorBox{ // 我的编辑器
        display: flex;
        justify-content: space-between;
        box-sizing: content-box;
        overflow: hidden;
        
        .lineNumber{
          box-sizing: content-box;
          display: inline-block;
          color: #999;
          background-color: #333;
          min- 38px;
          border-radius: 3px 0 0 3px;
          text-align: right;
          overflow: hidden;
          position: relative;
          ul{
            position: absolute;
            margin: 2px 0 0 0;
            padding: 0;
             100%;
            li{
              list-style-type: none; // 去掉 li 的默认样式
              padding: 0 0.5em 0 0;
               100%;
              line-height: 24px;
            }
          }
        }
        .textInner{
          flex: 1;
          box-sizing: content-box;
          padding: 0;
          line-height: 24px;
          min-height: 24px; //最小高度 即 每行高度 === 父级 line-height
          max-height: 2400px; //最大高度 === 10倍 line-height 相当于最多展现10行
          //  400px;
          background-color: #000;
          color: #ffffff;
          border-radius: 0 3px 3px 0;
          outline: none; // 去掉默认样式
        }
      }
    }

     可控组件的使用方式

    import React, { useState, useEffect } from 'react';
    import MyEditor from "@/components/MyEditor";
    
    function DeveloperPage(props) {
    
      const [value, setvalue] = useState(``)
    
      const onChange = (value) => {
        setvalue(value)
      }
    
      return (
        <div>
          <MyEditor
            style={{  "500px", height: "300px" }}
            value={value}
            onChange={onChange}
          // maxRow = 1000
          />
        </div>
      );
    }
    
    export default DeveloperPage;
  • 相关阅读:
    第七章第五题(打印不同的教)(Print distinct numbers)
    第七章第四题(分析成绩)(Analyze scores)
    第七章第三题(计算数字的出现次数)(Count occurrence of numbers)
    第七章第二题(倒置输入的数)(Reverse the numbers entered)
    第七章第一题(指定等级)(Assign grades)
    第六章第三十九题(几何:点的位置)(Geometry: point position)
    第六章第三十八题(生成随机字符)(Generate random characters)
    Java提示错误: 找不到或无法加载主类
    第六章第三十七题(格式化整数)(Format an integer)
    第六章第三十六题(几何:正多边形的面积)(Geometry: area of a regular polygon)
  • 原文地址:https://www.cnblogs.com/MrZhujl/p/13706814.html
Copyright © 2011-2022 走看看