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組件質量相對較好些,但這個封裝性也是看組件開發者。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章