Html网页中驱动React组件

Html网页中驱动React组件

本文是《Html网页中驱动Vue组件》的姊妹篇。

通常React组件的使用办法,是通过create-react-app创建一个应用骨架,然后import相应组件,在应用中调用ReactDOM.createRoot创建根结点,然后初始化整个页面、应用。

这样得到的应用,是需要进行编译、打包转换后的js/css等文件。

我希望是在手工弄一个原始纯净的HTML,将React组件的js文件引入,然后初始化起来。

这样的做法类似于webpack的dll组件思想,组件应该是方便加载、适配、运行的,而不是必须编译、打包后才能正常支行。

React官方网站对这种情况即有相关说明与支持:https://zh-hans.reactjs.org/docs/add-react-to-a-website.html

1.前提

首先,能够这么做的React组件,必须打包成umd之类的组件包。

2.目标组件

选定math3d-component组件,github链接:https://github.com/ecuber/math3d-component

如下代码为GitHub的Readme中的组件使用示例代码。

import React from 'react'
import Math3D from 'math3d-component'
import myGraphs from './myGraphs.json'

export default const App = (props) => {
  /**
   * You may store your dehydrated graphs however you like. If you have an existing database 
   * for your website, that's a great option! In this case, I have a file called myGraphs.json
   * in the same directory as this component file.
   * */
  const graphID = 'z6rPenvx'
  const dehydratedScene = myGraphs[graphID] // a JSON object containing the Math3D scene data

  return <Math3D dehydrated={dehydratedScene} style={{ width: '80%' }} />
}

3.页面初始化脚本

页面初始化脚本,参考链接https://zh-hans.reactjs.org/docs/add-react-to-a-website.html说明,并根据应用转化,如下:


  <script>
    const saveGraph = (dehydrated) => {
	  console.log("json data: ", JSON.stringify(dehydrated));
	}
    var math3d_json = JSON.parse('{"math3d01":{"metadata":{"id":"math3d01","title":"Production Demo","versionAtCreation":"1.2.9"},"sortableTree":{"root":["mainFolder"],"mainFolder":["2","6"]},"folders":{"cameraFolder":{"isCollapsed":false}},"mathSymbols":{"6":{"type":"VARIABLE_SLIDER","min":"0","max":"2\\\\pi","isAnimating":true,"speedMultiplier":0.125}},"mathGraphics":{"2":{"type":"EXPLICIT_SURFACE_POLAR","color":"bluered","expr":"_f(r,\\\\theta)=\\\\frac{1}{2}r^2\\\\cdot\\\\cos\\\\left(4\\\\left(\\\\theta+T\\\\right)\\\\right)"},"camera":{"type":"CAMERA","relativePosition":[1.338764790884554,-0.5084826992278124,0.8021663774172647],"relativeLookAt":[0,0,0]}},"sliderValues":{"6":1.655881127829626}},"math3d02":{"metadata":{"title":"math3d02"},"sortableTree":{"root":["mainFolder"],"mainFolder":["1"]},"mathGraphics":{"1":{"type":"EXPLICIT_SURFACE","color":"bluered"},"camera":{"type":"CAMERA","relativePosition":[0.4999999999999996,-1.9999999999999984,0.49999999999999933],"relativeLookAt":[0,0,0]}}},"math3d03":{"metadata":{"id":"math3d03"},"sortableTree":{"root":["mainFolder"],"mainFolder":["1"]},"mathGraphics":{"1":{"type":"EXPLICIT_SURFACE","color":"rainbow"},"camera":{"type":"CAMERA","relativePosition":[0.4999999999999996,-1.9999999999999984,0.49999999999999933],"relativeLookAt":[0,0,0]}}},"math3d04":{"metadata":{"id":"math3d04","title":"Slanty Arrows"},"sortableTree":{"root":["mainFolder"],"mainFolder":["4","5"]},"folders":{"cameraFolder":{"isCollapsed":false}},"mathSymbols":{"5":{"type":"VARIABLE_SLIDER","min":"0","max":"2\\\\pi","isAnimating":true,"speedMultiplier":2}},"mathGraphics":{"4":{"type":"VECTOR_FIELD","color":"#8e44ad","expr":"_f(x,y,z)=\\\\frac{[\\\\sin\\\\left(T+y\\\\right),\\\\ \\\\cos\\\\left(-T-x\\\\right),\\\\ 0.5]}{\\\\sqrt{x^2+y^2}}"},"camera":{"type":"CAMERA","relativePosition":[-0.0000019807056698150444,1.0714418019475147e-8,1.9807346488578335],"relativeLookAt":[0,0,0]}},"sliderValues":{"5":4.293509959906047}},"math3d05":{"metadata":{"id":"math3d05","title":"Yo-Yo"},"sortableTree":{"root":["mainFolder"],"mainFolder":["9"]},"folders":{"cameraFolder":{"isCollapsed":false}},"mathGraphics":{"9":{"type":"PARAMETRIC_SURFACE"},"camera":{"type":"CAMERA","relativePosition":[0.551530987800248,-1.3354629664836548,0.7177437429437827],"relativeLookAt":[0,0,0]}}}}');
	var math3d = React.createElement(window["math3d-component"].default, {dehydrated: math3d_json.math3d04, style:{width: '80%'}, save: saveGraph, dev: true}, );
	ReactDOM.render(math3d, document.getElementById('root'));
  </script>

这儿的math3d_json是从上面的myGraphs.json中提取出来的,核心代码在这儿:

	var math3d = React.createElement(window["math3d-component"].default, {dehydrated: math3d_json.math3d04, style:{width: '80%'}, save: saveGraph, dev: true}, );
	ReactDOM.render(math3d, document.getElementById('root'));

4.拼装

完整的HTML需要引入依赖的react.development.js/react-dom.development.js,组件的js与css等,组件依赖的jquery/mathquill/mathbox等,如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <link rel="icon" href="/assets/math3d-component/favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="theme-color" content="#000000" />
  <meta name="description" content="Website using this D.M.A.F.: Dope Math Authoring Framework" />

  <!-- JQuery -->
  <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
  <!-- MathQuill -->
  <script src="/assets/math3d-component/mathquill.min.js"></script>
  <link rel="stylesheet" href="/assets/math3d-component/mathquill.css">
  <!-- MathBox -->
  <script src="/assets/math3d-component/mathbox-bundle.min.js"></script>
  <link rel="stylesheet" href="/assets/math3d-component/mathbox.css">

    <link rel="manifest" href="/assets/math3d-component/manifest.json">
    <link rel="shortcut icon" href="/assets/math3d-component/favicon.ico">
	<script type="application/x-javascript" src="/assets/math3d-component/react.development.js"></script>
    <script type="application/x-javascript" src="/assets/math3d-component/react-dom.development.js"></script> 
    <!-- Math3D component -->
    <script type="application/x-javascript" src="/assets/math3d-component/dist/bundle.js"></script>

  <title>MAF App</title>
</head>

<body>
  <noscript>
    You need to enable JavaScript to run this app.
  </noscript>

  <h1 style="width: 95vw;margin: 1.5rem auto;"><strong>Math3D Component Demo</strong></h1>
  <div id="root">
  </div>

  <script>
    //...
  </script>
</body>

</html>

HTML中的/assets等目录即为网站部署的资源文件路径。

5.总结

React组件质量相对较好些,但这个封装性也是看组件开发者。

posted @ 2022-08-10 18:08  日月王  阅读(274)  评论(0编辑  收藏  举报