├── .gitignore ├── .vscode └── settings.json ├── README.md ├── RcForm.html ├── RcForm ├── 01实现基本的propsForm属性.js ├── 02实现FieldsStore类实现设置字段与值.js ├── 03获取form值.js ├── 04设置和重置form值.js └── 05校验.js ├── common └── js │ ├── ajax.js │ ├── browser.5.8.38.js │ ├── browser.v5.8.38.js │ ├── browser.v6.1.19.js │ ├── react-dom.development.v16.12.0.js │ ├── react-dom.development.v16.13.1.js │ ├── react-dom.development.v16.14.0.js │ ├── react-dom.development.v17.0.2.js │ ├── react.development.v16.12.0.js │ ├── react.development.v16.13.1.js │ ├── react.development.v16.14.0.js │ ├── react.development.v17.0.2.js │ ├── react.v16.12.0.js │ ├── react.v16.14.0.js │ ├── react.v17.0.2.js │ └── react.v17.0.2copy.js ├── demo.js ├── es5.html ├── es5_code └── es5_react_code │ ├── 01 │ ├── 01.js │ ├── 02.js │ ├── 03.js │ ├── 04.js │ └── 05mapChildren.js │ ├── 02 │ └── 01.js │ ├── 03 │ └── 01.js │ └── 04 │ └── 01.js ├── es6.html ├── es6_code └── es6_react_code │ ├── 01 │ ├── 01.js │ ├── 02.js │ ├── 03.js │ ├── 04.js │ ├── 05mapChildren.js │ └── classConpoment.js │ ├── 02 │ └── 01.js │ ├── 03 │ └── 01.js │ ├── 04 │ └── 01.js │ ├── 05 │ └── 01.js │ ├── 06 │ └── 01.js │ └── demo │ ├── FiberNodeTree结构.js │ ├── classConpoment.js │ ├── functionConpoment.js │ └── tag各种组件测试.js ├── fre.html ├── fre.js ├── graphiql.js ├── graphql.html ├── index2.html ├── ng测试题.html ├── nodeServer.js ├── package-lock.json ├── package.json ├── react逐行源码分析文档 ├── 01.png ├── 02.png ├── 03.png ├── 04.png ├── 05.png ├── 06.png ├── createVonde.jpg ├── react帖子.md ├── react逐行源码分析 copy.md └── react逐行源码分析.md ├── scattered_deom ├── MessageChannel.html ├── Object.prototype.hasOwnProperty.html ├── Symbol.html ├── clz32Fallback.html ├── demo.html ├── describeComponentFrame.html ├── getIteratorFn.html ├── hasOwnProperty.html ├── hasValidRef.html ├── lowPriorityWarning.html ├── newSet.html ├── objectAssign.html ├── performance.html ├── performance.mark.html ├── performance.measure.html ├── performance.now.html ├── printWarning.html ├── reg.html ├── removeChild.html ├── requestAnimationFrame.html ├── requestAnimationFrame1.html ├── requestAnimationFrame2.html ├── scheduling.html ├── shouldUseNative.html ├── tranform-rpx-px.html ├── update.next.html ├── warningWithoutStack.html ├── 二叉树.html ├── 二进制,八进制,十进制,位与,或,非,等.html └── 堆化.html └── 正则 └── at.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.port": 5508 3 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react 2 | react 这是个react 源码逐行分析,并且是开源免费的,只需要你帮我们点个赞,多多支持下即可 3 | -------------------------------------------------------------------------------- /RcForm.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello React! 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 36 | 37 | 38 |
39 | 40 | 41 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /RcForm/01实现基本的propsForm属性.js: -------------------------------------------------------------------------------- 1 | const createForm = (options) => { 2 | return (Component) => { 3 | return class Form extends React.Component { 4 | getForm() { 5 | return { 6 | getFieldsValue: () => {}, // 获取字段值得函数 7 | getFieldValue: () => {}, // 获取单个值得函数 8 | getFieldInstance: () => {}, // 获取字段实例 9 | setFieldsValue: () => {}, // 设置字段值 10 | setFields: () => {}, // 设置字段 新的值 11 | setFieldsInitialValue: () => {}, // 设置初始化值的函数 12 | getFieldDecorator: () => {}, // 用于和表单进行双向绑定,详见下方描述 装饰组件,促进双向绑定的修饰器 13 | getFieldProps: () => {}, // 创建待验证的表单 设置字段元数据,返回 计算被修饰组件的属性 14 | getFieldsError: () => {}, //获取一组输入控件的 Error ,如不传入参数,则获取全部组件的 Error 15 | getFieldError: () => {}, //获取某个输入控件的 Error 16 | isFieldValidating: () => {}, //判断一个输入控件是否在校验状态 17 | isFieldsValidating: () => {}, // 判断字段是否在校验中 18 | isFieldsTouched: () => {}, //判断是否任一输入控件经历过 getFieldDecorator 的值收集时机 options.trigger 19 | isFieldTouched: () => {}, //判断一个输入控件是否经历过 getFieldDecorator 的值收集时机 options.trigger 20 | isSubmitting: () => {}, // 是否在 提交状态 21 | submit: () => {}, // 表单提交函数 22 | validateFields: () => {}, //验证字段,返回promise 23 | resetFields: () => {}, // 重置字段 24 | }; 25 | } 26 | render() { 27 | const props = { 28 | form: this.getForm.call(this), 29 | }; 30 | return ; 31 | } 32 | }; 33 | }; 34 | }; 35 | 36 | class BaseForm extends React.Component { 37 | constructor(props) { 38 | super(props); 39 | } 40 | 41 | componentDidMount() { 42 | console.log(this.props); 43 | debugger; 44 | } 45 | render() { 46 | return ( 47 |
48 | 49 | 52 |
53 | ); 54 | } 55 | } 56 | 57 | const Form = createForm({ name: "abc" })(BaseForm); 58 | 59 | ReactDOM.render(
, document.getElementById("example")); 60 | -------------------------------------------------------------------------------- /RcForm/02实现FieldsStore类实现设置字段与值.js: -------------------------------------------------------------------------------- 1 | const createForm = (options) => { 2 | return (Component) => { 3 | function Field() {} 4 | // 检查obj实例是否是Field的构造函数 5 | function isFormField(obj) { 6 | return obj instanceof Field; 7 | } 8 | // 创建字段 9 | function createFormField(field) { 10 | if (isFormField(field)) { 11 | return field; 12 | } 13 | return new Field(field); 14 | } 15 | 16 | class FieldsStore { 17 | // fields: {age: {…}, name: {…}, note.tree: {…}} // 提供个用户的字段 18 | // fieldsMeta: {normal: {…}, note.tree: {…}, age: {…}, name: {…}, address: {…}, …} // rcForm 操作的字段 19 | // getAllValues: ƒ () // 获取所有值 20 | // getFieldError: ƒ (name) // 获取字段错误信息 21 | // getFieldValue: ƒ (name) // 获取字段值 22 | // getFieldsError: ƒ (names) // 获取所有字段错误信息 23 | // getFieldsValue: ƒ (names) // 获取所有字段值 24 | // isFieldTouched: ƒ (name) 25 | // isFieldValidating: ƒ (name) 26 | // isFieldsTouched: ƒ (ns) 27 | // isFieldsValidating: ƒ (ns) 28 | // setFieldsInitialValue: ƒ (initialValues) // 设置字段初始化值 29 | 30 | // Property 31 | // clearField: ƒ clearField(name) 32 | // constructor: ƒ FieldsStore(fields // 字段 ) 33 | // flattenRegisteredFields: ƒ flattenRegisteredFields(fields) 34 | // getAllFieldsName: ƒ getAllFieldsName() 35 | // getField: ƒ getField(name) 36 | // getFieldMember: ƒ getFieldMember(name, member) 37 | // getFieldMeta: ƒ getFieldMeta(name) 38 | // getFieldValuePropValue: ƒ getFieldValuePropValue(fieldMeta) 39 | // getNestedAllFields: ƒ getNestedAllFields() 40 | // getNestedField: ƒ getNestedField(name, getter) 41 | // getNestedFields: ƒ getNestedFields(names, //字段名称 getter //自定义设置字段对象的函数 ) 42 | // getNotCollectedFields: ƒ getNotCollectedFields() 43 | // getValidFieldsFullName: ƒ getValidFieldsFullName(maybePartialName) 44 | // getValidFieldsName: ƒ getValidFieldsName() 45 | // getValueFromFields: ƒ getValueFromFields(name, // 字段名称 fields // 所有的字段 ) 46 | // isValidNestedFieldName: ƒ isValidNestedFieldName(name) 47 | // resetFields: ƒ resetFields(ns) 48 | // setFieldMeta: ƒ setFieldMeta(name, meta) 49 | // setFields: ƒ setFields(fields) 50 | // setFieldsAsDirty: ƒ setFieldsAsDirty() 51 | // updateFields: ƒ updateFields(fields) 52 | // babel 在线转换 https://www.babeljs.cn/repl 53 | constructor(fields) { 54 | this.fields = fields || {}; 55 | this.fieldsMeta = {}; // rcForm存储表单字段初始化的值 56 | 57 | // name: "address" 58 | // originalProps: {type: "text"} 59 | // ref: null 60 | // rules: (2) [ 61 | // { 62 | // message: "Please input your note!", 63 | // required: true 64 | // }, 65 | // { 66 | // validator: (rule, value, callback) => {…} 67 | // } 68 | // ] 69 | // trigger: "onChange" 70 | // validate: [ 71 | // { 72 | // message: "Please input your note!", 73 | // required: true 74 | // }, 75 | // { 76 | // validator: (rule, value, callback) => {…} 77 | // } 78 | // ] 79 | // valuePropName: "value" 80 | 81 | // 以下写法会直接添加到对象的实例中 82 | this.getAllValues = () => {}; // 获取所有值 83 | this.getFieldError = () => {}; // 获取字段错误信息 84 | this.getFieldValue = () => {}; // 获取字段值 85 | this.getFieldsError = () => {}; // 获取所有字段错误信息 86 | this.getFieldsValue = () => {}; // 获取所有字段值 87 | this.isFieldTouched = () => {}; 88 | this.isFieldValidating = () => {}; 89 | this.isFieldsTouched = () => {}; 90 | this.isFieldsValidating = () => {}; 91 | this.setFieldsInitialValue = () => {}; // 设置字段初始化值 92 | } 93 | 94 | // 以下写法会直接添加到对象的实例中,这样写法是es7写法, 由于 cdn 不支持es7 所以只能写在实例中 95 | // getAllValues=()=> {} // 获取所有值 96 | // getFieldError=()=> {} // 获取字段错误信息 97 | // getFieldValue=()=> {} // 获取字段值 98 | // getFieldsError=()=> {} // 获取所有字段错误信息 99 | // getFieldsValue=()=>{} // 获取所有字段值 100 | // isFieldTouched=()=> {} 101 | // isFieldValidating=()=>{} 102 | // isFieldsTouched=()=>{} 103 | // isFieldsValidating=()=> {} 104 | // setFieldsInitialValue=()=> {} // 设置字段初始化值 105 | 106 | // 以下写法会添加到对象的 property 中 107 | clearField() {} 108 | flattenRegisteredFields() {} 109 | getAllFieldsName() {} 110 | getField(name) { 111 | return this.fields[name] || {}; 112 | } 113 | getFieldMember() {} 114 | getFieldMeta(name) { 115 | this.fieldsMeta[name] = this.fieldsMeta[name] || {}; 116 | return this.fieldsMeta[name]; 117 | } 118 | getFieldValuePropValue(fieldMeta) { 119 | console.log('fieldMeta=',fieldMeta); 120 | 121 | //获取字段名称 122 | var name = fieldMeta.name, 123 | //获取ValueProps 124 | getValueProps = fieldMeta.getValueProps, 125 | valuePropName = fieldMeta.valuePropName; // 这里一般指的是value 126 | 127 | // 获取单个字段对象 128 | var field = this.getField(name); 129 | // 字段是否存在值,如果没有则给初始化值 130 | var fieldValue = 131 | "value" in field ? field.value : fieldMeta.initialValue; 132 | // 如果属性上面设置有值则返回值 133 | if (getValueProps) { 134 | return getValueProps(fieldValue); 135 | } 136 | return { 137 | [valuePropName]: fieldValue, 138 | }; 139 | } 140 | getNestedAllFields() {} 141 | getNestedField() {} 142 | getNestedFields() {} 143 | getNotCollectedFields() {} 144 | getValidFieldsFullName() {} 145 | getValidFieldsName() {} 146 | getValueFromFields( 147 | name, // 字段名称 148 | fields // 所有的字段 149 | ) { 150 | var field = fields[name]; // 获取当前的字段 151 | if (field && "value" in field) { 152 | return field.value; //如果有值的返回出去 153 | } 154 | // 获取单个字段的getFieldMeta 对象 这个是字段 信息 155 | var fieldMeta = this.getFieldMeta(name); 156 | // 如果字段用没有值则取初始化值 157 | return fieldMeta && fieldMeta.initialValue; 158 | } 159 | isValidNestedFieldName() {} 160 | resetFields() { 161 | 162 | 163 | } 164 | setFieldMeta(name, meta) { 165 | this.fieldsMeta[name] = meta; 166 | } 167 | setFields(fields) { 168 | // 获取字段信息 169 | var fieldsMeta = this.fieldsMeta; 170 | var nowFields = { 171 | ...this.fields, 172 | ...fields, 173 | }; 174 | // 新的值 175 | var nowValues = {}; 176 | // 获取字段的值 177 | Object.keys(fieldsMeta).forEach(function (f) { 178 | // 获取字段的值 179 | nowValues[f] = this.getValueFromFields( 180 | f, // 字段名称 181 | nowFields // 所有字段 182 | ); 183 | }); 184 | 185 | // 循环现在的值 然后注册到Meta 中 186 | Object.keys(nowValues).forEach((f) => { 187 | // 获取单个值 188 | var value = nowValues[f]; 189 | // 获取单个字段的getFieldMeta 对象 这个是字段 信息 190 | var fieldMeta = _this.getFieldMeta(f); 191 | // 初始化值设定的一个函数 demo https://codepen.io/afc163/pen/JJVXzG?editors=0010 192 | if (fieldMeta && fieldMeta.normalize) { 193 | // 获取字段的值 194 | //当前值 195 | var nowValue = fieldMeta.normalize( 196 | value, 197 | this.getValueFromFields(f, _this.fields), 198 | nowValues 199 | ); 200 | //如果新的值和旧的值不相同则更新新的值 201 | if (nowValue !== value) { 202 | nowFields[f] = { 203 | ... nowFields[f], 204 | value: nowValue, 205 | } 206 | } 207 | } 208 | // 设置 字段 209 | this.fields = nowFields; 210 | }); 211 | } 212 | setFieldsAsDirty() {} 213 | updateFields() {} 214 | } 215 | 216 | return class Form extends React.Component { 217 | constructor(props) { 218 | super(props); 219 | this.fieldsStore = new FieldsStore(); 220 | } 221 | getValueFromEvent(e) { 222 | console.log("e===========", e); 223 | console.log("e.target===========", e.target); 224 | // To support custom element 225 | if (!e || !e.target) { 226 | return e; 227 | } 228 | var target = e.target; 229 | 230 | return target.type === "checkbox" ? target.checked : target.value; 231 | } 232 | // 收集 事件中获取值 和从事件中设置值 233 | onCollectCommon(name, action, args) { 234 | // 获取单个字段的getFieldMeta 对象 这个是字段 信息 和设置 Meta 初始化值作用 235 | var fieldMeta = this.fieldsStore.getFieldMeta(name); 236 | // 判断fieldMeta 中有 事件么 如果有有则执行事件 237 | if (fieldMeta[action]) { 238 | // 执行方法 239 | fieldMeta[action].apply( 240 | fieldMeta, 241 | // 数组去重 242 | [...new Set(args)] 243 | ); 244 | } else if ( 245 | //原始组件的的props 属性 246 | fieldMeta.originalProps && 247 | //原始组件的的props 属性 事件 248 | fieldMeta.originalProps[action] 249 | ) { 250 | var _fieldMeta$originalPr; 251 | 252 | (_fieldMeta$originalPr = fieldMeta.originalProps)[action].apply( 253 | _fieldMeta$originalPr, 254 | // 数组去重 255 | [...new Set(args)] 256 | ); 257 | } 258 | 259 | //从事件中获取值 260 | var value = fieldMeta.getValueFromEvent 261 | ? fieldMeta.getValueFromEvent.apply( 262 | fieldMeta, 263 | // 数组去重 264 | [...new Set(args)] 265 | ) 266 | : this.getValueFromEvent.apply( 267 | undefined, 268 | // 数组去重 269 | [...new Set(args)] 270 | ); 271 | // 获取字段 272 | var field = this.fieldsStore.getField(name); 273 | return { 274 | // 字段名称 275 | name: name, 276 | // 合并新的字段 277 | field: {...field, value: value, touched: true } , 278 | // 字段存储对象 279 | fieldMeta: fieldMeta, 280 | }; 281 | } 282 | onCollectValidate(name_, action) { 283 | console.log("arguments=", arguments); 284 | console.log("onCollectValidate==========="); 285 | for ( 286 | var _len2 = arguments.length, 287 | args = Array(_len2 > 2 ? _len2 - 2 : 0), 288 | _key2 = 2; 289 | _key2 < _len2; 290 | _key2++ 291 | ) { 292 | // 收集大于2个参数组成数组存放在args数组中 293 | args[_key2 - 2] = arguments[_key2]; 294 | } 295 | // 收集设置字段 从事件中获取值 和从事件中设置值 296 | var onCollectCommon = this.onCollectCommon(name_, action, args) 297 | console.log('onCollectCommon=',onCollectCommon) 298 | 299 | 300 | } 301 | getForm() { 302 | return { 303 | getFieldsValue: () => {}, // 获取字段值得函数 304 | getFieldValue: () => {}, // 获取单个值得函数 305 | getFieldInstance: () => {}, // 获取字段实例 306 | setFieldsValue: () => {}, // 设置字段值 307 | setFields: () => {}, // 设置字段 新的值 308 | setFieldsInitialValue: () => {}, // 设置初始化值的函数 309 | getFieldDecorator: () => {}, // 用于和表单进行双向绑定,详见下方描述 装饰组件,促进双向绑定的修饰器 310 | getFieldProps: (name, usersFieldOption) => { 311 | //获取字段选项参数 312 | var fieldOption = { 313 | ...{ 314 | name: name, // 字段名称 315 | trigger: "onChange", //onChange 收集子节点的值的时机 316 | valuePropName: "value", // 字段value 317 | validate: [], // 验证 空数组 318 | }, 319 | ...usersFieldOption, 320 | }; 321 | var fieldMeta = this.fieldsStore.getFieldMeta(name); 322 | 323 | console.log("this.fieldsStore==", this.fieldsStore); 324 | // 判断是否有初始化值 325 | if ("initialValue" in fieldOption) { 326 | // 如果有重新赋值 327 | fieldMeta.initialValue = fieldOption.initialValue; 328 | } 329 | // 获取字段的value 值 330 | var inputProps = this.fieldsStore.getFieldValuePropValue( 331 | fieldOption 332 | ); 333 | 334 | 335 | inputProps[fieldOption.trigger] = this.onCollectValidate.bind( 336 | this, 337 | name, 338 | fieldOption.trigger 339 | ); 340 | console.log("inputProps=", inputProps); 341 | return inputProps; 342 | // this.fieldsStore.cre; 343 | }, // 创建待验证的表单 设置字段元数据,返回 计算被修饰组件的属性 344 | getFieldsError: () => {}, //获取一组输入控件的 Error ,如不传入参数,则获取全部组件的 Error 345 | getFieldError: () => {}, //获取某个输入控件的 Error 346 | isFieldValidating: () => {}, //判断一个输入控件是否在校验状态 347 | isFieldsValidating: () => {}, // 判断字段是否在校验中 348 | isFieldsTouched: () => {}, //判断是否任一输入控件经历过 getFieldDecorator 的值收集时机 options.trigger 349 | isFieldTouched: () => {}, //判断一个输入控件是否经历过 getFieldDecorator 的值收集时机 options.trigger 350 | isSubmitting: () => {}, // 是否在 提交状态 351 | submit: () => {}, // 表单提交函数 352 | validateFields: () => { 353 | 354 | }, //验证字段,返回promise 355 | resetFields: () => {}, // 重置字段 356 | }; 357 | } 358 | 359 | render() { 360 | const props = { 361 | form: this.getForm.call(this), 362 | }; 363 | return ; 364 | } 365 | }; 366 | }; 367 | }; 368 | 369 | class BaseForm extends React.Component { 370 | constructor(props) { 371 | super(props); 372 | } 373 | 374 | componentDidMount() { 375 | console.log(this.props); 376 | // debugger; 377 | } 378 | submit = (e) => { 379 | // this.props.form.resetFields(["note"]); 380 | // console.log("this.props.form=", this.props.form); 381 | 382 | // this.props.form.setFields({ 383 | // "note.tree": { 384 | // value: 123, 385 | // // errors: [new Error("forbid ha")], 386 | // }, 387 | // }); 388 | 389 | // setTimeout(() => { 390 | this.props.form.validateFields((error, value) => { 391 | console.log(error, value); 392 | debugger; 393 | }); 394 | e.preventDefault(); 395 | e.stopPropagation(); 396 | e.cancelBubble = true; 397 | return false; 398 | // }, 100); 399 | }; 400 | render() { 401 | const { form: { getFieldProps } = {} } = this.props; 402 | return ( 403 | 404 | 405 | 409 | 412 | 413 | ); 414 | } 415 | } 416 | 417 | const Form = createForm({ name: "abc" })(BaseForm); 418 | 419 | ReactDOM.render(
, document.getElementById("example")); 420 | -------------------------------------------------------------------------------- /RcForm/03获取form值.js: -------------------------------------------------------------------------------- 1 | const createForm = (options) => { 2 | return (Component) => { 3 | function Field() {} 4 | // 检查obj实例是否是Field的构造函数 5 | function isFormField(obj) { 6 | return obj instanceof Field; 7 | } 8 | // 创建字段 9 | function createFormField(field) { 10 | if (isFormField(field)) { 11 | return field; 12 | } 13 | return new Field(field); 14 | } 15 | 16 | class FieldsStore { 17 | // fields: {age: {…}, name: {…}, note.tree: {…}} // 提供个用户的字段 18 | // fieldsMeta: {normal: {…}, note.tree: {…}, age: {…}, name: {…}, address: {…}, …} // rcForm 操作的字段 19 | // getAllValues: ƒ () // 获取所有值 20 | // getFieldError: ƒ (name) // 获取字段错误信息 21 | // getFieldValue: ƒ (name) // 获取字段值 22 | // getFieldsError: ƒ (names) // 获取所有字段错误信息 23 | // getFieldsValue: ƒ (names) // 获取所有字段值 24 | // isFieldTouched: ƒ (name) 25 | // isFieldValidating: ƒ (name) 26 | // isFieldsTouched: ƒ (ns) 27 | // isFieldsValidating: ƒ (ns) 28 | // setFieldsInitialValue: ƒ (initialValues) // 设置字段初始化值 29 | 30 | // Property 31 | // clearField: ƒ clearField(name) 32 | // constructor: ƒ FieldsStore(fields // 字段 ) 33 | // flattenRegisteredFields: ƒ flattenRegisteredFields(fields) 34 | // getAllFieldsName: ƒ getAllFieldsName() 35 | // getField: ƒ getField(name) 36 | // getFieldMember: ƒ getFieldMember(name, member) 37 | // getFieldMeta: ƒ getFieldMeta(name) 38 | // getFieldValuePropValue: ƒ getFieldValuePropValue(fieldMeta) 39 | // getNestedAllFields: ƒ getNestedAllFields() 40 | // getNestedField: ƒ getNestedField(name, getter) 41 | // getNestedFields: ƒ getNestedFields(names, //字段名称 getter //自定义设置字段对象的函数 ) 42 | // getNotCollectedFields: ƒ getNotCollectedFields() 43 | // getValidFieldsFullName: ƒ getValidFieldsFullName(maybePartialName) 44 | // getValidFieldsName: ƒ getValidFieldsName() 45 | // getValueFromFields: ƒ getValueFromFields(name, // 字段名称 fields // 所有的字段 ) 46 | // isValidNestedFieldName: ƒ isValidNestedFieldName(name) 47 | // resetFields: ƒ resetFields(ns) 48 | // setFieldMeta: ƒ setFieldMeta(name, meta) 49 | // setFields: ƒ setFields(fields) 50 | // setFieldsAsDirty: ƒ setFieldsAsDirty() 51 | // updateFields: ƒ updateFields(fields) 52 | // babel 在线转换 https://www.babeljs.cn/repl 53 | constructor(fields) { 54 | this.fields = fields || {}; 55 | this.fieldsMeta = {}; // rcForm存储表单字段初始化的值 56 | 57 | // name: "address" 58 | // originalProps: {type: "text"} 59 | // ref: null 60 | // rules: (2) [ 61 | // { 62 | // message: "Please input your note!", 63 | // required: true 64 | // }, 65 | // { 66 | // validator: (rule, value, callback) => {…} 67 | // } 68 | // ] 69 | // trigger: "onChange" 70 | // validate: [ 71 | // { 72 | // message: "Please input your note!", 73 | // required: true 74 | // }, 75 | // { 76 | // validator: (rule, value, callback) => {…} 77 | // } 78 | // ] 79 | // valuePropName: "value" 80 | 81 | // 以下写法会直接添加到对象的实例中 82 | // this.getAllValues = () => {}; // 获取所有值 83 | this.getFieldError = () => {}; // 获取字段错误信息 84 | this.getFieldValue = (name) => { 85 | var fields = this.fields; 86 | console.log("name=", name); 87 | console.log("fields=", fields); 88 | 89 | return this.getValueFromFields( 90 | name, // 字段名称 91 | fields // 所有的字段 92 | ); 93 | }; // 获取字段值 94 | this.getFieldsError = () => {}; // 获取所有字段错误信息 95 | 96 | this.getFieldsValue = (names) => { 97 | // 重新定义设置 fields 每个field对象的值,可以根据getter函数值, 可以返回自定义的值 98 | console.log( 99 | "this.getNestedFields(names, this.getFieldValue)=", 100 | this.getNestedFields(names, this.getFieldValue) 101 | ); 102 | 103 | return this.getNestedFields(names, this.getFieldValue); 104 | }; // 获取所有字段值 105 | this.isFieldTouched = () => {}; 106 | this.isFieldValidating = () => {}; 107 | this.isFieldsTouched = () => {}; 108 | this.isFieldsValidating = () => {}; 109 | this.setFieldsInitialValue = () => {}; // 设置字段初始化值 110 | } 111 | 112 | // 以下写法会直接添加到对象的实例中,这样写法是es7写法, 由于 cdn 不支持es7 所以只能写在实例中 113 | // getAllValues=()=> {} // 获取所有值 114 | // getFieldError=()=> {} // 获取字段错误信息 115 | // getFieldValue=()=> {} // 获取字段值 116 | // getFieldsError=()=> {} // 获取所有字段错误信息 117 | // getFieldsValue=()=>{} // 获取所有字段值 118 | // isFieldTouched=()=> {} 119 | // isFieldValidating=()=>{} 120 | // isFieldsTouched=()=>{} 121 | // isFieldsValidating=()=> {} 122 | // setFieldsInitialValue=()=> {} // 设置字段初始化值 123 | 124 | // 以下写法会添加到对象的 property 中 125 | clearField() {} 126 | flattenRegisteredFields() {} 127 | getAllFieldsName() {} 128 | getField(name) { 129 | return this.fields[name] || {}; 130 | } 131 | getFieldMember() {} 132 | getFieldMeta(name) { 133 | this.fieldsMeta[name] = this.fieldsMeta[name] || {}; 134 | return this.fieldsMeta[name]; 135 | } 136 | getFieldValuePropValue(fieldMeta) { 137 | console.log("fieldMeta=", fieldMeta); 138 | 139 | //获取字段名称 140 | var name = fieldMeta.name, 141 | //获取ValueProps 142 | getValueProps = fieldMeta.getValueProps, 143 | valuePropName = fieldMeta.valuePropName; // 这里一般指的是value 144 | 145 | // 获取单个字段对象 146 | var field = this.getField(name); 147 | // 字段是否存在值,如果没有则给初始化值 148 | var fieldValue = 149 | "value" in field ? field.value : fieldMeta.initialValue; 150 | // 如果属性上面设置有值则返回值 151 | if (getValueProps) { 152 | return getValueProps(fieldValue); 153 | } 154 | return { 155 | [valuePropName]: fieldValue, 156 | }; 157 | } 158 | getNestedAllFields() {} 159 | getNestedField() {} 160 | getNotCollectedFields() {} 161 | getValidFieldsFullName() {} 162 | getValidFieldsName() { 163 | //记录fieldsMeta 字段信息 164 | var fieldsMeta = this.fieldsMeta; 165 | console.log("this.fieldsMeta=", this.fieldsMeta); 166 | 167 | return fieldsMeta 168 | ? Object.keys(fieldsMeta).filter((name) => { 169 | // 获取单个字段的getFieldMeta 对象 这个是字段 信息 170 | return !this.getFieldMeta(name).hidden; 171 | }) 172 | : []; 173 | } 174 | getValueFromFields( 175 | name, // 字段名称 176 | fields // 所有的字段 177 | ) { 178 | var field = fields[name]; // 获取当前的字段 179 | if (field && "value" in field) { 180 | return field.value; //如果有值的返回出去 181 | } 182 | // 获取单个字段的getFieldMeta 对象 这个是字段 信息 183 | var fieldMeta = this.getFieldMeta(name); 184 | // 如果字段用没有值则取初始化值 185 | return fieldMeta && fieldMeta.initialValue; 186 | } 187 | getNestedFields( 188 | names, //字段名称 189 | getter //自定义设置字段对象的函数 190 | ) { 191 | // 获取所有字段的名称,不包含 含有hidden 属性的字段 192 | var fields = names || this.getValidFieldsName(); 193 | console.log("fields=", fields); 194 | 195 | 196 | return fields.reduce( 197 | function (acc, f) { 198 | // field设置对象值 199 | return { ...acc, [f]: getter(f) }; 200 | }, 201 | {} //初始化值 202 | ); 203 | } 204 | isValidNestedFieldName() {} 205 | resetFields() {} 206 | setFieldMeta(name, meta) { 207 | this.fieldsMeta[name] = meta; 208 | } 209 | setFields(fields) { 210 | // 获取字段信息 211 | var fieldsMeta = this.fieldsMeta; 212 | console.log('fields=',fields) 213 | console.log('this.fields=',this.fields) 214 | 215 | var nowFields = { 216 | ...this.fields, 217 | ...fields, 218 | }; 219 | console.log('nowFields=',nowFields) 220 | 221 | // 新的值 222 | var nowValues = {}; 223 | // 获取字段的值 224 | Object.keys(fieldsMeta).forEach( (f)=> { 225 | // 获取字段的值 226 | nowValues[f] = this.getValueFromFields( 227 | f, // 字段名称 228 | nowFields // 所有字段 229 | ); 230 | }); 231 | 232 | // 循环现在的值 然后注册到Meta 中 233 | Object.keys(nowValues).forEach((f) => { 234 | // 获取单个值 235 | var value = nowValues[f]; 236 | // 获取单个字段的getFieldMeta 对象 这个是字段 信息 237 | var fieldMeta = this.getFieldMeta(f); 238 | // 初始化值设定的一个函数 demo https://codepen.io/afc163/pen/JJVXzG?editors=0010 239 | if (fieldMeta && fieldMeta.normalize) { 240 | // 获取字段的值 241 | //当前值 242 | var nowValue = fieldMeta.normalize( 243 | value, 244 | this.getValueFromFields(f, this.fields), 245 | nowValues 246 | ); 247 | //如果新的值和旧的值不相同则更新新的值 248 | if (nowValue !== value) { 249 | nowFields[f] = { 250 | ...nowFields[f], 251 | value: nowValue, 252 | }; 253 | } 254 | } 255 | // 设置 字段 256 | this.fields = nowFields; 257 | }); 258 | } 259 | setFieldsAsDirty() {} 260 | updateFields() {} 261 | } 262 | 263 | return class Form extends React.Component { 264 | constructor(props) { 265 | super(props); 266 | this.fieldsStore = new FieldsStore(); 267 | } 268 | getValueFromEvent(e) { 269 | console.log("e===========", e); 270 | console.log("e.target===========", e.target); 271 | // To support custom element 272 | if (!e || !e.target) { 273 | return e; 274 | } 275 | var target = e.target; 276 | 277 | return target.type === "checkbox" ? target.checked : target.value; 278 | } 279 | // 收集 事件中获取值 和从事件中设置值 280 | onCollectCommon(name, action, args) { 281 | // 获取单个字段的getFieldMeta 对象 这个是字段 信息 和设置 Meta 初始化值作用 282 | var fieldMeta = this.fieldsStore.getFieldMeta(name); 283 | // 判断fieldMeta 中有 事件么 如果有有则执行事件 284 | if (fieldMeta[action]) { 285 | // 执行方法 286 | fieldMeta[action].apply( 287 | fieldMeta, 288 | // 数组去重 289 | [...new Set(args)] 290 | ); 291 | } else if ( 292 | //原始组件的的props 属性 293 | fieldMeta.originalProps && 294 | //原始组件的的props 属性 事件 295 | fieldMeta.originalProps[action] 296 | ) { 297 | var _fieldMeta$originalPr; 298 | 299 | (_fieldMeta$originalPr = fieldMeta.originalProps)[action].apply( 300 | _fieldMeta$originalPr, 301 | // 数组去重 302 | [...new Set(args)] 303 | ); 304 | } 305 | 306 | //从事件中获取值 307 | var value = fieldMeta.getValueFromEvent 308 | ? fieldMeta.getValueFromEvent.apply( 309 | fieldMeta, 310 | // 数组去重 311 | [...new Set(args)] 312 | ) 313 | : this.getValueFromEvent.apply( 314 | undefined, 315 | // 数组去重 316 | [...new Set(args)] 317 | ); 318 | // 获取字段 319 | var field = this.fieldsStore.getField(name); 320 | return { 321 | // 字段名称 322 | name: name, 323 | // 合并新的字段 324 | field: { ...field, value: value, touched: true }, 325 | // 字段存储对象 326 | fieldMeta: fieldMeta, 327 | }; 328 | } 329 | onCollectValidate(name_, action) { 330 | console.log("arguments=", arguments); 331 | console.log("arguments=", arguments); 332 | console.log("onCollectValidate==========="); 333 | for ( 334 | var _len2 = arguments.length, 335 | args = Array(_len2 > 2 ? _len2 - 2 : 0), 336 | _key2 = 2; 337 | _key2 < _len2; 338 | _key2++ 339 | ) { 340 | // 收集大于2个参数组成数组存放在args数组中 341 | args[_key2 - 2] = arguments[_key2]; 342 | } 343 | // 收集设置字段 从事件中获取值 和从事件中设置值 344 | var onCollectCommon = this.onCollectCommon(name_, action, args), 345 | name = onCollectCommon.name, // 字段名称 346 | field = onCollectCommon.field, //字段 347 | fieldMeta = onCollectCommon.fieldMeta; //字段存储对象 348 | 349 | var newField = { ...field }; 350 | console.log('this=',this) 351 | console.log('newField=',newField) 352 | console.log('name=',name) 353 | // 设置字段 354 | this.getForm().setFields( 355 | // 为对象添加 描述设置属性 或者是为对象添加 属性或者方法 356 | { [name]: newField } 357 | ); 358 | console.log("onCollectCommon=", onCollectCommon); 359 | } 360 | // 获取全部字段值的函数 返回是对象 {key:value} 数据形式 361 | getAllValues() { 362 | var fieldsMeta = this.fieldsMeta, 363 | fields = this.fields; 364 | 365 | return Object.keys(fieldsMeta).reduce(function (acc, name) { 366 | // 获取字段的值 367 | return { ...acc, name: this.getValueFromFields(name, fields) }; 368 | }, {}); 369 | } 370 | getForm() { 371 | return { 372 | getFieldsValue: () => { 373 | // this.getValueFromFields name, // 字段名称 374 | // fields // 所有的字段 375 | // this.getValueFromFields(name, fields) 376 | }, // 获取字段值得函数 377 | getFieldValue: () => {}, // 获取单个值得函数 378 | getFieldInstance: () => {}, // 获取字段实例 379 | setFieldsValue: () => {}, // 设置字段值 380 | setFields: (fields) => { 381 | /// 到这里 382 | // // 设置字段 新的值 383 | this.fieldsStore.setFields(fields); 384 | // // 强制更新 render 385 | // this.forceUpdate(callback); 386 | }, // 设置字段 新的值 387 | setFieldsInitialValue: () => {}, // 设置初始化值的函数 388 | getFieldDecorator: ( 389 | name, // 字段名称 390 | fieldOption // 字段设置参数 391 | ) => { 392 | var props = this.getForm().getFieldProps(name,fieldOption) 393 | return (fieldElem)=>{ 394 | var fieldMeta = this.fieldsStore.getFieldMeta(name); 395 | return React.cloneElement( 396 | fieldElem, //原来的vnode 397 | // props 属性 398 | { 399 | ...props, // 用户传进来的 props 属性 400 | // 获取value 属性值 401 | ...this.fieldsStore.getFieldValuePropValue(fieldMeta) 402 | } 403 | ); 404 | } 405 | }, // 用于和表单进行双向绑定,详见下方描述 装饰组件,促进双向绑定的修饰器 406 | getFieldProps: (name, usersFieldOption) => { 407 | //获取字段选项参数 408 | var fieldOption = { 409 | ...{ 410 | name: name, // 字段名称 411 | trigger: "onChange", //onChange 收集子节点的值的时机 412 | valuePropName: "value", // 字段value 413 | validate: [], // 验证 空数组 414 | }, 415 | ...usersFieldOption, 416 | }; 417 | var fieldMeta = this.fieldsStore.getFieldMeta(name); 418 | 419 | console.log("this.fieldsStore==", this.fieldsStore); 420 | // 判断是否有初始化值 421 | if ("initialValue" in fieldOption) { 422 | // 如果有重新赋值 423 | fieldMeta.initialValue = fieldOption.initialValue; 424 | } 425 | // 获取字段的value 值 426 | var inputProps = this.fieldsStore.getFieldValuePropValue( 427 | fieldOption 428 | ); 429 | // 绑定的时候就会传字段 和 事件 430 | inputProps[fieldOption.trigger] = this.onCollectValidate.bind( 431 | this, 432 | name, 433 | fieldOption.trigger 434 | ); 435 | console.log("inputProps=", inputProps); 436 | // 合并验证规则到fieldMeta 对象中 437 | var meta = { 438 | ...fieldMeta, 439 | ...fieldOption, 440 | // validate: validateRules, 441 | }; 442 | // 重新设置fieldMeta 443 | this.fieldsStore.setFieldMeta(name, meta); 444 | 445 | return inputProps; 446 | // this.fieldsStore.cre; 447 | }, // 创建待验证的表单 设置字段元数据,返回 计算被修饰组件的属性 448 | getFieldsError: () => {}, //获取一组输入控件的 Error ,如不传入参数,则获取全部组件的 Error 449 | getFieldError: () => {}, //获取某个输入控件的 Error 450 | isFieldValidating: () => {}, //判断一个输入控件是否在校验状态 451 | isFieldsValidating: () => {}, // 判断字段是否在校验中 452 | isFieldsTouched: () => {}, //判断是否任一输入控件经历过 getFieldDecorator 的值收集时机 options.trigger 453 | isFieldTouched: () => {}, //判断一个输入控件是否经历过 getFieldDecorator 的值收集时机 options.trigger 454 | isSubmitting: () => {}, // 是否在 提交状态 455 | submit: () => {}, // 表单提交函数 456 | validateFields: (callback) => { 457 | console.log("this.fieldsStore=", this.fieldsStore); 458 | 459 | // 获取字段名称 从所有字段中 过滤出 maybePartialName 参数匹配到的字段 460 | var fieldNames = this.fieldsStore.getValidFieldsName(); 461 | console.log("fieldNames=", fieldNames); 462 | console.log("this.fieldsStore=", this.fieldsStore); 463 | 464 | // 获取字段值 465 | callback(null, this.fieldsStore.getFieldsValue(fieldNames)); 466 | }, //验证字段,返回promise 467 | resetFields: () => {}, // 重置字段 468 | }; 469 | } 470 | 471 | render() { 472 | const props = { 473 | form: this.getForm.call(this), 474 | }; 475 | return ; 476 | } 477 | }; 478 | }; 479 | }; 480 | 481 | class BaseForm extends React.Component { 482 | constructor(props) { 483 | super(props); 484 | } 485 | 486 | componentDidMount() { 487 | console.log(this.props); 488 | 489 | } 490 | submit(e) { 491 | // this.props.form.resetFields(["note"]); 492 | // console.log("this.props.form=", this.props.form); 493 | 494 | // this.props.form.setFields({ 495 | // "note.tree": { 496 | // value: 123, 497 | // // errors: [new Error("forbid ha")], 498 | // }, 499 | // }); 500 | 501 | // setTimeout(() => { 502 | this.props.form.validateFields((error, value) => { 503 | console.log(error, value); 504 | 505 | }); 506 | e.preventDefault(); 507 | e.stopPropagation(); 508 | e.cancelBubble = true; 509 | 510 | return false; 511 | // }, 100); 512 | } 513 | render() { 514 | const { form: { getFieldProps,getFieldDecorator } = {} } = this.props; 515 | return ( 516 | 517 | 姓名:
518 | 年龄:
519 | 地址: {getFieldDecorator("address", { 520 | // rules: [ 521 | // { required: true, message: "Please input your note!" }, 522 | // { 523 | // validator: (rule, value, callback) => { 524 | // const { getFieldValue } = this.props.form; 525 | // // if (value && value !== getFieldValue("newPassword")) { 526 | // callback("年龄不正确"); 527 | // // } 528 | 529 | // // Note: 必须总是返回一个 callback,否则 validateFieldsAndScroll 无法响应 530 | // // callback(); 531 | // }, 532 | // }, 533 | // ], 534 | })()} 535 |
536 | 537 | 541 |
提交
542 | 543 | ); 544 | } 545 | } 546 | 547 | const Form = createForm({ name: "abc" })(BaseForm); 548 | 549 | ReactDOM.render(
, document.getElementById("example")); 550 | -------------------------------------------------------------------------------- /RcForm/04设置和重置form值.js: -------------------------------------------------------------------------------- 1 | const createForm = (options) => { 2 | return (Component) => { 3 | function Field() {} 4 | // 检查obj实例是否是Field的构造函数 5 | function isFormField(obj) { 6 | return obj instanceof Field; 7 | } 8 | // 创建字段 9 | function createFormField(field) { 10 | if (isFormField(field)) { 11 | return field; 12 | } 13 | return new Field(field); 14 | } 15 | 16 | class FieldsStore { 17 | // fields: {age: {…}, name: {…}, note.tree: {…}} // 提供个用户的字段 18 | // fieldsMeta: {normal: {…}, note.tree: {…}, age: {…}, name: {…}, address: {…}, …} // rcForm 操作的字段 19 | // getAllValues: ƒ () // 获取所有值 20 | // getFieldError: ƒ (name) // 获取字段错误信息 21 | // getFieldValue: ƒ (name) // 获取字段值 22 | // getFieldsError: ƒ (names) // 获取所有字段错误信息 23 | // getFieldsValue: ƒ (names) // 获取所有字段值 24 | // isFieldTouched: ƒ (name) 25 | // isFieldValidating: ƒ (name) 26 | // isFieldsTouched: ƒ (ns) 27 | // isFieldsValidating: ƒ (ns) 28 | // setFieldsInitialValue: ƒ (initialValues) // 设置字段初始化值 29 | 30 | // Property 31 | // clearField: ƒ clearField(name) 32 | // constructor: ƒ FieldsStore(fields // 字段 ) 33 | // flattenRegisteredFields: ƒ flattenRegisteredFields(fields) 34 | // getAllFieldsName: ƒ getAllFieldsName() 35 | // getField: ƒ getField(name) 36 | // getFieldMember: ƒ getFieldMember(name, member) 37 | // getFieldMeta: ƒ getFieldMeta(name) 38 | // getFieldValuePropValue: ƒ getFieldValuePropValue(fieldMeta) 39 | // getNestedAllFields: ƒ getNestedAllFields() 40 | // getNestedField: ƒ getNestedField(name, getter) 41 | // getNestedFields: ƒ getNestedFields(names, //字段名称 getter //自定义设置字段对象的函数 ) 42 | // getNotCollectedFields: ƒ getNotCollectedFields() 43 | // getValidFieldsFullName: ƒ getValidFieldsFullName(maybePartialName) 44 | // getValidFieldsName: ƒ getValidFieldsName() 45 | // getValueFromFields: ƒ getValueFromFields(name, // 字段名称 fields // 所有的字段 ) 46 | // isValidNestedFieldName: ƒ isValidNestedFieldName(name) 47 | // resetFields: ƒ resetFields(ns) 48 | // setFieldMeta: ƒ setFieldMeta(name, meta) 49 | // setFields: ƒ setFields(fields) 50 | // setFieldsAsDirty: ƒ setFieldsAsDirty() 51 | // updateFields: ƒ updateFields(fields) 52 | // babel 在线转换 https://www.babeljs.cn/repl 53 | constructor(fields) { 54 | this.fields = fields || {}; 55 | this.fieldsMeta = {}; // rcForm存储表单字段初始化的值 56 | 57 | // name: "address" 58 | // originalProps: {type: "text"} 59 | // ref: null 60 | // rules: (2) [ 61 | // { 62 | // message: "Please input your note!", 63 | // required: true 64 | // }, 65 | // { 66 | // validator: (rule, value, callback) => {…} 67 | // } 68 | // ] 69 | // trigger: "onChange" 70 | // validate: [ 71 | // { 72 | // message: "Please input your note!", 73 | // required: true 74 | // }, 75 | // { 76 | // validator: (rule, value, callback) => {…} 77 | // } 78 | // ] 79 | // valuePropName: "value" 80 | 81 | // 以下写法会直接添加到对象的实例中 82 | // this.getAllValues = () => {}; // 获取所有值 83 | this.getFieldError = () => {}; // 获取字段错误信息 84 | this.getFieldValue = (name) => { 85 | var fields = this.fields; 86 | console.log("name=", name); 87 | console.log("fields=", fields); 88 | 89 | return this.getValueFromFields( 90 | name, // 字段名称 91 | fields // 所有的字段 92 | ); 93 | }; // 获取字段值 94 | this.getFieldsError = () => {}; // 获取所有字段错误信息 95 | 96 | this.getFieldsValue = (names) => { 97 | // 重新定义设置 fields 每个field对象的值,可以根据getter函数值, 可以返回自定义的值 98 | console.log( 99 | "this.getNestedFields(names, this.getFieldValue)=", 100 | this.getNestedFields(names, this.getFieldValue) 101 | ); 102 | 103 | return this.getNestedFields(names, this.getFieldValue); 104 | }; // 获取所有字段值 105 | this.isFieldTouched = () => {}; 106 | this.isFieldValidating = () => {}; 107 | this.isFieldsTouched = () => {}; 108 | this.isFieldsValidating = () => {}; 109 | this.setFieldsInitialValue = () => {}; // 设置字段初始化值 110 | } 111 | 112 | // 以下写法会直接添加到对象的实例中,这样写法是es7写法, 由于 cdn 不支持es7 所以只能写在实例中 113 | // getAllValues=()=> {} // 获取所有值 114 | // getFieldError=()=> {} // 获取字段错误信息 115 | // getFieldValue=()=> {} // 获取字段值 116 | // getFieldsError=()=> {} // 获取所有字段错误信息 117 | // getFieldsValue=()=>{} // 获取所有字段值 118 | // isFieldTouched=()=> {} 119 | // isFieldValidating=()=>{} 120 | // isFieldsTouched=()=>{} 121 | // isFieldsValidating=()=> {} 122 | // setFieldsInitialValue=()=> {} // 设置字段初始化值 123 | 124 | // 以下写法会添加到对象的 property 中 125 | clearField() {} 126 | flattenRegisteredFields() {} 127 | //获取全部字段名称 128 | getAllFieldsName() { 129 | //记录fieldsMeta 字段信息 130 | var fieldsMeta = this.fieldsMeta; 131 | return fieldsMeta ? Object.keys(fieldsMeta) : []; 132 | } 133 | getField(name) { 134 | return this.fields[name] || {}; 135 | } 136 | getFieldMember() {} 137 | getFieldMeta(name) { 138 | this.fieldsMeta[name] = this.fieldsMeta[name] || {}; 139 | return this.fieldsMeta[name]; 140 | } 141 | getFieldValuePropValue(fieldMeta) { 142 | console.log("fieldMeta=", fieldMeta); 143 | 144 | //获取字段名称 145 | var name = fieldMeta.name, 146 | //获取ValueProps 147 | getValueProps = fieldMeta.getValueProps, 148 | valuePropName = fieldMeta.valuePropName; // 这里一般指的是value 149 | 150 | // 获取单个字段对象 151 | var field = this.getField(name); 152 | // 字段是否存在值,如果没有则给初始化值 153 | var fieldValue = 154 | "value" in field ? field.value : fieldMeta.initialValue; 155 | // 如果属性上面设置有值则返回值 156 | if (getValueProps) { 157 | return getValueProps(fieldValue); 158 | } 159 | return { 160 | [valuePropName]: fieldValue, 161 | }; 162 | } 163 | getNestedAllFields() {} 164 | getNestedField() {} 165 | getNotCollectedFields() {} 166 | // 过滤 167 | getValidFieldsFullName(fields) { 168 | console.log("this.getValidFieldsName()===", this.getValidFieldsName()); 169 | return this.getValidFieldsName().filter(function (fullName) { 170 | return fields.some((item) => item == fullName); 171 | }); 172 | } 173 | getValidFieldsName() { 174 | //记录fieldsMeta 字段信息 175 | var fieldsMeta = this.fieldsMeta; 176 | console.log("this.fieldsMeta=", this.fieldsMeta); 177 | 178 | return fieldsMeta 179 | ? Object.keys(fieldsMeta).filter((name) => { 180 | // 获取单个字段的getFieldMeta 对象 这个是字段 信息 181 | return !this.getFieldMeta(name).hidden; 182 | }) 183 | : []; 184 | } 185 | getValueFromFields( 186 | name, // 字段名称 187 | fields // 所有的字段 188 | ) { 189 | var field = fields[name]; // 获取当前的字段 190 | if (field && "value" in field) { 191 | return field.value; //如果有值的返回出去 192 | } 193 | // 获取单个字段的getFieldMeta 对象 这个是字段 信息 194 | var fieldMeta = this.getFieldMeta(name); 195 | // 如果字段用没有值则取初始化值 196 | return fieldMeta && fieldMeta.initialValue; 197 | } 198 | getNestedFields( 199 | names, //字段名称 200 | getter //自定义设置字段对象的函数 201 | ) { 202 | // 获取所有字段的名称,不包含 含有hidden 属性的字段 203 | var fields = names || this.getValidFieldsName(); 204 | console.log("fields=", fields); 205 | 206 | return fields.reduce( 207 | function (acc, f) { 208 | // field设置对象值 209 | return { ...acc, [f]: getter(f) }; 210 | }, 211 | {} //初始化值 212 | ); 213 | } 214 | isValidNestedFieldName() {} 215 | resetFields(ns) { 216 | var fields = this.fields; 217 | // 重置字段的值 218 | // 从所有字段中 过滤出 maybePartialName 参数匹配到的字段 //获取全部字段名称 219 | console.log( 220 | " this.fieldsStore.getValidFieldsFullName(ns)=", 221 | this.getValidFieldsFullName(ns) 222 | ); 223 | var names = ns 224 | ? this.getValidFieldsFullName(ns) 225 | : this.getAllFieldsName(); 226 | console.log("names==", names); 227 | console.log("fields==", fields); 228 | // 重置 value 清空 229 | return names.reduce(function (acc, name) { 230 | var field = fields[name]; 231 | if (field && "value" in field) { 232 | acc[name] = {}; 233 | } 234 | return acc; 235 | }, {}); 236 | } 237 | setFieldMeta(name, meta) { 238 | this.fieldsMeta[name] = meta; 239 | } 240 | setFields(fields) { 241 | // 获取字段信息 242 | var fieldsMeta = this.fieldsMeta; 243 | console.log("setFields fields=", fields); 244 | console.log("this.fields=", this.fields); 245 | 246 | var nowFields = { 247 | ...this.fields, 248 | ...fields, 249 | }; 250 | console.log("nowFields=", nowFields); 251 | 252 | // 新的值 253 | var nowValues = {}; 254 | // 获取字段的值 255 | Object.keys(fieldsMeta).forEach((f) => { 256 | // 获取字段的值 257 | nowValues[f] = this.getValueFromFields( 258 | f, // 字段名称 259 | nowFields // 所有字段 260 | ); 261 | }); 262 | console.log("nowValues=", nowValues); 263 | debugger; 264 | 265 | // 循环现在的值 然后注册到Meta 中 266 | Object.keys(nowValues).forEach((f) => { 267 | // 获取单个值 268 | var value = nowValues[f]; 269 | // 获取单个字段的getFieldMeta 对象 这个是字段 信息 270 | var fieldMeta = this.getFieldMeta(f); 271 | var nowValue = fieldMeta.value; 272 | 273 | // 初始化值设定的一个函数 demo https://codepen.io/afc163/pen/JJVXzG?editors=0010 274 | // if (fieldMeta && fieldMeta.normalize) { 275 | // // 获取字段的值 276 | // //当前值 277 | // var nowValue = fieldMeta.normalize( 278 | // value, 279 | // this.getValueFromFields(f, this.fields), 280 | // nowValues 281 | // ); 282 | // //如果新的值和旧的值不相同则更新新的值 283 | // if (nowValue !== value) { 284 | // nowFields[f] = { 285 | // ...nowFields[f], 286 | // value: nowValue, 287 | // }; 288 | // } 289 | // } 290 | if (nowValue !== value) { 291 | nowFields[f] = { 292 | ...nowFields[f], 293 | value: nowValue, 294 | }; 295 | } 296 | // 设置 字段 297 | this.fields = nowFields; 298 | }); 299 | } 300 | setFieldsAsDirty() {} 301 | updateFields() {} 302 | } 303 | 304 | return class Form extends React.Component { 305 | constructor(props) { 306 | super(props); 307 | this.fieldsStore = new FieldsStore(); 308 | } 309 | getValueFromEvent(e) { 310 | console.log("e===========", e); 311 | console.log("e.target===========", e.target); 312 | // To support custom element 313 | if (!e || !e.target) { 314 | return e; 315 | } 316 | var target = e.target; 317 | 318 | return target.type === "checkbox" ? target.checked : target.value; 319 | } 320 | // 收集 事件中获取值 和从事件中设置值 321 | onCollectCommon(name, action, args) { 322 | // 获取单个字段的getFieldMeta 对象 这个是字段 信息 和设置 Meta 初始化值作用 323 | var fieldMeta = this.fieldsStore.getFieldMeta(name); 324 | // 判断fieldMeta 中有 事件么 如果有有则执行事件 325 | if (fieldMeta[action]) { 326 | // 执行方法 327 | fieldMeta[action].apply( 328 | fieldMeta, 329 | // 数组去重 330 | [...new Set(args)] 331 | ); 332 | } else if ( 333 | //原始组件的的props 属性 334 | fieldMeta.originalProps && 335 | //原始组件的的props 属性 事件 336 | fieldMeta.originalProps[action] 337 | ) { 338 | var _fieldMeta$originalPr; 339 | 340 | (_fieldMeta$originalPr = fieldMeta.originalProps)[action].apply( 341 | _fieldMeta$originalPr, 342 | // 数组去重 343 | [...new Set(args)] 344 | ); 345 | } 346 | 347 | //从事件中获取值 348 | var value = fieldMeta.getValueFromEvent 349 | ? fieldMeta.getValueFromEvent.apply( 350 | fieldMeta, 351 | // 数组去重 352 | [...new Set(args)] 353 | ) 354 | : this.getValueFromEvent.apply( 355 | undefined, 356 | // 数组去重 357 | [...new Set(args)] 358 | ); 359 | // 获取字段 360 | var field = this.fieldsStore.getField(name); 361 | return { 362 | // 字段名称 363 | name: name, 364 | // 合并新的字段 365 | field: { ...field, value: value, touched: true }, 366 | // 字段存储对象 367 | fieldMeta: fieldMeta, 368 | }; 369 | } 370 | onCollectValidate(name_, action) { 371 | console.log("arguments=", arguments); 372 | console.log("arguments=", arguments); 373 | console.log("onCollectValidate==========="); 374 | for ( 375 | var _len2 = arguments.length, 376 | args = Array(_len2 > 2 ? _len2 - 2 : 0), 377 | _key2 = 2; 378 | _key2 < _len2; 379 | _key2++ 380 | ) { 381 | // 收集大于2个参数组成数组存放在args数组中 382 | args[_key2 - 2] = arguments[_key2]; 383 | } 384 | // 收集设置字段 从事件中获取值 和从事件中设置值 385 | var onCollectCommon = this.onCollectCommon(name_, action, args), 386 | name = onCollectCommon.name, // 字段名称 387 | field = onCollectCommon.field, //字段 388 | fieldMeta = onCollectCommon.fieldMeta; //字段存储对象 389 | 390 | var newField = { ...field }; 391 | console.log("this=", this); 392 | console.log("newField=", newField); 393 | console.log("name=", name); 394 | // 设置字段 395 | this.getForm().setFields( 396 | // 为对象添加 描述设置属性 或者是为对象添加 属性或者方法 397 | { [name]: newField } 398 | ); 399 | console.log("onCollectCommon=", onCollectCommon); 400 | } 401 | // 获取全部字段值的函数 返回是对象 {key:value} 数据形式 402 | getAllValues() { 403 | var fieldsMeta = this.fieldsMeta, 404 | fields = this.fields; 405 | 406 | return Object.keys(fieldsMeta).reduce(function (acc, name) { 407 | // 获取字段的值 408 | return { ...acc, name: this.getValueFromFields(name, fields) }; 409 | }, {}); 410 | } 411 | getForm() { 412 | return { 413 | getFieldsValue: () => { 414 | // this.getValueFromFields name, // 字段名称 415 | // fields // 所有的字段 416 | // this.getValueFromFields(name, fields) 417 | }, // 获取字段值得函数 418 | getFieldValue: () => {}, // 获取单个值得函数 419 | getFieldInstance: () => {}, // 获取字段实例 420 | setFieldsValue: ( 421 | // 改变的值 对象类型 {[key]:newValue} 422 | changedValues, 423 | // 回调函数 424 | callback 425 | ) => { 426 | // { 427 | // field:value, 428 | // } 429 | // 获取 原来的 字段 信息 430 | var fieldsMeta = this.fieldsStore.fieldsMeta; 431 | changedValues = Object.keys(changedValues).reduce((acc, key) => { 432 | return { 433 | ...acc, 434 | [key]: { 435 | value: changedValues[key], 436 | }, 437 | }; 438 | }, {}); 439 | console.log("changedValues===", changedValues); 440 | this.getForm().setFields(changedValues, callback); 441 | }, // 设置字段值 442 | setFields: ( 443 | fields, //{ field:{value:value} } 444 | callback = () => {} 445 | ) => { 446 | console.log("fields=", fields); 447 | 448 | /// 到这里 449 | // // 设置字段 新的值 450 | this.fieldsStore.setFields(fields); 451 | // 获取字段名称 从所有字段中 过滤出 maybePartialName 参数匹配到的字段 452 | var fieldNames = this.fieldsStore.getValidFieldsName(); 453 | console.log("fieldNames=", fieldNames); 454 | console.log( 455 | "this.fieldsStore.getFieldsValue(fieldNames)=", 456 | this.fieldsStore.getFieldsValue(fieldNames) 457 | ); 458 | debugger; 459 | // // 强制更新 render 460 | this.forceUpdate( 461 | callback.bind(null, this.fieldsStore.getFieldsValue(fieldNames)) 462 | ); 463 | }, // 设置字段 新的值 464 | setFieldsInitialValue: () => {}, // 设置初始化值的函数 465 | getFieldDecorator: ( 466 | name, // 字段名称 467 | fieldOption // 字段设置参数 468 | ) => { 469 | var props = this.getForm().getFieldProps(name, fieldOption); 470 | return (fieldElem) => { 471 | var fieldMeta = this.fieldsStore.getFieldMeta(name); 472 | return React.cloneElement( 473 | fieldElem, //原来的vnode 474 | // props 属性 475 | { 476 | ...props, // 用户传进来的 props 属性 477 | // 获取value 属性值 478 | ...this.fieldsStore.getFieldValuePropValue(fieldMeta), 479 | } 480 | ); 481 | }; 482 | }, // 用于和表单进行双向绑定,详见下方描述 装饰组件,促进双向绑定的修饰器 483 | getFieldProps: (name, usersFieldOption) => { 484 | //获取字段选项参数 485 | var fieldOption = { 486 | ...{ 487 | name: name, // 字段名称 488 | trigger: "onChange", //onChange 收集子节点的值的时机 489 | valuePropName: "value", // 字段value 490 | validate: [], // 验证 空数组 491 | }, 492 | ...usersFieldOption, 493 | }; 494 | var fieldMeta = this.fieldsStore.getFieldMeta(name); 495 | 496 | console.log("this.fieldsStore==", this.fieldsStore); 497 | // 判断是否有初始化值 498 | if ("initialValue" in fieldOption) { 499 | // 如果有重新赋值 500 | fieldMeta.initialValue = fieldOption.initialValue; 501 | } 502 | // 获取字段的value 值 503 | var inputProps = this.fieldsStore.getFieldValuePropValue( 504 | fieldOption 505 | ); 506 | // 绑定的时候就会传字段 和 事件 507 | inputProps[fieldOption.trigger] = this.onCollectValidate.bind( 508 | this, 509 | name, 510 | fieldOption.trigger 511 | ); 512 | console.log("inputProps=", inputProps); 513 | // 合并验证规则到fieldMeta 对象中 514 | var meta = { 515 | ...fieldMeta, 516 | ...fieldOption, 517 | // validate: validateRules, 518 | }; 519 | // 重新设置fieldMeta 520 | this.fieldsStore.setFieldMeta(name, meta); 521 | 522 | return inputProps; 523 | // this.fieldsStore.cre; 524 | }, // 创建待验证的表单 设置字段元数据,返回 计算被修饰组件的属性 525 | getFieldsError: () => {}, //获取一组输入控件的 Error ,如不传入参数,则获取全部组件的 Error 526 | getFieldError: () => {}, //获取某个输入控件的 Error 527 | isFieldValidating: () => {}, //判断一个输入控件是否在校验状态 528 | isFieldsValidating: () => {}, // 判断字段是否在校验中 529 | isFieldsTouched: () => {}, //判断是否任一输入控件经历过 getFieldDecorator 的值收集时机 options.trigger 530 | isFieldTouched: () => {}, //判断一个输入控件是否经历过 getFieldDecorator 的值收集时机 options.trigger 531 | isSubmitting: () => {}, // 是否在 提交状态 532 | submit: () => {}, // 表单提交函数 533 | validateFields: (callback) => { 534 | console.log("this.fieldsStore=", this.fieldsStore); 535 | 536 | // 获取字段名称 从所有字段中 过滤出 maybePartialName 参数匹配到的字段 537 | var fieldNames = this.fieldsStore.getValidFieldsName(); 538 | console.log("fieldNames=", fieldNames); 539 | console.log("this.fieldsStore=", this.fieldsStore); 540 | 541 | // 获取字段值 542 | callback(null, this.fieldsStore.getFieldsValue(fieldNames)); 543 | }, //验证字段,返回promise 544 | resetFields: (ns) => { 545 | var newFields = this.fieldsStore.resetFields(ns); 546 | 547 | var fields = this.fieldsStore.fields; 548 | if (Object.keys(newFields).length > 0) { 549 | console.log("newFields", newFields); 550 | 551 | // 设置字段 重新设置值 552 | this.getForm().setFields(newFields); 553 | } 554 | }, // 重置字段 555 | }; 556 | } 557 | 558 | render() { 559 | const props = { 560 | form: this.getForm.call(this), 561 | }; 562 | return ; 563 | } 564 | }; 565 | }; 566 | }; 567 | 568 | class BaseForm extends React.Component { 569 | constructor(props) { 570 | super(props); 571 | } 572 | 573 | componentDidMount() { 574 | console.log(this.props); 575 | 576 | this.props.form.setFieldsValue( 577 | { 578 | name: "姓名", 579 | }, 580 | (value) => { 581 | console.log(value); 582 | this.props.form.resetFields(["name", "age"]); 583 | } 584 | ); 585 | } 586 | submit(e) { 587 | // this.props.form.resetFields(["note"]); 588 | // console.log("this.props.form=", this.props.form); 589 | 590 | // this.props.form.setFields({ 591 | // "note.tree": { 592 | // value: 123, 593 | // // errors: [new Error("forbid ha")], 594 | // }, 595 | // }); 596 | 597 | // setTimeout(() => { 598 | this.props.form.validateFields((error, value) => { 599 | console.log(error, value); 600 | }); 601 | e.preventDefault(); 602 | e.stopPropagation(); 603 | e.cancelBubble = true; 604 | 605 | return false; 606 | // }, 100); 607 | } 608 | render() { 609 | const { form: { getFieldProps, getFieldDecorator } = {} } = this.props; 610 | return ( 611 | 612 | 姓名:
613 | 年龄: 614 |
615 | 地址:{" "} 616 | {getFieldDecorator("address", { 617 | // rules: [ 618 | // { required: true, message: "Please input your note!" }, 619 | // { 620 | // validator: (rule, value, callback) => { 621 | // const { getFieldValue } = this.props.form; 622 | // // if (value && value !== getFieldValue("newPassword")) { 623 | // callback("年龄不正确"); 624 | // // } 625 | // // Note: 必须总是返回一个 callback,否则 validateFieldsAndScroll 无法响应 626 | // // callback(); 627 | // }, 628 | // }, 629 | // ], 630 | })()} 631 |
632 | 636 |
提交
637 | 638 | ); 639 | } 640 | } 641 | 642 | const Form = createForm({ name: "abc" })(BaseForm); 643 | 644 | ReactDOM.render(
, document.getElementById("example")); 645 | -------------------------------------------------------------------------------- /common/js/ajax.js: -------------------------------------------------------------------------------- 1 | function ajax(options){ 2 | options = options ||{}; //调用函数时如果options没有指定,就给它赋值{},一个空的Object 3 | options.type=(options.type || "GET").toUpperCase();/// 请求格式GET、POST,默认为GET 4 | options.dataType=options.dataType || "json"; //响应数据格式,默认json 5 | 6 | var params=formatParams(options.data);//options.data请求的数据 7 | 8 | var xhr; 9 | 10 | //考虑兼容性 11 | if(window.XMLHttpRequest){ 12 | xhr=new XMLHttpRequest(); 13 | }else if(window.ActiveObject){//兼容IE6以下版本 14 | xhr=new ActiveXobject('Microsoft.XMLHTTP'); 15 | } 16 | 17 | //启动并发送一个请求 18 | if(options.type=="GET"){ 19 | xhr.open("GET",options.url+"?"+params,true); 20 | xhr.send(null); 21 | }else if(options.type=="POST"){ 22 | xhr.open("post",options.url,true); 23 | 24 | //设置表单提交时的内容类型 25 | //Content-type数据请求的格式 26 | xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 27 | xhr.send(params); 28 | } 29 | 30 | // 设置有效时间 31 | setTimeout(function(){ 32 | if(xhr.readySate!=4){ 33 | xhr.abort(); 34 | } 35 | },options.timeout) 36 | 37 | // 接收 38 | // options.success成功之后的回调函数 options.error失败后的回调函数 39 | //xhr.responseText,xhr.responseXML 获得字符串形式的响应数据或者XML形式的响应数据 40 | xhr.onreadystatechange=function(){ 41 | if(xhr.readyState==4){ 42 | var status=xhr.status; 43 | if(status>=200&& status<300 || status==304){ 44 | options.success&&options.success(xhr.responseText,xhr.responseXML); 45 | }else{ 46 | options.error&&options.error(status); 47 | } 48 | } 49 | } 50 | } 51 | 52 | //格式化请求参数 53 | function formatParams(data){ 54 | var arr=[]; 55 | for(var name in data){ 56 | arr.push(encodeURIComponent(name)+"="+encodeURIComponent(data[name])); 57 | } 58 | arr.push(("v="+Math.random()).replace(".","")); 59 | return arr.join("&"); 60 | 61 | } 62 | 63 | -------------------------------------------------------------------------------- /demo.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2021-05-10 18:11:35 4 | * @LastEditTime: 2021-05-10 18:15:06 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /react/demo.js 8 | */ 9 | 10 | var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; 11 | var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; 12 | 13 | 14 | ReactSharedInternals 15 | ReactCurrentBatchConfig: ReactCurrentBatchConfig, // *跟踪当前批处理的配置,比如更新多长时间 , *如有需要,应暂停。 16 | 17 | var ReactCurrentBatchConfig = { 18 | suspense: null, 19 | }; 20 | 21 | 22 | var ReactSharedInternals = { 23 | ReactCurrentDispatcher: ReactCurrentDispatcher, // 跟踪当前调度程序。 24 | ReactCurrentBatchConfig: ReactCurrentBatchConfig, // *跟踪当前批处理的配置,比如更新多长时间 , *如有需要,应暂停。 25 | ReactCurrentOwner: ReactCurrentOwner, //跟踪当前的所有者。*当前所有者是应该拥有任何组件的组件 *正在执行中。 26 | IsSomeRendererActing: IsSomeRendererActing, //由act()使用,以跟踪您是否处于act()范围内。 27 | // Used by renderers to avoid bundling object-assign twice in UMD bundles: 28 | assign: objectAssign, //浅拷贝函数 29 | }; 30 | 31 | { 32 | objectAssign(ReactSharedInternals, { 33 | // These should not be included in production. 这些不应该包括在生产中。 34 | ReactDebugCurrentFrame: ReactDebugCurrentFrame, 35 | // Shim for React DOM 16.0.0 which still destructured (but not used) this. 用于DOM 16.0.0的垫片仍然破坏(但没有使用)这个。 36 | // TODO: remove in React 17.0. 待办事项:在17.0 react中移除。 37 | ReactComponentTreeHook: {}, 38 | }); 39 | } 40 | 41 | 42 | 43 | var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; 44 | 45 | function requestCurrentSuspenseConfig() { 46 | /* 47 | var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; 48 | var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; 49 | */ 50 | return ReactCurrentBatchConfig.suspense; 51 | } 52 | -------------------------------------------------------------------------------- /es5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello React! 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 41 | 42 | 43 | 44 |
45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /es5_code/es5_react_code/01/01.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2021-05-06 12:29:53 4 | * @LastEditTime: 2022-03-29 17:34:39 5 | * @LastEditors: Yao guan shou 6 | * @Description: In User Settings Edit 7 | * @FilePath: /react/es5_code/es5_react_code/01/01.js 8 | */ 9 | 10 | 'use strict'; 11 | var vonde = React.createElement('h1', null, 'Hello, world'); 12 | console.log('vonde=', vonde); 13 | console.log('ReactDOM.render=', ReactDOM.render); 14 | debugger; 15 | ReactDOM.render(vonde, document.getElementById('example')); -------------------------------------------------------------------------------- /es5_code/es5_react_code/01/02.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2021-04-10 18:51:19 4 | * @LastEditTime: 2021-04-10 18:51:38 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /react源码分析/es5_code/es5_react_code/01/02.js 8 | */ 9 | 'use strict'; 10 | 11 | var H = function H() { 12 | return React.createElement( 13 | 'h1', 14 | null, 15 | 'Hello, world' 16 | ); 17 | }; 18 | ReactDOM.render(React.createElement(H, null), document.getElementById('example')); 19 | -------------------------------------------------------------------------------- /es5_code/es5_react_code/01/03.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var H = function H() { 4 | return React.createElement( 5 | "div", 6 | null, 7 | React.createElement( 8 | "h1", 9 | null, 10 | "这个是标题" 11 | ), 12 | React.createElement( 13 | "p", 14 | null, 15 | "这个是内容" 16 | ) 17 | ); 18 | }; -------------------------------------------------------------------------------- /es5_code/es5_react_code/01/04.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var style = { 4 | width: '100px', 5 | height: '200px', 6 | color: 'red' 7 | }; 8 | var H = function H() { 9 | return React.createElement( 10 | 'div', { 11 | style: style 12 | }, 13 | 'Hello, world' 14 | ); 15 | }; 16 | ReactDOM.render(React.createElement(H, null), document.getElementById('example')); -------------------------------------------------------------------------------- /es5_code/es5_react_code/01/05mapChildren.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Date: 2022-05-30 21:22:17 3 | * @Author: Yao guan shou 4 | * @LastEditors: Yao guan shou 5 | * @LastEditTime: 2022-05-30 22:29:34 6 | * @FilePath: /react/es5_code/es5_react_code/01/05mapChildren.js 7 | * @Description: 8 | */ 9 | 10 | 'use strict'; 11 | 12 | var _React = React; 13 | var Children = _React.Children; 14 | 15 | var HighOrderComponent = function HighOrderComponent(props) { 16 | var children = props.children; 17 | 18 | return React.createElement('div', null, React.createElement('div', null, '我是父组件'), React.createElement('div', null, Children.map(children, function(child) { 19 | console.log('child=============', child); 20 | 21 | return React.createElement('div', null, child); 22 | })), 'Ï'); 23 | }; 24 | var Child = function Child() { 25 | return React.createElement('div', null, '我是子组件'); 26 | }; 27 | ReactDOM.render(React.createElement(HighOrderComponent, null, React.createElement(Child, null), React.createElement(Child, null), React.createElement(Child, null), React.createElement(Child, null), React.createElement(Child, null)), document.getElementById('example')); -------------------------------------------------------------------------------- /es5_code/es5_react_code/02/01.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var number = 0; 4 | var H = function H() { 5 | return React.createElement( 6 | 'div', { 7 | onClick: function() { 8 | console.log(++number); 9 | } 10 | }, 11 | '点击事件' 12 | ); 13 | }; 14 | console.log('H=',H()) 15 | ReactDOM.render(React.createElement(H, null), document.getElementById('example')); -------------------------------------------------------------------------------- /es5_code/es5_react_code/03/01.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var _extends = Object.assign || function(target) { 4 | for (var i = 1; i < arguments.length; i++) { 5 | var source = arguments[i]; 6 | for (var key in source) { 7 | if (Object.prototype.hasOwnProperty.call(source, key)) { 8 | target[key] = source[key]; 9 | } 10 | } 11 | } 12 | return target; 13 | }; 14 | 15 | var _createClass = (function() { 16 | function defineProperties(target, props) { 17 | for (var i = 0; i < props.length; i++) { 18 | var descriptor = props[i]; 19 | descriptor.enumerable = descriptor.enumerable || false; 20 | descriptor.configurable = true; 21 | if ('value' in descriptor) descriptor.writable = true; 22 | Object.defineProperty(target, descriptor.key, descriptor); 23 | } 24 | } 25 | return function(Constructor, protoProps, staticProps) { 26 | if (protoProps) defineProperties(Constructor.prototype, protoProps); 27 | if (staticProps) defineProperties(Constructor, staticProps); 28 | return Constructor; 29 | }; 30 | })(); 31 | 32 | var _get = function get(_x, _x2, _x3) { 33 | var _again = true; 34 | _function: while (_again) { 35 | var object = _x, 36 | property = _x2, 37 | receiver = _x3; 38 | _again = false; 39 | if (object === null) object = Function.prototype; 40 | var desc = Object.getOwnPropertyDescriptor(object, property); 41 | if (desc === undefined) { 42 | var parent = Object.getPrototypeOf(object); 43 | if (parent === null) { 44 | return undefined; 45 | } else { 46 | _x = parent; 47 | _x2 = property; 48 | _x3 = receiver; 49 | _again = true; 50 | desc = parent = undefined; 51 | continue _function; 52 | } 53 | } else if ('value' in desc) { 54 | return desc.value; 55 | } else { 56 | var getter = desc.get; 57 | if (getter === undefined) { 58 | return undefined; 59 | } 60 | return getter.call(receiver); 61 | } 62 | } 63 | }; 64 | 65 | function _classCallCheck(instance, Constructor) { 66 | if (!(instance instanceof Constructor)) { 67 | throw new TypeError('Cannot call a class as a function'); 68 | } 69 | } 70 | 71 | function _inherits(subClass, superClass) { 72 | if (typeof superClass !== 'function' && superClass !== null) { 73 | throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); 74 | } 75 | subClass.prototype = Object.create(superClass && superClass.prototype, { 76 | constructor: { 77 | value: subClass, 78 | enumerable: false, 79 | writable: true, 80 | configurable: true 81 | } 82 | }); 83 | if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; 84 | } 85 | 86 | var ThemeContext = React.createContext(); 87 | 88 | function Button(props) { 89 | console.log('props===', props); 90 | return React.createElement( 91 | 'button', 92 | null, 93 | props.theme 94 | ); 95 | } 96 | 97 | function ThemedButton(props) { 98 | return React.createElement( 99 | ThemeContext.Consumer, 100 | null, 101 | function(theme) { 102 | console.log('theme=', theme); 103 | console.log('props==', props); 104 | return React.createElement(Button, _extends({}, props, { 105 | theme: theme 106 | })); 107 | } 108 | ); 109 | } 110 | 111 | function Toolbar(props) { 112 | return React.createElement( 113 | 'div', 114 | null, 115 | React.createElement(ThemedButton, null) 116 | ); 117 | } 118 | 119 | var App = (function(_React$Component) { 120 | _inherits(App, _React$Component); 121 | 122 | function App() { 123 | _classCallCheck(this, App); 124 | 125 | _get(Object.getPrototypeOf(App.prototype), 'constructor', this).apply(this, arguments); 126 | } 127 | 128 | _createClass(App, [{ 129 | key: 'render', 130 | value: function render() { 131 | return React.createElement( 132 | ThemeContext.Provider, { 133 | value: 'dark' 134 | }, 135 | React.createElement(Toolbar, null) 136 | ); 137 | } 138 | }]); 139 | 140 | return App; 141 | })(React.Component); 142 | 143 | ReactDOM.render(React.createElement(App, null), document.getElementById('example')); -------------------------------------------------------------------------------- /es5_code/es5_react_code/04/01.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var _slicedToArray = (function() { 4 | function sliceIterator(arr, i) { 5 | var _arr = []; 6 | var _n = true; 7 | var _d = false; 8 | var _e = undefined; 9 | try { 10 | for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { 11 | _arr.push(_s.value); 12 | if (i && _arr.length === i) break; 13 | } 14 | } catch (err) { 15 | _d = true; 16 | _e = err; 17 | } finally { 18 | try { 19 | if (!_n && _i["return"]) _i["return"](); 20 | } finally { 21 | if (_d) throw _e; 22 | } 23 | } 24 | return _arr; 25 | } 26 | return function(arr, i) { 27 | if (Array.isArray(arr)) { 28 | return arr; 29 | } else if (Symbol.iterator in Object(arr)) { 30 | return sliceIterator(arr, i); 31 | } else { 32 | throw new TypeError("Invalid attempt to destructure non-iterable instance"); 33 | } 34 | }; 35 | })(); 36 | 37 | var Show = function Show(props) { 38 | var flag = props.flag; 39 | 40 | React.useEffect(function() { 41 | console.log(1); 42 | 43 | return function() { 44 | console.log(2); 45 | }; 46 | }); 47 | 48 | return React.createElement( 49 | "div", 50 | null, 51 | " ", 52 | flag ? React.createElement( 53 | "div", 54 | null, 55 | " 显示" 56 | ) : null, 57 | " " 58 | ); 59 | }; 60 | 61 | var LazyPage = function LazyPage() { 62 | var _React$useState = React.useState("zhangsan"); 63 | 64 | var _React$useState2 = _slicedToArray(_React$useState, 2); 65 | 66 | var name = _React$useState2[0]; 67 | var setName = _React$useState2[1]; 68 | 69 | var _React$useState3 = React.useState(true); 70 | 71 | var _React$useState32 = _slicedToArray(_React$useState3, 2); 72 | 73 | var flag = _React$useState32[0]; 74 | var setFlag = _React$useState32[1]; 75 | 76 | return React.createElement( 77 | "div", 78 | null, 79 | React.createElement( 80 | "button", { 81 | onClick: function() { 82 | setFlag(false); 83 | } 84 | }, 85 | "按钮" 86 | ), 87 | React.createElement( 88 | Show, { 89 | flag: flag 90 | }, 91 | " " 92 | ), 93 | React.createElement( 94 | "p", 95 | null, 96 | " My Name is: ", 97 | name, 98 | " " 99 | ), 100 | React.createElement("input", { 101 | type: "text", 102 | value: name, 103 | onChange: function(e) { 104 | return setName(e.target.value); 105 | } 106 | }) 107 | ); 108 | }; 109 | 110 | ReactDOM.render(React.createElement(LazyPage, null), document.getElementById("example")); -------------------------------------------------------------------------------- /es6.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | Hello React! 15 | 16 | 17 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 47 | 48 | 49 |
50 |

51 | 52 |
53 | 54 | 55 | 56 | 57 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /es6_code/es6_react_code/01/01.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2021-05-06 12:29:53 4 | * @LastEditTime: 2021-05-07 10:10:54 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /react/es6_code/es6_react_code/01/01.js 8 | */ 9 | 10 | ReactDOM.render( 11 |

Hello, world

, 12 | document.getElementById('example') 13 | ); -------------------------------------------------------------------------------- /es6_code/es6_react_code/01/02.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2021-04-10 18:51:19 4 | * @LastEditTime: 2021-04-10 18:51:58 5 | * @LastEditors: your name 6 | * @Description: In User Settings Edit 7 | * @FilePath: /react源码分析/es6_code/es6_react_code/01/02.js 8 | */ 9 | 10 | const H=()=>(

Hello, world

); 11 | ReactDOM.render( 12 | , 13 | document.getElementById('example') 14 | ); 15 | -------------------------------------------------------------------------------- /es6_code/es6_react_code/01/03.js: -------------------------------------------------------------------------------- 1 | 2 | const H=()=>( 3 |
4 |

这个是标题

5 |

这个是内容

6 |
7 | ); 8 | // ReactDOM.render( 9 | // , 10 | // document.getElementById('example') 11 | // ); -------------------------------------------------------------------------------- /es6_code/es6_react_code/01/04.js: -------------------------------------------------------------------------------- 1 | 2 | const style={ 3 | width:'100px', 4 | height:'200px', 5 | color:'red', 6 | } 7 | const H=()=>( 8 |
Hello, world 11 |
); 12 | ReactDOM.render( 13 | , 14 | document.getElementById('example') 15 | ); -------------------------------------------------------------------------------- /es6_code/es6_react_code/01/05mapChildren.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Date: 2022-05-30 21:22:17 3 | * @Author: Yao guan shou 4 | * @LastEditors: Yao guan shou 5 | * @LastEditTime: 2022-05-30 21:44:25 6 | * @FilePath: /react/es6_code/es6_react_code/01/05mapChildren.js 7 | * @Description: 8 | */ 9 | 10 | const { Children } = React 11 | 12 | console.log('React=',React) 13 | console.log('Children=',Children) 14 | debugger; 15 | const HighOrderComponent = (props) => { 16 | const { children } = props 17 | return ( 18 |
19 |
我是父组件
20 |
21 | {Children.map(children, (child) => { 22 | return
{child}
23 | })} 24 |
25 | Ï 26 |
27 | ) 28 | } 29 | const Child = () => { 30 | return
我是子组件
31 | } 32 | ReactDOM.render( 33 | 34 | 35 | 36 | 37 | 38 | 39 | , 40 | document.getElementById('example'), 41 | ) 42 | -------------------------------------------------------------------------------- /es6_code/es6_react_code/01/classConpoment.js: -------------------------------------------------------------------------------- 1 | const { useState } = React; 2 | 3 | const Label = (props) => { 4 | const { label } = props; 5 | return {label}; 6 | }; 7 | 8 | const Input = (props) => { 9 | const [value, setValue] = useState("初始值"); 10 | 11 | return ( 12 |
13 | { 16 | setValue(event.target.value); 17 | }} 18 | > 19 | value= {value} 20 |
21 | ); 22 | }; 23 | 24 | class Box extends React.Component { 25 | constructor(props) { 26 | super(props); 27 | this.state = { 28 | name: "box", 29 | }; 30 | } 31 | componentDidMount() {} 32 | 33 | componentDidUpdate() {} 34 | render() { 35 | return
这是一个盒子 {this.state.name}
; 36 | } 37 | } 38 | 39 | class StaticBox extends React.Component { 40 | constructor(props) { 41 | super(props); 42 | } 43 | componentDidMount() {} 44 | 45 | componentDidUpdate() {} 46 | render() { 47 | return
StaticBox
; 48 | } 49 | } 50 | 51 | class PropsBox extends React.Component { 52 | constructor(props) { 53 | super(props); 54 | } 55 | componentDidMount() {} 56 | 57 | componentDidUpdate() {} 58 | render() { 59 | return
PropsBox={this.props.name}
; 60 | } 61 | } 62 | 63 | class App extends React.Component { 64 | constructor(props) { 65 | super(props); 66 | this.state = { 67 | count: 0, 68 | value: "", 69 | }; 70 | } 71 | componentDidMount() {} 72 | 73 | componentDidUpdate() {} 74 | onChange(e) { 75 | this.setState({ 76 | value: e.target.value, 77 | }); 78 | } 79 | render() { 80 | return ( 81 |
82 |
83 |
84 | 94 | 95 | value={this.state.value} 96 |
97 |
98 | {/* 99 | 100 | 101 | 102 | 103 | 104 | */} 105 |
106 | ); 107 | } 108 | } 109 | 110 | ReactDOM.render(, document.getElementById("example")); 111 | -------------------------------------------------------------------------------- /es6_code/es6_react_code/02/01.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2021-05-06 12:29:53 4 | * @LastEditTime: 2021-05-07 10:12:41 5 | * @LastEditors: your name 6 | * @Description: In User Settings Edit 7 | * @FilePath: /react/es6_code/es6_react_code/02/01.js 8 | */ 9 | var number=0; 10 | const H=()=>( 11 |
{ 12 | console.log(++number) 13 | }}> 14 | 点击事件 15 |
16 | ); 17 | ReactDOM.render( 18 | , 19 | document.getElementById('example') 20 | ); -------------------------------------------------------------------------------- /es6_code/es6_react_code/03/01.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2021-05-06 12:29:53 4 | * @LastEditTime: 2021-05-07 10:12:24 5 | * @LastEditors: your name 6 | * @Description: In User Settings Edit 7 | * @FilePath: /react/es6_code/es6_react_code/03/03_01.js 8 | */ 9 | // 创建一个 theme Context, 默认 theme 的值为 light 10 | const ThemeContext = React.createContext(); 11 | 12 | function Button(props){ 13 | console.log('props===',props) 14 | return ( 15 | 16 | ) 17 | } 18 | 19 | function ThemedButton(props) { 20 | // ThemedButton 组件从 context 接收 theme 21 | return ( 22 | 23 | { 24 | theme =>{ 25 | console.log('theme=',theme) 26 | console.log('props==',props) 27 | return 54 | 55 |

My Name is: {name}

56 | setName(e.target.value)} 60 | /> 61 | 62 | ); 63 | }; 64 | 65 | ReactDOM.render(, document.getElementById("example")); 66 | -------------------------------------------------------------------------------- /es6_code/es6_react_code/05/01.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-11-09 14:51:25 4 | * @LastEditTime: 2021-05-12 11:02:35 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /react-hook/js/09_02-useContext.js 8 | */ 9 | // Context 解决了多层组件props传递数据等问题。 创建Context 10 | const TestContext = React.createContext({ 11 | color: "red", 12 | }); 13 | const Navbar = () => { 14 | // 获取Context 的值 15 | const { username, color } = React.useContext(TestContext); 16 | const Context = React.useContext(TestContext); 17 | console.log("TestContext=", TestContext); 18 | return ( 19 |
20 |

{username}

21 |

color={color}

22 |
23 | ); 24 | }; 25 | 26 | Navbar.contextType = TestContext; 27 | 28 | const Messages = () => { 29 | // 获取Context 的值 30 | // const { username, count } = React.useContext(TestContext); 31 | console.log("username="); 32 | 33 | return ( 34 |
35 | {/* 36 | 37 |

1 message for {username}

38 |

1 count for {count}

39 | */} 40 |
41 | ); 42 | }; 43 | 44 | class App extends React.Component { 45 | constructor(props) { 46 | super(props); 47 | this.state = { 48 | count: 0, 49 | }; 50 | } 51 | componentDidMount() { 52 | var flag = true; 53 | setTimeout(() => { 54 | flag = false; 55 | }, 3000); 56 | // for (let i = 0; i < 1000000000; i++) {} 57 | } 58 | 59 | componentDidUpdate() { 60 | // console.log("performance.getEntries()1:",performance.getEntries()); 61 | // for (let i = 0; i < 10000100000; i++) {} 62 | // setTimeout(()=>{ 63 | // console.log("performance.getEntries()2:",performance.getEntries()); 64 | // },500) 65 | 66 | // // debugger 67 | // this.setState({ 68 | // count: this.state.count + 1, 69 | // }); 70 | // return true 71 | } 72 | render() { 73 | return ( 74 |
75 | 85 | 92 |
93 | 94 | 95 |
96 |
97 |
98 | ); 99 | } 100 | } 101 | 102 | // function App() { 103 | // const data = {}; 104 | // const [count, setCount] = React.useState(0); 105 | 106 | // return ( 107 | //
108 | // 111 | // 118 | //
119 | // 120 | // 121 | //
122 | //
123 | //
124 | // ); 125 | // } 126 | 127 | const Root = () => { 128 | return ( 129 |
130 | 131 |
132 | ); 133 | }; 134 | 135 | ReactDOM.render(, document.getElementById("example")); 136 | -------------------------------------------------------------------------------- /es6_code/es6_react_code/06/01.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-11-09 14:51:25 4 | * @LastEditTime: 2021-05-12 20:12:27 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /react-hook/js/09_02-useContext.js 8 | */ 9 | // Context 解决了多层组件props传递数据等问题。 创建Context 10 | 11 | const C0 = (props) => { 12 | console.log('props=',props) 13 | const {count} =props 14 | return
0 count={count}
; 15 | }; 16 | const C1 = (props) => { 17 | return ( 18 |
19 | 1 20 | 21 |
22 | ); 23 | }; 24 | const C2 = (props) => { 25 | return ( 26 |
27 | 2 28 | 29 |
30 | ); 31 | }; 32 | const C3 = (props) => { 33 | return ( 34 |
35 | 3 36 | 37 |
38 | ); 39 | }; 40 | const C4 = (props) => { 41 | return ( 42 |
43 | 3 44 | 45 |
46 | ); 47 | }; 48 | const C5 = (props) => { 49 | return ( 50 |
51 | 4 52 | 53 |
54 | ); 55 | }; 56 | 57 | class App extends React.Component { 58 | constructor(props) { 59 | super(props); 60 | this.state = { 61 | count: 0, 62 | }; 63 | } 64 | componentDidMount() { 65 | var flag = true; 66 | setTimeout(() => { 67 | flag = false; 68 | }, 3000); 69 | // for (let i = 0; i < 1000000000; i++) {} 70 | } 71 | 72 | componentDidUpdate() { 73 | // console.log("performance.getEntries()1:",performance.getEntries()); 74 | // for (let i = 0; i < 10000100000; i++) {} 75 | // setTimeout(()=>{ 76 | // console.log("performance.getEntries()2:",performance.getEntries()); 77 | // },500) 78 | // // debugger 79 | // this.setState({ 80 | // count: this.state.count + 1, 81 | // }); 82 | // return true 83 | } 84 | render() { 85 | return ( 86 |
87 | 97 | 98 |
99 | ); 100 | } 101 | } 102 | 103 | // function App() { 104 | // const data = {}; 105 | // const [count, setCount] = React.useState(0); 106 | 107 | // return ( 108 | //
109 | // 112 | // 119 | //
120 | // 121 | // 122 | //
123 | //
124 | //
125 | // ); 126 | // } 127 | 128 | const Root = () => { 129 | return ( 130 |
131 | 132 |
133 | ); 134 | }; 135 | 136 | ReactDOM.render(, document.getElementById("example")); 137 | -------------------------------------------------------------------------------- /es6_code/es6_react_code/demo/FiberNodeTree结构.js: -------------------------------------------------------------------------------- 1 | const { useState } = React; 2 | 3 | const Label = (props) => { 4 | const { label } = props; 5 | return {label}; 6 | }; 7 | 8 | const Input = (props) => { 9 | const [value, setValue] = useState("初始值"); 10 | 11 | return ( 12 |
13 | { 16 | setValue(event.target.value); 17 | }} 18 | > 19 | value= {value} 20 |
21 | ); 22 | }; 23 | 24 | class Box extends React.Component { 25 | constructor(props) { 26 | super(props); 27 | this.state = { 28 | name: "box", 29 | }; 30 | } 31 | componentDidMount() {} 32 | 33 | componentDidUpdate() {} 34 | render() { 35 | return
这是一个盒子 {this.state.name}
; 36 | } 37 | } 38 | 39 | class StaticBox extends React.Component { 40 | constructor(props) { 41 | super(props); 42 | } 43 | componentDidMount() {} 44 | 45 | componentDidUpdate() {} 46 | render() { 47 | return
StaticBox
; 48 | } 49 | } 50 | 51 | class PropsBox extends React.Component { 52 | constructor(props) { 53 | super(props); 54 | } 55 | componentDidMount() {} 56 | 57 | componentDidUpdate() {} 58 | render() { 59 | return
PropsBox={this.props.name}
; 60 | } 61 | } 62 | 63 | class App extends React.Component { 64 | constructor(props) { 65 | super(props); 66 | this.state = { 67 | count: 0, 68 | value: "", 69 | }; 70 | } 71 | componentDidMount() {} 72 | 73 | componentDidUpdate() {} 74 | onChange(e) { 75 | this.setState({ 76 | value: e.target.value, 77 | }); 78 | } 79 | render() { 80 | return ( 81 |
82 |
83 |
84 | 94 | 95 | value={this.state.value} 96 |
97 |
98 | 99 | 100 | 101 | 102 | 103 |
104 | ); 105 | } 106 | } 107 | 108 | ReactDOM.render(, document.getElementById("example")); 109 | -------------------------------------------------------------------------------- /es6_code/es6_react_code/demo/classConpoment.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2021-05-14 16:30:43 4 | * @LastEditTime: 2021-05-14 16:31:45 5 | * @LastEditors: your name 6 | * @Description: In User Settings Edit 7 | * @FilePath: /react/es6_code/es6_react_code/demo/classConpoment.js 8 | */ 9 | class App extends React.Component { 10 | constructor(props) { 11 | super(props); 12 | this.state = { 13 | count: 0, 14 | value: "", 15 | }; 16 | } 17 | componentDidMount() {} 18 | 19 | componentDidUpdate() {} 20 | onChange(e) { 21 | this.setState({ 22 | value: e.target.value, 23 | }); 24 | } 25 | render() { 26 | return ( 27 |
28 | 38 |
39 | ); 40 | } 41 | } 42 | 43 | ReactDOM.render(, document.getElementById("example")); 44 | -------------------------------------------------------------------------------- /es6_code/es6_react_code/demo/functionConpoment.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2021-05-14 16:30:43 4 | * @LastEditTime: 2021-05-17 12:27:46 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /react/es6_code/es6_react_code/demo/classConpoment.js 8 | */ 9 | const { useState } = React; 10 | const Box =(props)=>{ 11 | return (
这是一个{props.name}盒子
) 12 | } 13 | const App = () => { 14 | const [count, setCount] = useState(0); 15 | return ( 16 |
17 | 24 | 25 |
26 | ); 27 | }; 28 | 29 | ReactDOM.render(, document.getElementById("example")); 30 | -------------------------------------------------------------------------------- /es6_code/es6_react_code/demo/tag各种组件测试.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2021-05-14 11:23:59 4 | * @LastEditTime: 2021-05-14 12:06:21 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /react/es6_code/es6_react_code/demo/tag各种组件测试.js 8 | */ 9 | const { 10 | Component, 11 | useRef, 12 | useEffect, 13 | useLayoutEffect, 14 | useState, 15 | useMemo, 16 | useCallback, 17 | useImperativeHandle, 18 | forwardRef, 19 | memo, 20 | } = React; 21 | 22 | class ClassComponent extends Component { 23 | render() { 24 | return
ClassComponent组件
; 25 | } 26 | } 27 | 28 | // memo 29 | const MemoComponent = memo((props) => ( 30 |
MemoComponent组件
31 | )); 32 | 33 | const UseMemoComponent = () => { 34 | const [count, setCount] = useState(1); 35 | 36 | const expensive = useMemo(() => { 37 | return count; 38 | }, [count]); 39 | // 返回函数 40 | 41 | return
expensive={expensive}
; 42 | }; 43 | 44 | //forwardRef 45 | const ForwardRefComponent = forwardRef((props, ref) => ( 46 |
ForwardRefComponent组件
47 | )); 48 | 49 | //HocComponent 50 | class HocComponent extends React.Component { 51 | constructor(props) { 52 | super(props); 53 | this.state = { 54 | // 获取初始化值 55 | value: props.initialValue, 56 | }; 57 | } 58 | onChange(e) { 59 | // 事件改变值回调 60 | this.setState({ value: e.target.value }); 61 | if (this.props.onChange) { 62 | this.props.onChange(e.target.value); 63 | } 64 | } 65 | render() { 66 | return ( 67 |
68 | {/* 这样children 可以传递参数啦 */} 69 | {this.props.children({ 70 | value: this.state.value, 71 | onChange: this.onChange.bind(this), 72 | })} 73 |
74 | ); 75 | } 76 | } 77 | 78 | const App = (props) => { 79 | return ( 80 |
81 | 82 | 83 | 84 | 85 | 86 | { 91 | console.log("HocBind", val); 92 | }} 93 | > 94 | { 95 | // 这是一个函数接受props 96 | (parentProps) => ( 97 |
98 |

Render Props HocBind实现 value:{parentProps.value}

99 | 100 |
101 | ) 102 | } 103 |
104 |
105 | ); 106 | }; 107 | 108 | ReactDOM.render(, document.getElementById("example")); 109 | -------------------------------------------------------------------------------- /fre.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 13 |
14 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /fre.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Object.defineProperty(exports, '__esModule', { value: true }); 4 | 5 | const updateElement = (dom, oldProps, newProps) => { 6 | for (let name in Object.assign(Object.assign({}, oldProps), newProps)) { 7 | let oldValue = oldProps[name]; 8 | let newValue = newProps[name]; 9 | if (oldValue == newValue || name === 'children'); 10 | else if (name === 'style') { 11 | for (const k in Object.assign(Object.assign({}, oldValue), newValue)) { 12 | if (!(oldValue && newValue && oldValue[k] === newValue[k])) { 13 | dom[name][k] = (newValue && newValue[k]) || ''; 14 | } 15 | } 16 | } 17 | else if (name[0] === 'o' && name[1] === 'n') { 18 | name = name.slice(2).toLowerCase(); 19 | if (oldValue) 20 | dom.removeEventListener(name, oldValue); 21 | dom.addEventListener(name, newValue); 22 | } 23 | else if (name in dom && !(dom instanceof SVGElement)) { 24 | dom[name] = newValue == null ? '' : newValue; 25 | } 26 | else if (newValue == null || newValue === false) { 27 | dom.removeAttribute(name); 28 | } 29 | else { 30 | dom.setAttribute(name, newValue); 31 | } 32 | } 33 | }; 34 | const createElement = (fiber) => { 35 | const dom = fiber.type === 'text' 36 | ? document.createTextNode('') 37 | : fiber.tag === 4 38 | ? document.createElementNS('http://www.w3.org/2000/svg', fiber.type) 39 | : document.createElement(fiber.type); 40 | updateElement(dom, {}, fiber.props); 41 | return dom; 42 | }; 43 | 44 | let cursor = 0; 45 | const resetCursor = () => { 46 | cursor = 0; 47 | }; 48 | const useState = (initState) => { 49 | return useReducer(null, initState); 50 | }; 51 | const useReducer = (reducer, initState) => { 52 | const [hook, current] = getHook(cursor++); 53 | const setter = (value) => { 54 | let newValue = reducer 55 | ? reducer(hook[0], value) 56 | : isFn(value) 57 | ? value(hook[0]) 58 | : value; 59 | if (newValue !== hook[0]) { 60 | hook[0] = newValue; 61 | scheduleWork(current); 62 | } 63 | }; 64 | if (hook.length) { 65 | return [hook[0], setter]; 66 | } 67 | else { 68 | hook[0] = initState; 69 | return [initState, setter]; 70 | } 71 | }; 72 | const useEffect = (cb, deps) => { 73 | return effectImpl(cb, deps, 'effect'); 74 | }; 75 | const useLayout = (cb, deps) => { 76 | return effectImpl(cb, deps, 'layout'); 77 | }; 78 | const effectImpl = (cb, deps, key) => { 79 | let [hook, current] = getHook(cursor++); 80 | if (isChanged(hook[1], deps)) { 81 | hook[0] = useCallback(cb, deps); 82 | hook[1] = deps; 83 | current.hooks[key].push(hook); 84 | } 85 | }; 86 | const useMemo = (cb, deps) => { 87 | let hook = getHook(cursor++)[0]; 88 | if (isChanged(hook[1], deps)) { 89 | hook[1] = deps; 90 | return (hook[0] = cb()); 91 | } 92 | return hook[0]; 93 | }; 94 | const useCallback = (cb, deps) => { 95 | return useMemo(() => cb, deps); 96 | }; 97 | const useRef = (current) => { 98 | return useMemo(() => ({ current }), []); 99 | }; 100 | const getHook = (cursor) => { 101 | const current = getCurrentFiber(); 102 | let hooks = current.hooks || (current.hooks = { list: [], effect: [], layout: [] }); 103 | if (cursor >= hooks.list.length) { 104 | hooks.list.push([]); 105 | } 106 | return [hooks.list[cursor], current]; 107 | }; 108 | const isChanged = (a, b) => { 109 | return !a || b.some((arg, index) => arg !== a[index]); 110 | }; 111 | 112 | let taskQueue = []; 113 | let currentCallback; 114 | let frameDeadline = 0; 115 | const frameLength = 5; 116 | const scheduleCallback = (callback) => { 117 | const currentTime = getTime(); 118 | const timeout = 3000; 119 | const dueTime = currentTime + timeout; 120 | let newTask = { 121 | callback, 122 | dueTime 123 | }; 124 | taskQueue.push(newTask); 125 | currentCallback = flush; 126 | planWork(null); 127 | }; 128 | const flush = (iniTime) => { 129 | let currentTime = iniTime; 130 | let currentTask = peek(taskQueue); 131 | while (currentTask) { 132 | const timeout = currentTask.dueTime <= currentTime; 133 | if (!timeout && shouldYeild()) 134 | break; 135 | let callback = currentTask.callback; 136 | currentTask.callback = null; 137 | let next = isFn(callback) && callback(timeout); 138 | next ? (currentTask.callback = next) : taskQueue.shift(); 139 | currentTask = peek(taskQueue); 140 | currentTime = getTime(); 141 | } 142 | return !!currentTask; 143 | }; 144 | const peek = (queue) => { 145 | queue.sort((a, b) => a.dueTime - b.dueTime); 146 | return queue[0]; 147 | }; 148 | const flushWork = () => { 149 | if (isFn(currentCallback)) { 150 | let currentTime = getTime(); 151 | frameDeadline = currentTime + frameLength; 152 | let more = currentCallback(currentTime); 153 | more ? planWork(null) : (currentCallback = null); 154 | } 155 | }; 156 | const planWork = (() => { 157 | if (typeof MessageChannel !== 'undefined') { 158 | const { port1, port2 } = new MessageChannel(); 159 | port1.onmessage = flushWork; 160 | return (cb) => cb ? requestAnimationFrame(cb) : port2.postMessage(null); 161 | } 162 | return (cb) => setTimeout(cb || flushWork); 163 | })(); 164 | const shouldYeild = () => { 165 | return getTime() >= frameDeadline; 166 | }; 167 | const getTime = () => performance.now(); 168 | 169 | const options = { 170 | catchError (_, e) { 171 | throw e; 172 | } 173 | }; 174 | let preCommit; 175 | let currentFiber; 176 | let WIP; 177 | let updateQueue = []; 178 | let commitQueue = []; 179 | const render = (vnode, node, done) => { 180 | let rootFiber = { 181 | node, 182 | props: { children: vnode }, 183 | done 184 | }; 185 | scheduleWork(rootFiber); 186 | }; 187 | const scheduleWork = (fiber) => { 188 | if (!fiber.dirty) { 189 | fiber.dirty = true; 190 | updateQueue.push(fiber); 191 | } 192 | scheduleCallback(reconcileWork); 193 | }; 194 | const reconcileWork = (timeout) => { 195 | if (!WIP) 196 | WIP = updateQueue.shift(); 197 | while (WIP && (!shouldYeild() || timeout)) { 198 | WIP = reconcile(WIP); 199 | } 200 | if (WIP && !timeout) { 201 | return reconcileWork.bind(null); 202 | } 203 | if (preCommit) 204 | commitWork(preCommit); 205 | return null; 206 | }; 207 | const reconcile = (WIP) => { 208 | WIP.parentNode = getParentNode(WIP); 209 | if (isFn(WIP.type)) { 210 | try { 211 | updateHook(WIP); 212 | } 213 | catch (e) { 214 | options.catchError(WIP, e); 215 | } 216 | } 217 | else { 218 | updateHost(WIP); 219 | } 220 | WIP.dirty = WIP.dirty ? false : 0; 221 | commitQueue.push(WIP); 222 | if (WIP.child) 223 | return WIP.child; 224 | while (WIP) { 225 | if (!preCommit && WIP.dirty === false) { 226 | preCommit = WIP; 227 | return null; 228 | } 229 | if (WIP.sibling) { 230 | return WIP.sibling; 231 | } 232 | WIP = WIP.parent; 233 | } 234 | }; 235 | const updateHook = (WIP) => { 236 | currentFiber = WIP; 237 | resetCursor(); 238 | let children = WIP.type(WIP.props); 239 | if (isStr(children)) 240 | children = createText(children); 241 | reconcileChildren(WIP, children); 242 | }; 243 | const updateHost = (WIP) => { 244 | if (!WIP.node) { 245 | if (WIP.type === 'svg') { 246 | WIP.tag = 4; 247 | } 248 | WIP.node = createElement(WIP); 249 | } 250 | let p = WIP.parentNode || {}; 251 | WIP.insertPoint = p.last || null; 252 | p.last = WIP; 253 | WIP.node.last = null; 254 | reconcileChildren(WIP, WIP.props.children); 255 | }; 256 | const getParentNode = (WIP) => { 257 | while ((WIP = WIP.parent)) { 258 | if (!isFn(WIP.type)) 259 | return WIP.node; 260 | } 261 | }; 262 | const reconcileChildren = (WIP, children) => { 263 | delete WIP.child; 264 | const oldFibers = WIP.kids; 265 | const newFibers = (WIP.kids = hashfy(children)); 266 | let reused = {}; 267 | for (const k in oldFibers) { 268 | let newFiber = newFibers[k]; 269 | let oldFiber = oldFibers[k]; 270 | if (newFiber && newFiber.type === oldFiber.type) { 271 | reused[k] = oldFiber; 272 | } 273 | else { 274 | oldFiber.op = 3; 275 | commitQueue.push(oldFiber); 276 | } 277 | } 278 | let prevFiber; 279 | for (const k in newFibers) { 280 | let newFiber = newFibers[k]; 281 | let oldFiber = reused[k]; 282 | if (oldFiber) { 283 | oldFiber.op = 2; 284 | newFiber = Object.assign(Object.assign({}, oldFiber), newFiber); 285 | newFiber.lastProps = oldFiber.props; 286 | if (shouldPlace(newFiber)) 287 | newFiber.op = 1; 288 | } 289 | else { 290 | newFiber.op = 1; 291 | } 292 | newFibers[k] = newFiber; 293 | newFiber.parent = WIP; 294 | if (prevFiber) { 295 | prevFiber.sibling = newFiber; 296 | } 297 | else { 298 | if (WIP.tag === 4) { 299 | newFiber.tag = 4; 300 | } 301 | WIP.child = newFiber; 302 | } 303 | prevFiber = newFiber; 304 | } 305 | if (prevFiber) 306 | prevFiber.sibling = null; 307 | }; 308 | const shouldPlace = (fiber) => { 309 | let p = fiber.parent; 310 | if (isFn(p.type)) 311 | return p.key && !p.dirty; 312 | return fiber.key; 313 | }; 314 | const commitWork = (fiber) => { 315 | commitQueue.forEach(c => c.parent && commit(c)); 316 | fiber.done && fiber.done(); 317 | commitQueue.length = 0; 318 | preCommit = null; 319 | WIP = null; 320 | }; 321 | const commit = (fiber) => { 322 | const { op, parentNode, node, ref, hooks } = fiber; 323 | if (op === 3) { 324 | hooks && hooks.list.forEach(cleanup); 325 | cleanupRef(fiber.kids); 326 | while (isFn(fiber.type)) 327 | fiber = fiber.child; 328 | parentNode.removeChild(fiber.node); 329 | } 330 | else if (isFn(fiber.type)) { 331 | if (hooks) { 332 | side(hooks.layout); 333 | planWork(() => side(hooks.effect)); 334 | } 335 | } 336 | else if (op === 2) { 337 | updateElement(node, fiber.lastProps, fiber.props); 338 | } 339 | else { 340 | let point = fiber.insertPoint ? fiber.insertPoint.node : null; 341 | let after = point ? point.nextSibling : parentNode.firstChild; 342 | if (after === node) 343 | return; 344 | if (after === null && node === parentNode.lastChild) 345 | return; 346 | parentNode.insertBefore(node, after); 347 | } 348 | refer(ref, node); 349 | }; 350 | const hashfy = (c) => { 351 | const out = {}; 352 | isArr(c) 353 | ? c.forEach((v, i) => isArr(v) 354 | ? v.forEach((vi, j) => (out[hs(i, j, vi.key)] = vi)) 355 | : some(v) && (out[hs(i, null, v.key)] = v)) 356 | : some(c) && (out[hs(0, null, c.key)] = c); 357 | return out; 358 | }; 359 | const refer = (ref, dom) => { 360 | if (ref) 361 | isFn(ref) ? ref(dom) : (ref.current = dom); 362 | }; 363 | const cleanupRef = (kids) => { 364 | for (const k in kids) { 365 | const kid = kids[k]; 366 | refer(kid.ref, null); 367 | if (kid.kids) 368 | cleanupRef(kid.kids); 369 | } 370 | }; 371 | const side = (effects) => { 372 | effects.forEach(cleanup); 373 | effects.forEach(effect); 374 | effects.length = 0; 375 | }; 376 | const getCurrentFiber = () => currentFiber || null; 377 | const effect = (e) => e[2] = e[0](currentFiber); 378 | const cleanup = (e) => e[2] && e[2](currentFiber); 379 | const isFn = (x) => typeof x === 'function'; 380 | const isStr = (s) => typeof s === 'number' || typeof s === 'string'; 381 | const some = (v) => v != null && v !== false && v !== true; 382 | const hs = (i, j, k) => k != null && j != null 383 | ? '.' + i + '.' + k 384 | : j != null 385 | ? '.' + i + '.' + j 386 | : k != null 387 | ? '.' + k 388 | : '.' + i; 389 | 390 | const h = function (type, attrs) { 391 | let props = attrs || {}; 392 | let key = props.key || null; 393 | let ref = props.ref || null; 394 | let children = []; 395 | let simpleNode = ''; 396 | const childrenArgLen = arguments.length; 397 | for (let i = 2; i < childrenArgLen; i++) { 398 | let child = arguments[i]; 399 | const isEnd = i === childrenArgLen - 1; 400 | while (isArr(child) && child.some(v => isArr(v))) { 401 | child = [].concat(...child); 402 | } 403 | let vnode = some(child) ? child : ''; 404 | const isStrNode = isStr(vnode); 405 | if (isStrNode) { 406 | simpleNode += String(vnode); 407 | } 408 | if (simpleNode && (!isStrNode || isEnd)) { 409 | children.push(createText(simpleNode)); 410 | simpleNode = ''; 411 | } 412 | if (!isStrNode) { 413 | children.push(vnode); 414 | } 415 | } 416 | if (children.length) { 417 | props.children = children.length === 1 ? children[0] : children; 418 | } 419 | delete props.key; 420 | delete props.ref; 421 | return { type, props, key, ref }; 422 | }; 423 | function createText (vnode) { 424 | return { type: 'text', props: { nodeValue: vnode } }; 425 | } 426 | const Fragment = (props) => { 427 | return props.children; 428 | }; 429 | const isArr = Array.isArray; 430 | 431 | const Fre = { 432 | h, 433 | createElement: h, 434 | render, 435 | scheduleWork, 436 | useState, 437 | useReducer, 438 | useEffect, 439 | useMemo, 440 | useCallback, 441 | useRef, 442 | Fragment, 443 | getCurrentFiber, 444 | options 445 | }; 446 | 447 | // exports.Fragment = Fragment; 448 | // exports.createElement = h; 449 | // exports.default = Fre; 450 | // exports.getCurrentFiber = getCurrentFiber; 451 | // exports.h = h; 452 | // exports.options = options; 453 | // exports.render = render; 454 | // exports.scheduleWork = scheduleWork; 455 | // exports.useCallback = useCallback; 456 | // exports.useEffect = useEffect; 457 | // exports.useLayout = useLayout; 458 | // exports.useLayoutEffect = useLayout; 459 | // exports.useMemo = useMemo; 460 | // exports.useReducer = useReducer; 461 | // exports.useRef = useRef; 462 | // exports.useState = useState; 463 | 464 | window['React'] = { 465 | Fragment: Fragment, 466 | createElement: h, 467 | default: Fre, 468 | getCurrentFiber: getCurrentFiber, 469 | h: h, 470 | options: options, 471 | render: render, 472 | scheduleWork: scheduleWork, 473 | useCallback: useCallback, 474 | useEffect: useEffect, 475 | useLayout: useLayout, 476 | useLayoutEffect: useLayout, 477 | useMemo: useMemo, 478 | useReducer: useReducer, 479 | useRef: useRef, 480 | useState: useState, 481 | } 482 | //# sourceMappingURL=fre.js.map 483 | -------------------------------------------------------------------------------- /graphql.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | GraphiQL Workspace Example 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /index2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello React! 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 51 | 52 | 53 |
54 |
55 |

代码编辑窗口

56 | 57 | 60 |
61 | 62 |
63 |
64 |
65 |
66 |

标准组件demo代码

67 | 99 |

模板组件 demo 代码

100 | 111 |
112 |
113 |
114 | 305 | 306 | -------------------------------------------------------------------------------- /ng测试题.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello React! 7 | 8 | 9 | 10 | 11 | 12 | 13 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /nodeServer.js: -------------------------------------------------------------------------------- 1 | const http = require('http') 2 | const fs = require('fs'); 3 | const path = require('path'); 4 | const beautify = require('js-beautify').js 5 | // querystring 模块提供用于解析和格式化 URL 查询字符串的实用工具 6 | const querystring = require('querystring') 7 | 8 | const promise = (fn) => new Promise(fn) 9 | const mkdirCreateFile = async (codePath, content, lastPath) => { 10 | const reg = /\\/g; 11 | codePath = codePath.replace(reg, '/') 12 | // 截取目录 13 | const pathArr = codePath.split('/'); 14 | let mkdirPath = '' 15 | lastPath = lastPath || ''; 16 | if (pathArr.length > 1) { 17 | if (!lastPath) { 18 | mkdirPath = pathArr.shift(); 19 | lastPath = mkdirPath; 20 | } else { 21 | mkdirPath = pathArr.shift(); 22 | lastPath = `${lastPath}/${mkdirPath}`; 23 | mkdirPath = lastPath; 24 | } 25 | await promise((resolve, reject) => { 26 | // 创建目录 27 | fs.mkdir(path.join(__dirname, mkdirPath), async function (err) { 28 | // 递归创建目录 29 | resolve(); 30 | }) 31 | }).then(async () => { 32 | await mkdirCreateFile(pathArr.join('/'), content, lastPath) 33 | }) 34 | 35 | } else { 36 | mkdirPath = pathArr.shift(); 37 | mkdirPath = `${lastPath}/${mkdirPath}`; 38 | await promise((resolve, reject) => { 39 | // 写入文件 40 | fs.writeFile(path.join(__dirname, mkdirPath), content, async function (err) { 41 | if (err) { 42 | // console.log('写入失败', err); 43 | reject(err) 44 | } else { 45 | resolve() 46 | // console.log('写入成功'); 47 | } 48 | }) 49 | }) 50 | 51 | } 52 | 53 | } 54 | 55 | 56 | // 路由配置 57 | const routes = { 58 | createCode: { 59 | url: '/createCode', 60 | callback: function (request, response) { 61 | // 接收数据 62 | let postData = '' 63 | // chunk为一点点数据,逐渐积累 64 | request.on('data', chunk => { 65 | // console.log('chunk=', chunk) 66 | postData += chunk 67 | }) 68 | 69 | request.on('end', () => { 70 | let { 71 | path: codePath, 72 | code 73 | } = querystring.parse(postData.toString()) 74 | code=beautify(code, { indent_size: 4, space_in_empty_paren: true }) 75 | console.log('codePath=', codePath) 76 | console.log('code=', code) 77 | mkdirCreateFile(codePath, code).then(() => { 78 | console.log('文件写入成功'); 79 | // 在这里返回 因为是异步 80 | response.end( 81 | // 返回json字字符串 82 | JSON.stringify({ 83 | message:'文件写入成功', 84 | path: codePath, 85 | code 86 | }) 87 | ) 88 | }).catch((err) => { 89 | console.log('文件写入失败', err); 90 | response.end( 91 | // 返回json字字符串 92 | JSON.stringify({ 93 | message: '文件写入失败' 94 | }) 95 | ) 96 | }) 97 | 98 | }) 99 | }, 100 | type: 'post', 101 | }, 102 | getCode: { 103 | url: '/getCode', 104 | callback: function (request, response) { 105 | // url路径 106 | const url = request.url 107 | const path = url.split('?')[0] 108 | // 解析 get请求的参数 为?后面 所以数组下标为1 109 | const getParams = querystring.parse(url.split('?')[1]) 110 | response.end( 111 | // 返回json字字符串 112 | JSON.stringify({ 113 | ...getParams 114 | }) 115 | ) 116 | }, 117 | type: 'get', 118 | } 119 | 120 | } 121 | 122 | const server = http.createServer((req, res) => { 123 | // 请求的方式 124 | const method = req.method 125 | // 获取完整请求url 126 | const url = req.url 127 | //设置跨域 128 | res.setHeader("Access-Control-Allow-Origin", "*"); 129 | res.setHeader("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With"); 130 | res.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); 131 | // res.setHeader("X-Powered-By", ' 3.2.1') 132 | 133 | for (let key in routes) { 134 | if (url.indexOf(routes[key].url) != '-1') { 135 | // 设置返回的格式 json格式 136 | res.setHeader('Content-type', 'application/json') 137 | if (method === 'POST' && routes[key].type == 'post') { // 0.如果是Post请求 138 | routes[key].callback(req, res) 139 | } else if (method === 'GET' && routes[key].type == 'get') { // get请求 140 | console.log('method', method) 141 | routes[key].callback(req, res) 142 | } 143 | return false; 144 | } 145 | } 146 | 147 | res.statusCode = 200 148 | res.setHeader('Content-Type', 'text/plain') 149 | res.end('Hello World\n') 150 | 151 | }) 152 | 153 | 154 | server.listen(5000, () => { 155 | console.log('http://localhost:5000/') 156 | }) -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react_demo", 3 | "version": "1.1.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "abbrev": { 8 | "version": "1.1.1", 9 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 10 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", 11 | "dev": true 12 | }, 13 | "balanced-match": { 14 | "version": "1.0.0", 15 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 16 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 17 | "dev": true 18 | }, 19 | "brace-expansion": { 20 | "version": "1.1.11", 21 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 22 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 23 | "dev": true, 24 | "requires": { 25 | "balanced-match": "^1.0.0", 26 | "concat-map": "0.0.1" 27 | } 28 | }, 29 | "commander": { 30 | "version": "2.20.3", 31 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 32 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 33 | "dev": true 34 | }, 35 | "concat-map": { 36 | "version": "0.0.1", 37 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 38 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 39 | "dev": true 40 | }, 41 | "config-chain": { 42 | "version": "1.1.12", 43 | "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", 44 | "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", 45 | "dev": true, 46 | "requires": { 47 | "ini": "^1.3.4", 48 | "proto-list": "~1.2.1" 49 | } 50 | }, 51 | "editorconfig": { 52 | "version": "0.15.3", 53 | "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", 54 | "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", 55 | "dev": true, 56 | "requires": { 57 | "commander": "^2.19.0", 58 | "lru-cache": "^4.1.5", 59 | "semver": "^5.6.0", 60 | "sigmund": "^1.0.1" 61 | } 62 | }, 63 | "fs.realpath": { 64 | "version": "1.0.0", 65 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 66 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 67 | "dev": true 68 | }, 69 | "glob": { 70 | "version": "7.1.6", 71 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 72 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 73 | "dev": true, 74 | "requires": { 75 | "fs.realpath": "^1.0.0", 76 | "inflight": "^1.0.4", 77 | "inherits": "2", 78 | "minimatch": "^3.0.4", 79 | "once": "^1.3.0", 80 | "path-is-absolute": "^1.0.0" 81 | } 82 | }, 83 | "inflight": { 84 | "version": "1.0.6", 85 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 86 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 87 | "dev": true, 88 | "requires": { 89 | "once": "^1.3.0", 90 | "wrappy": "1" 91 | } 92 | }, 93 | "inherits": { 94 | "version": "2.0.4", 95 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 96 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 97 | "dev": true 98 | }, 99 | "ini": { 100 | "version": "1.3.5", 101 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", 102 | "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", 103 | "dev": true 104 | }, 105 | "js-beautify": { 106 | "version": "1.10.3", 107 | "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.10.3.tgz", 108 | "integrity": "sha512-wfk/IAWobz1TfApSdivH5PJ0miIHgDoYb1ugSqHcODPmaYu46rYe5FVuIEkhjg8IQiv6rDNPyhsqbsohI/C2vQ==", 109 | "dev": true, 110 | "requires": { 111 | "config-chain": "^1.1.12", 112 | "editorconfig": "^0.15.3", 113 | "glob": "^7.1.3", 114 | "mkdirp": "~0.5.1", 115 | "nopt": "~4.0.1" 116 | } 117 | }, 118 | "js-tokens": { 119 | "version": "4.0.0", 120 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 121 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 122 | "dev": true 123 | }, 124 | "loose-envify": { 125 | "version": "1.4.0", 126 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", 127 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", 128 | "dev": true, 129 | "requires": { 130 | "js-tokens": "^3.0.0 || ^4.0.0" 131 | } 132 | }, 133 | "lru-cache": { 134 | "version": "4.1.5", 135 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", 136 | "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", 137 | "dev": true, 138 | "requires": { 139 | "pseudomap": "^1.0.2", 140 | "yallist": "^2.1.2" 141 | } 142 | }, 143 | "minimatch": { 144 | "version": "3.0.4", 145 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 146 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 147 | "dev": true, 148 | "requires": { 149 | "brace-expansion": "^1.1.7" 150 | } 151 | }, 152 | "minimist": { 153 | "version": "0.0.8", 154 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 155 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 156 | "dev": true 157 | }, 158 | "mkdirp": { 159 | "version": "0.5.1", 160 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 161 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 162 | "dev": true, 163 | "requires": { 164 | "minimist": "0.0.8" 165 | } 166 | }, 167 | "nopt": { 168 | "version": "4.0.1", 169 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", 170 | "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", 171 | "dev": true, 172 | "requires": { 173 | "abbrev": "1", 174 | "osenv": "^0.1.4" 175 | } 176 | }, 177 | "object-assign": { 178 | "version": "4.1.1", 179 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 180 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 181 | "dev": true 182 | }, 183 | "once": { 184 | "version": "1.4.0", 185 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 186 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 187 | "dev": true, 188 | "requires": { 189 | "wrappy": "1" 190 | } 191 | }, 192 | "os-homedir": { 193 | "version": "1.0.2", 194 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", 195 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", 196 | "dev": true 197 | }, 198 | "os-tmpdir": { 199 | "version": "1.0.2", 200 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 201 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 202 | "dev": true 203 | }, 204 | "osenv": { 205 | "version": "0.1.5", 206 | "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", 207 | "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", 208 | "dev": true, 209 | "requires": { 210 | "os-homedir": "^1.0.0", 211 | "os-tmpdir": "^1.0.0" 212 | } 213 | }, 214 | "path-is-absolute": { 215 | "version": "1.0.1", 216 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 217 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 218 | "dev": true 219 | }, 220 | "prop-types": { 221 | "version": "15.7.2", 222 | "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", 223 | "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", 224 | "dev": true, 225 | "requires": { 226 | "loose-envify": "^1.4.0", 227 | "object-assign": "^4.1.1", 228 | "react-is": "^16.8.1" 229 | } 230 | }, 231 | "proto-list": { 232 | "version": "1.2.4", 233 | "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", 234 | "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", 235 | "dev": true 236 | }, 237 | "pseudomap": { 238 | "version": "1.0.2", 239 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 240 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", 241 | "dev": true 242 | }, 243 | "react": { 244 | "version": "16.12.0", 245 | "resolved": "https://registry.npmjs.org/react/-/react-16.12.0.tgz", 246 | "integrity": "sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==", 247 | "dev": true, 248 | "requires": { 249 | "loose-envify": "^1.1.0", 250 | "object-assign": "^4.1.1", 251 | "prop-types": "^15.6.2" 252 | } 253 | }, 254 | "react-dom": { 255 | "version": "16.12.0", 256 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.12.0.tgz", 257 | "integrity": "sha512-LMxFfAGrcS3kETtQaCkTKjMiifahaMySFDn71fZUNpPHZQEzmk/GiAeIT8JSOrHB23fnuCOMruL2a8NYlw+8Gw==", 258 | "dev": true, 259 | "requires": { 260 | "loose-envify": "^1.1.0", 261 | "object-assign": "^4.1.1", 262 | "prop-types": "^15.6.2", 263 | "scheduler": "^0.18.0" 264 | } 265 | }, 266 | "react-is": { 267 | "version": "16.12.0", 268 | "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", 269 | "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", 270 | "dev": true 271 | }, 272 | "scheduler": { 273 | "version": "0.18.0", 274 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.18.0.tgz", 275 | "integrity": "sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==", 276 | "dev": true, 277 | "requires": { 278 | "loose-envify": "^1.1.0", 279 | "object-assign": "^4.1.1" 280 | } 281 | }, 282 | "semver": { 283 | "version": "5.7.1", 284 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 285 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 286 | "dev": true 287 | }, 288 | "sigmund": { 289 | "version": "1.0.1", 290 | "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", 291 | "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", 292 | "dev": true 293 | }, 294 | "wrappy": { 295 | "version": "1.0.2", 296 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 297 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 298 | "dev": true 299 | }, 300 | "yallist": { 301 | "version": "2.1.2", 302 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 303 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", 304 | "dev": true 305 | } 306 | } 307 | } 308 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react_demo", 3 | "version": "1.1.1", 4 | "description": "react 逐行源码分析", 5 | "main": "react-dom.15.5.4.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/qq281113270/react.git" 12 | }, 13 | "author": "", 14 | "license": "ISC", 15 | "bugs": { 16 | "url": "https://github.com/qq281113270/react/issues" 17 | }, 18 | "homepage": "https://github.com/qq281113270/react#readme", 19 | "devDependencies": { 20 | "js-beautify": "^1.10.3", 21 | "react": "^16.12.0", 22 | "react-dom": "^16.12.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /react逐行源码分析文档/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ygs-code/react/7f532f80a66460f90b075f50c028b48faed6fd31/react逐行源码分析文档/01.png -------------------------------------------------------------------------------- /react逐行源码分析文档/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ygs-code/react/7f532f80a66460f90b075f50c028b48faed6fd31/react逐行源码分析文档/02.png -------------------------------------------------------------------------------- /react逐行源码分析文档/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ygs-code/react/7f532f80a66460f90b075f50c028b48faed6fd31/react逐行源码分析文档/03.png -------------------------------------------------------------------------------- /react逐行源码分析文档/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ygs-code/react/7f532f80a66460f90b075f50c028b48faed6fd31/react逐行源码分析文档/04.png -------------------------------------------------------------------------------- /react逐行源码分析文档/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ygs-code/react/7f532f80a66460f90b075f50c028b48faed6fd31/react逐行源码分析文档/05.png -------------------------------------------------------------------------------- /react逐行源码分析文档/06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ygs-code/react/7f532f80a66460f90b075f50c028b48faed6fd31/react逐行源码分析文档/06.png -------------------------------------------------------------------------------- /react逐行源码分析文档/createVonde.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ygs-code/react/7f532f80a66460f90b075f50c028b48faed6fd31/react逐行源码分析文档/createVonde.jpg -------------------------------------------------------------------------------- /react逐行源码分析文档/react帖子.md: -------------------------------------------------------------------------------- 1 | 9 | React 源码讲解第 6 节- expirationTime 公式 10 | 11 | https://blog.csdn.net/weixin_44135121/article/details/108863397 12 | https://github.com/7kms/react-illustration-series 13 | https://pomb.us/build-your-own-react/ 14 | 潇晨 https://xiaochen1024.com/article_item/600aca0cecf02e002e6db56c -------------------------------------------------------------------------------- /scattered_deom/MessageChannel.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Document 17 | 18 | 19 | 20 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /scattered_deom/Object.prototype.hasOwnProperty.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Document 16 | 17 | 18 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /scattered_deom/Symbol.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /scattered_deom/clz32Fallback.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Document 16 | 17 | 18 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /scattered_deom/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 |
    13 | 14 | 15 |
16 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /scattered_deom/describeComponentFrame.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Document 16 | 17 | 18 | 70 | 71 | -------------------------------------------------------------------------------- /scattered_deom/getIteratorFn.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Document 16 | 17 | 18 | 65 | 66 | -------------------------------------------------------------------------------- /scattered_deom/hasOwnProperty.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /scattered_deom/hasValidRef.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /scattered_deom/lowPriorityWarning.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /scattered_deom/newSet.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Document 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /scattered_deom/objectAssign.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /scattered_deom/performance.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Document 16 | 17 | 18 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /scattered_deom/performance.mark.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Document 16 | 17 | 18 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /scattered_deom/performance.measure.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Document 16 | 17 | 18 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /scattered_deom/performance.now.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Document 16 | 17 | 18 | 42 | 43 | -------------------------------------------------------------------------------- /scattered_deom/printWarning.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 40 | 41 | -------------------------------------------------------------------------------- /scattered_deom/reg.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Document 16 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /scattered_deom/removeChild.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |
11 |
12 | 1 13 |
1-1
14 |
1-2
15 |
1-3
16 |
17 |
18 |
2-1
19 |
2-2
20 |
2-3
21 |
22 |
3 23 |
3-1
24 |
3-2
25 |
3-3
26 |
27 |
28 | 49 | 50 | -------------------------------------------------------------------------------- /scattered_deom/requestAnimationFrame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Document 10 | 11 | 20 | 21 |
22 | 23 |
24 | 54 | 55 | -------------------------------------------------------------------------------- /scattered_deom/requestAnimationFrame1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 19 | 20 |
21 | 22 |
23 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /scattered_deom/requestAnimationFrame2.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Document 17 | 18 | 27 | 28 |
29 | 30 |
31 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /scattered_deom/scheduling.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 14 | 15 | -------------------------------------------------------------------------------- /scattered_deom/shouldUseNative.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /scattered_deom/tranform-rpx-px.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /scattered_deom/update.next.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Document 16 | 17 | 18 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /scattered_deom/warningWithoutStack.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 64 | 65 | -------------------------------------------------------------------------------- /scattered_deom/二叉树.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /scattered_deom/二进制,八进制,十进制,位与,或,非,等.html: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Document 16 | 17 | 18 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /scattered_deom/堆化.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /正则/at.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Date: 2022-03-29 17:22:53 3 | * @Author: Yao guan shou 4 | * @LastEditors: Yao guan shou 5 | * @LastEditTime: 2022-03-29 17:27:32 6 | * @FilePath: /react/正则/at.js 7 | * @Description: 8 | * 9 | */ 10 | // 匹配 '\n at ' 11 | const str = ` 12 | at 13 | wer 14 | `; 15 | // var str1 = str.match(/\n(*(at)?)/) 16 | var str1 = str.match(/\n( *(at )?)/); 17 | console.log("str1=", str1); 18 | --------------------------------------------------------------------------------