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组件质量相对较好些,但这个封装性也是看组件开发者。