亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
專案描述
實作方案
建構小程式框架產物
React運行到小程式平臺方案分析
編譯時實現(xiàn)
運行時實現(xiàn)
總結
項目地址
首頁 微信小程式 小程式開發(fā) React如何建立小程式?兩種實現(xiàn)方案分享

React如何建立小程式?兩種實現(xiàn)方案分享

Dec 23, 2021 am 10:27 AM
react 小程式

React如何建立小程式?以下這篇文章給大家透過1500行程式碼揭秘React如何運作到小程式平臺,介紹一下React 建構小程式兩種實作方案,希望對大家有幫助!

React如何建立小程式?兩種實現(xiàn)方案分享

你是否使用過 TaroRemax 類似的框架?你是否想了解這類框架如何實作 React 程式碼運行到小程式平臺?如果是的話,那麼也許你可以花喝一杯咖啡的時間繼續(xù)往下閱讀,本文將透過兩種方案實現(xiàn) React 運行到小程式平臺。如果你現(xiàn)在就想閱讀這1500行的實作程式碼,那麼可以直接點擊專案原始碼來取得(也許要多喝幾杯咖啡)。

專案描述

為了更清楚地描述實現(xiàn)過程,我們把實作方案當作一個專案來對待。
專案需求:使下列計數(shù)器功能的 React 程式碼運作到微信小程式平臺。

import React, { Component } from 'react'
import { View, Text, Button } from '@leo/components'
import './index.css'

export default class Index extends Component {
  constructor() {
    super()
    this.state = { count: 0 }
    this.onAddClick = this.onAddClick.bind(this)
    this.onReduceClick = this.onReduceClick.bind(this)
  }
  componentDidMount () {
    console.log('執(zhí)行componentDidMount')
    this.setState({ count: 1 })
  }
  onAddClick() {
    this.setState({ count: this.state.count + 1 })
  }
  onReduceClick() {
    this.setState({ count: this.state.count - 1 })
  }
  render () {
    const text = this.state.count % 2 === 0 ? '偶數(shù)' : '奇數(shù)'
    return (
      <View className="container">
        <View className="conut">
          <Text>count: {this.state.count}</Text>
        </View>
        <View>
          <Text className="text">{text}</Text>
        </View>
        <Button onClick={this.onAddClick} className="btn">+1</Button>
        <Button onClick={this.onReduceClick} className="btn">-1</Button>
      </View>
    )
  }
}

如果使用過 Taro 或 Remax 等框架,對上述程式碼應該有似曾相識的感覺,上述程式碼正式模仿這類框架的 React DSL 寫法。如果想迫切看到實現(xiàn)這個需求的效果,可點選此項目原始碼進行取得原始碼,然後根據提示運行項目,即可觀察到如下效果:

React如何建立小程式?兩種實現(xiàn)方案分享

到這裡,就清楚了知道這個專案的需求以及最終實現(xiàn)結果是什麼,接下來便是重點闡述從需求點到結果這個過程的具體實現(xiàn)。

實作方案

建構小程式框架產物

開發(fā)過小程式的同學都知道,小程式框架包含主體和頁面,其中主體是由三個檔案生組成的,且必須放在根目錄,這三個檔案分別是: app.js (必需,小程式邏輯),app.json(必需,小程式公共配置),app.wxss(非必須,小程式公共樣式表)。所以要將 React 程式碼建構成小程式碼,首先需要先生成app.jsapp.json檔。因為這次轉換未涉及到app.js文件,所以app.js內容可以直接寫死 App({})取代。 app.json是設定文件,可以直接在React 工程新增一個app.config.js用來填入設定內容,即React 程式碼工程目錄如下:

├── src
│   ├── app.config.js          // 小程序配置文件,用來生成app.json內容      
│   └── pages
│       └── index
│           ├── index.css
│           └── index.jsx      // React代碼,即上述計數(shù)器代碼
└── tsconfig.json

app.config.js內容就是小程式全域設定內容,如下:

module.exports = {
  pages: [&#39;pages/index/index&#39;],
  window: {
    navigationBarTitleText: &#39;react-wxapp&#39;,
    navigationBarBackgroundColor: &#39;#282c34&#39;
  }
};

有了這個設定文件,就可以透過以下方式產生app.jsapp.json檔案。

/*outputDir為小程序代碼生成目錄*/
fs.writeFileSync(path.join(outputDir, &#39;./app.js&#39;), `App({})`)
fs.writeFileSync(path.join(outputDir, &#39;./app.json&#39;), JSON.stringify(config, undefined, 2)) // config即為app.config.js文件內容

小程式頁面則是由四種類型檔案構成,分別是js(必需,頁面邏輯)、wxml(必需,頁面結是構) 、json(非必要、頁面配置)、wxss(非必要、頁面樣式表)。而React程式碼轉小程序,主要是考慮如何將React程式碼轉換程序對應的jswxml類型文件,後文會詳細闡述。

React運行到小程式平臺方案分析

實現(xiàn)React程式碼運行到小程式平臺上主要有兩種方式,一種是編譯時實現(xiàn),一種是運行時實現(xiàn),如果你已經查看的本專案專案原始碼,就可以發(fā)現(xiàn)原始碼裡也體現(xiàn)了這兩種方式(編譯時實作目錄:packages/compile-core;執(zhí)行階段實作目錄:packages/runtime-core)。

編譯時方式主要透過靜態(tài)編譯將 JSX 轉換成小程式對應的 template 來實現(xiàn)渲染,類似 Taro1.0 和 2.0,此方式效能接近原生小程序,但是語法卻有很大的限制。運行時實作是透過react-reconciler重新在小程式平臺定義一個React 渲染器,使得React 程式碼可以真正運行到小程式裡,類似Taro3.0、Remax 等,因此這種方式無語法限制,但是性能會比較差。本專案原始碼正是參考Taro、Remax 這類框架原始碼並簡化許多細節(jié)進行實現(xiàn)的,因此這個專案原始碼只是適合來學習的,並不能投入實際業(yè)務進行使用。

接下來將分別講述如何通過編譯時和運行時這兩種方式來實現(xiàn) React 運行到小程序平臺。

編譯時實現(xiàn)

在講述具體實現(xiàn)流程之前,首先需要了解下編譯時實現(xiàn)這個名詞的概念,首先這里的編譯并非傳統(tǒng)的高大上“編譯”,傳統(tǒng)意義上的編譯一般將高級語言往低級語言進行編譯,但這里只是將同等水平語言轉換,即將javascript代碼字符串編譯成另一種javascript代碼字符串,因此這里的編譯更類似于“轉譯”。其次,雖然這里稱編譯時實現(xiàn),并非所有實現(xiàn)過程都是編譯的,還是需要少部分實現(xiàn)需要運行時配合,因此這種方式稱為重編譯輕運行方式更為合適。同樣的,運行時實現(xiàn)也含有少量編譯時實現(xiàn),亦可稱為重運行輕編譯方式。

為了方便實現(xiàn)將javascript代碼字符串編譯成另一種javascript代碼字符串,這里直接采用Babel工具,由于篇幅問題,這里就不詳細講述Babel用法了,如果對Babel不熟的話,可以看看這篇文章簡單了解下(沒錯,就是給自己打廣告)。接下來我們來分析編譯時實現(xiàn)步驟有哪些:

1. JSX轉換成對應小程序的模板

React是通過JSX來渲染視圖的,而小程序則通過wxml來渲染視圖,要將 React 運行到小程序上,其重點就是要如何實現(xiàn)JSX轉換成對應的小程序的wxml,其轉換規(guī)則就是將JSX使用語法轉換成小程序相同功能的語法,例如:

  • 標簽元素轉換:View、TextButton等標簽直接映射為小程序基礎組件本身(改為小寫)

  • 樣式類名轉換:className修改為class

    <View className="xxx" />  ==>  <View class="xxx" />
  • 事件轉換:如onClick修改為bindtap

    <View onClick=xxx />  ==>  <View bindtap =xxx />
  • 循環(huán)轉換:map語法修改為wx:for

    list.map(i => <Text>{i}</Text>) => <Text wx:for="{{list}}">{{item}}</Text>

語法轉換遠不止上面這些類型,如果要保證開發(fā)者可以使用各種JSX語法開發(fā)小程序,就需要盡可能窮舉出所有語法轉換規(guī)則,否則很可能開發(fā)者用了一個寫法就不支持轉換。而事實是,有些寫法(比如動態(tài)生成JSX片段等等)是根本無法支持轉換,這也是前文為什么說編譯時實現(xiàn)方案的缺點是語法有限制,開發(fā)者不能隨意編碼,需要受限于框架本身開發(fā)規(guī)則。

由于上述需要轉換JSX代碼語法相對簡單,只需要涉及幾種簡單語法規(guī)則轉換,這里直接貼出轉換后的wxml結果如下,對應的實現(xiàn)代碼位于:packages/compile-core/transform/parseTemplate.ts

<view class="container">
  <view class="conut"><Text>count: {{count}}</Text></view>
  <view>
    <text class="text">{{text}}</text>
  </view>
  <button bindtap="onAddClick" class="btn">+1</button>
  <button bindtap="onReduceClick" class="btn">-1</button>
</view>

2. 運行時適配

如前文所說,雖然這個方案稱為編譯時實現(xiàn),但是要將React代碼在小程序平臺驅動運行起來,還需要在運行時做下適配處理。適配處理主要在小程序js邏輯實現(xiàn),內容主要有三塊:數(shù)據渲染、事件處理、生命周期映射。

小程序js邏輯是通過一個object參數(shù)配置聲明周期、事件等來進行注冊,并通過setData方法觸發(fā)視圖渲染:

Component({
  data: {},
  onReady () { this.setData(..) },
  handleClick () {}
})

而計數(shù)器React代碼是通過class聲明一個組件邏輯,類似:

class CustomComponent extends Component {
  state = { }
  componentDidMount() { this.setState(..)  }
  handleClick () { }
}

從上面兩段代碼可以看出,小程序是通過object聲明邏輯,React 則是通過class進行聲明。除此之外,小程序是通過setData觸發(fā)視圖(wxml)渲染,React 則是通過 setState 觸發(fā)視圖(render方法)渲染。所以要使得 React 邏輯可以運行到小程序平臺,可以加入一個運行時墊片,將兩者邏輯寫法通過墊片對應起來。再介紹運行時墊片具體實現(xiàn)前,還需要對上述 React 計數(shù)器代碼進行簡單的轉換處理,處理完的代碼如下:

import React, { Component } from "../../npm/app.js";  // 1.app.js為墊片實現(xiàn)文件
export default class Index extends Component {
  static $$events = ["onAddClick", "onReduceClick"];  // 2.收集JSX事件名稱
  constructor() {
    super();
    this.state = {
      count: 0
    };
    this.onAddClick = this.onAddClick.bind(this);
    this.onReduceClick = this.onReduceClick.bind(this);
  }
  componentDidMount() {
    console.log(&#39;執(zhí)行componentDidMount&#39;);
    this.setState({
      count: 1
    });
  }
  onAddClick() {
    this.setState({
      count: this.state.count + 1
    });
  }
  onReduceClick() {
    this.setState({
      count: this.state.count - 1
    });
  }
  createData() {                                      // 3.render函數(shù)改為createData,刪除
    this.__state = arguments[0];                      // 原本的JSX代碼,返回更新后的state
                                                      // 提供給小程序進行setData
    const text = this.state.count % 2 === 0 ? &#39;偶數(shù)&#39; : &#39;奇數(shù)&#39;;
    Object.assign(this.__state, {
      text: text
    });
    return this.__state;
  }

}    
Page(require(&#39;../../npm/app.js&#39;).createPage(Index))。 // 4.使用運行時墊片提供的createPage
                                                      // 方法進行初始化
                                                      // 方法進行初始化復制代碼

如上代碼,需要處理的地方有4處:

  • Component進行重寫,重寫邏輯在運行時墊片文件內實現(xiàn),即app.js,實現(xiàn)具體邏輯后文會貼出。

  • 將原本JSX的點擊事件對應的回調方法名稱進行收集,以便在運行時墊片在小程序平臺進行事件注冊。

  • 因為原本render方法內JSX片段轉換為wxml了,所以這里render方法可將JSX片段進行刪除。另外因為React每次執(zhí)行setState都會觸發(fā)render方法,而render方法內會接受到最新的state數(shù)據來更新視圖,因此這里產生的最新state正是需要提供給小程序的setData方法,從而觸發(fā)小程序的數(shù)據渲染,為此將render名稱重命名為createData(生產小程序的data數(shù)據),同時改寫內部邏輯,將產生的最新state進行返回。

  • 使用運行時墊片提供的createPage方法進行初始化(createPage方法實現(xiàn)具體邏輯后文會貼出),同時通過小程序平臺提供的Page方法進行注冊,從這里可得知createPage方法返回的數(shù)據肯定是一個object類型。

運行時墊片(app.js)實現(xiàn)邏輯如下:

export class Component {                             // 重寫Component的實現(xiàn)邏輯
  constructor() {
    this.state = {}
  }
  setState(state) {                                  // setState最終觸發(fā)小程序的setData
    update(this.$scope.$component, state)
  }
  _init(scope) {
    this.$scope = scope
  }
}
function update($component, state = {}) {
  $component.state = Object.assign($component.state, state)
  let data = $component.createData(state)            // 執(zhí)行createData獲取最新的state
  data[&#39;$leoCompReady&#39;] = true
  $component.state = data
  $component.$scope.setData(data)                    // 將state傳遞給setData進行更新
}
export function createPage(ComponentClass) {         // createPage實現(xiàn)邏輯
  const componentInstance = new ComponentClass()     // 實例化傳入進來React的Class組件
  const initData = componentInstance.state     
  const option = {                                   // 聲明一個小程序邏輯的對象字面量
    data: initData,
    onLoad() {
      this.$component = new ComponentClass()
      this.$component._init(this)
      update(this.$component, this.$component.state)
    },
    onReady() {
      if (typeof this.$component.componentDidMount === &#39;function&#39;) {
        this.$component.componentDidMount()           // 生命邏輯映射
      }
    }
  }
  const events = ComponentClass[&#39;$$events&#39;]          // 獲取React組件內所有事件回調方法名稱
  if (events) {
    events.forEach(eventHandlerName => {             
      if (option[eventHandlerName]) return
      option[eventHandlerName] = function () {
        this.$component[eventHandlerName].call(this.$component)
      }
    })
  }
  return option
}

上文提到了重寫Component類和createPage方法具體實現(xiàn)邏輯如上代碼所示。

Component內聲明的state會執(zhí)行一個update方法,update方法里主要是將 React 產生的新state和舊state進行合并,然后通過上文說的createData方法獲取到合并后的最新state,最新的state再傳遞給小程序進行setData,從而實現(xiàn)小程序數(shù)據渲染。

createPage方法邏輯首先是將 React 組件實例化,然后構建出一個小程序邏輯的對應字面量,并將 React 組件實例相關方法和這個小程序邏輯對象字面量進行綁定:其次進行生命周期綁定:在小程序onReady周期里出發(fā) React 組件對應的componentDidMount生命周期;最好進行事件綁定:通過上文提到的回調事件名,取出React 組件實例內的對應的事件,并將這些事件注冊到小程序邏輯的對應字面量內,這樣就完成小程序平臺事件綁定。最后將這個對象字面量返回,供前文所說的Page方法進行注冊。

到此,就可以實現(xiàn) React 代碼運行到小程序平臺了,可以在項目源碼里執(zhí)行 npm run build:compile 看看效果。編譯時實現(xiàn)方案主要是通過靜態(tài)編譯JSX代碼和運行時墊片結合,完成 React 代碼運行到小程序平臺,這種方案基本無性能上的損耗,且可以在運行時墊片做一些優(yōu)化處理(比如去除不必要的渲染數(shù)據,減少setData數(shù)據量),因此其性能與使用小程序原生語法開發(fā)相近甚至某些場景會更優(yōu)。然而這種方案的缺點就是語法限制問題(上文已經提過了),使得開發(fā)并不友好,因此也就有了運行時實現(xiàn)方案的誕生。

運行時實現(xiàn)

從上文可以看出,編譯時實現(xiàn)之所以有語法限制,主要因為其不是讓 React 真正運行到小程序平臺,而運行時實現(xiàn)方案則可以,其原理是在小程序平臺實現(xiàn)一個 React 自定義渲染器,用來渲染 React 代碼。這里我們以 remax 框架實現(xiàn)方式來進行講解,本項目源碼中的運行時實現(xiàn)也正是參照 remax 框架實現(xiàn)的。

如果使用過 React 開發(fā)過 Web,入口文件有一段類似這樣的代碼:

import React from &#39;react&#39;
import ReactDom from &#39;react-dom&#39;
import App from &#39;./App&#39;

ReactDom.render(
  App,
  document.getElementById(&#39;root&#39;)
)

可以看出渲染 Web 頁面需要引用一個叫 react-dom 模塊,那這個模塊作用是什么?react-dom是 Web 平臺的渲染器,主要負責將 React 執(zhí)行后的Vitrual DOM數(shù)據渲染到 Web 平臺。同樣的,React 要渲染到 Native,也有一個針對 Native 平臺的渲染器:React Native。
React實現(xiàn)多平臺方式,是在每個平臺實現(xiàn)一個React渲染器,如下圖所示。

React如何建立小程式?兩種實現(xiàn)方案分享

而如果要將 React 運行到小程序平臺,只需要開發(fā)一個小程序自定義渲染器即可。React 官方提供了一個react-reconciler 包專門來實現(xiàn)自定義渲染器,官方提供了一個簡單demo重寫了react-dom

使用react-reconciler實現(xiàn)渲染器主要有兩步,第一步:實現(xiàn)渲染函數(shù)(render方法),類似ReactDOM.render方法:

import ReactReconciler from &#39;react-reconciler&#39;
import hostConfig from &#39;./hostConfig&#39;      // 宿主配置

// 創(chuàng)建Reconciler實例, 并將HostConfig傳遞給Reconciler
const ReactReconcilerInst = ReactReconciler(hostConfig)

/**
 * 提供一個render方法,類似ReactDom.render方法
 * 與ReactDOM一樣,接收三個參數(shù)
 * render(<MyComponent />, container, () => console.log(&#39;rendered&#39;))
 */
export function render(element, container, callback) {
  // 創(chuàng)建根容器
  if (!container._rootContainer) {
    container._rootContainer = ReactReconcilerInst.createContainer(container, false);
  }
  // 更新根容器
  return ReactReconcilerInst.updateContainer(element, container._rootContainer, null, callback);
}

第二步,如上圖引用的import hostConfig from &#39;./hostConfig&#39; ,需要通過react-reconciler實現(xiàn)宿主配置(HostConfig),HostConfig是宿主環(huán)境提供一系列適配器方案和配置項,定義了如何創(chuàng)建節(jié)點實例、構建節(jié)點樹、提交和更新等操作,完整列表可以點擊查看。值得注意的是在小程序平臺未提供DOM API操作,只能通過setData將數(shù)據傳遞給視圖層。因此Remax重新定義了一個VNode類型的節(jié)點,讓 React 在reconciliation過程中不是直接去改變DOM,而先更新VNode,hostConfig文件內容大致如下:

interface VNode {
  id: number;              // 節(jié)點 id,這是一個自增的唯一 id,用于標識節(jié)點。
  container: Container;    // 類似 ReactDOM.render(<App />, document.getElementById(&#39;root&#39;) 中的第二個參數(shù)
  children: VNode[];       // 子節(jié)點。
  type: string | symbol;   // 節(jié)點的類型,也就是小程序中的基礎組件,如:view、text等等。
  props?: any;             // 節(jié)點的屬性。
  parent: VNode | null;    // 父節(jié)點
  text?: string;           // 文本節(jié)點上的文字
  appendChild(node: VNode): void;
  removeChild(node: VNode): void;
  insertBefore(newNode: VNode, referenceNode: VNode): void;
  ...
}

// 實現(xiàn)宿主配置
const hostConfig = {

  ...
  // reconciler提交后執(zhí)行,觸發(fā)容器更新數(shù)據(實際會觸發(fā)小程序的setData)
  resetAfterCommit: (container) => {
    container.applyUpdate();
  },
  // 創(chuàng)建宿主組件實例,初始化VNode節(jié)點
  createInstance(type, newProps, container) {
    const id = generate();
    const node = new VNode({ ... });
    return node;
  },
  // 插入節(jié)點
  appendChild(parent, child) {
    parent.appendChild(child);
  },
  // 
  insertBefore(parent, child, beforeChild) {
    parent.insertBefore(child, beforeChild);
  },
  // 移除節(jié)點
  removeChild(parent, child) {
    parent.removeChild(child);
  }
  
  ...
  
};

除了上面的配置內容,還需要提供一個容器用來將VNode數(shù)據格式化為JSON數(shù)據,供小程序setData傳遞給視圖層,這個容器類實現(xiàn)如下:

class Container {
  constructor(context) {
    this.root = new VNode({..});   // 根節(jié)點
  }

  toJson(nodes ,data) {            // 將VNode數(shù)據格式化JSON
    const json = data || []
    nodes.forEach(node => {
      const nodeData = {
        type: node.type,
        props: node.props || {},
        text: node.text,
        id: node.id,
        children: []
      }
      if (node.children) {
        this.toJson(node.children, nodeData.children)
      }
      json.push(nodeData)
    })
    return json
  }
  applyUpdate() {                 // 供HostConfig配置的resetAfterCommit方法執(zhí)行
    const root = this.toJson([this.root])[0]
    console.log(root)
    this.context.setData({ root});
  }
  ...
}

緊接著,我們封裝一個createPageConfig方法,用來執(zhí)行渲染,其中Page參數(shù)為 React 組件,即上文計數(shù)器的組件。

import * as React from &#39;react&#39;;
import Container from &#39;./container&#39;; // 上文定義的Container
import render from &#39;./render&#39;;       // 上文定義的render方法

export default function createPageConfig(component) {  // component為React組件
  const config = {  // 小程序邏輯對象字面量,供Page方法注冊
    data: {
      root: {
        children: [],
      }
    },
    onLoad() {
      this.container = new Container(this, &#39;root&#39;);
      const pageElement = React.createElement(component, {
        page: this,
      });

      this.element = render(pageElement, this.container);
    }
  };

  return config;
}

到這里,基本已經實現(xiàn)完小程序渲染器了,為了使代碼跑起來,還需要通過靜態(tài)編譯改造下 React 計數(shù)器組件,其實就是在末尾插入一句代碼:

import React, { Component } from &#39;react&#39;;
export default class Index extends Component {
  constructor() {
    super();
    this.state = {
      count: 0
    };
    this.onAddClick = this.onAddClick.bind(this);
    this.onReduceClick = this.onReduceClick.bind(this);
  }
  ...

} 
// app.js封裝了上述createPage方法
Page(require(&#39;../../npm/app.js&#39;).createPage(Index))

通過這樣,就可以使得React代碼在小程序真正運行起來了,但是這里我們還有個流程沒介紹,上述Container類的applyUpdate方法中生成的頁面JSON數(shù)據要如何更新到視圖?首先我們先來看下這個JSON數(shù)據長什么樣子:

// 篇幅問題,這里只貼部分數(shù)據
{
	"type": "root",
	"props": {},
	"id": 0,
	"children": [{
		"type": "view",
		"props": {
			"class": "container"
		},
		"id": 12,
		"children": [{
			"type": "view",
			"props": {
				"class": "conut"
			},
			"id": 4,
			"children": [{
				"type": "text",
				"props": {},
				"id": 3,
				"children": [{
					"type": "plain-text",
					"props": {},
					"text": "count: ",
					"id": 1,
					"children": []
				}, {
					"type": "plain-text",
					"props": {},
					"text": "1",
					"id": 2,
					"children": []
				}]
			}]
		}
 	...
 	...
 		
	}]
}

可以看出JSON數(shù)據,其實是一棵類似Tree UI的數(shù)據,要將這些數(shù)據渲染出頁面,可以使用小程序提供的Temlate進行渲染,由于小程序模板遞歸嵌套會有問題(微信小程序平臺限制),因此需要提供多個同樣組件類型的模板進行遞歸渲染,代碼如下:

<template is="TPL" data="{{root: root}}" />  <!-- root為上述的JSON數(shù)據 -->


<template name="TPL">
 <block wx:for="{{root.children}}" wx:key="id">
  <template is="TPL_1_CONTAINER" data="{{i: item, a: &#39;&#39;}}" />
 </block>
</template>

    
<template name="TPL_1_view">
  <view
    style="{{i.props.style}}"
    class="{{i.props.class}}"
    bindtap="{{i.props.bindtap}}"
  >
    <block wx:for="{{i.children}}" wx:key="id">
      <template is="{{&#39;TPL_&#39; + (tid + 1) + &#39;_CONTAINER&#39;}}" data="{{i: item, a: a, tid: tid + 1 }}" />
    </block>
  </view>
</template>
  
<template name="TPL_2_view">
  <view
    style="{{i.props.style}}"
    class="{{i.props.class}}"
    bindtap="{{i.props.bindtap}}"
  >
    <block wx:for="{{i.children}}" wx:key="id">
      <template is="{{&#39;TPL_&#39; + (tid + 1) + &#39;_CONTAINER&#39;}}" data="{{i: item, a: a, tid: tid + 1 }}" />
    </block>
  </view>
</template>
  
<template name="TPL_3_view">
  <view
    style="{{i.props.style}}"
    class="{{i.props.class}}"
    bindtap="{{i.props.bindtap}}"
  >
    <block wx:for="{{i.children}}" wx:key="id">
      <template is="{{&#39;TPL_&#39; + (tid + 1) + &#39;_CONTAINER&#39;}}" data="{{i: item, a: a, tid: tid + 1 }}" />
    </block>
  </view>
</template>
 
...
...

至此,就可以真正實現(xiàn) React 代碼運行到小程序了,可以在項目源碼里執(zhí)行npm run build:runtime看看效果。運行時方案優(yōu)點是無語法限制,(不信的話,可以在本項目里隨便寫各種動態(tài)寫法試試哦),而缺點時性能比較差,主要原因是因為其setData數(shù)據量比較大(上文已經貼出的JSON數(shù)據,妥妥的比編譯時方案大),因此性能就比編譯時方案差。當然了,業(yè)界針對運行時方案也有做大量的性能優(yōu)化,比如局部更新、虛擬列表等,由于篇幅問題,這里就不一一講解(代碼中也沒有實現(xiàn))。

總結

本文以最簡實現(xiàn)方式講述了 React 構建小程序兩種實現(xiàn)方案,這兩種方案優(yōu)缺點分明,都有各自的優(yōu)勢,對于追求性能好場的場景,編譯時方案更為合適。對于著重開發(fā)體驗且對性能要求不高的場景,運行時方案為首選。如果想了解更多源碼實現(xiàn),可以去看下 Taro、Remax 官方源碼,歡迎互相討論。

項目地址

https://github.com/canfoo/react-wxapp

【相關學習推薦:小程序開發(fā)教程

以上是React如何建立小程式?兩種實現(xiàn)方案分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發(fā)現(xiàn)涉嫌抄襲或侵權的內容,請聯(lián)絡admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

React與Vue:Netflix使用哪個框架? React與Vue:Netflix使用哪個框架? Apr 14, 2025 am 12:19 AM

NetflixusesAcustomFrameworkcalled“ Gibbon” BuiltonReact,notReactorVuedIrectly.1)TeamSperience:selectBasedonFamiliarity.2)ProjectComplexity:vueforsimplerprojects:reactforforforproproject,reactforforforcompleplexones.3)cocatizationneedneeds:reactoffipicatizationneedneedneedneedneedneeds:reactoffersizationneedneedneedneedneeds:reactoffersizatization needefersmoreflexibleise.4)

React的生態(tài)系統(tǒng):庫,工具和最佳實踐 React的生態(tài)系統(tǒng):庫,工具和最佳實踐 Apr 18, 2025 am 12:23 AM

React生態(tài)系統(tǒng)包括狀態(tài)管理庫(如Redux)、路由庫(如ReactRouter)、UI組件庫(如Material-UI)、測試工具(如Jest)和構建工具(如Webpack)。這些工具協(xié)同工作,幫助開發(fā)者高效開發(fā)和維護應用,提高代碼質量和開發(fā)效率。

Netflix的前端:React(或VUE)的示例和應用 Netflix的前端:React(或VUE)的示例和應用 Apr 16, 2025 am 12:08 AM

Netflix使用React作為其前端框架。 1)React的組件化開發(fā)模式和強大生態(tài)系統(tǒng)是Netflix選擇它的主要原因。 2)通過組件化,Netflix將復雜界面拆分成可管理的小塊,如視頻播放器、推薦列表和用戶評論。 3)React的虛擬DOM和組件生命週期優(yōu)化了渲染效率和用戶交互管理。

反應:JavaScript庫用於Web開發(fā)的功能 反應:JavaScript庫用於Web開發(fā)的功能 Apr 18, 2025 am 12:25 AM

React是由Meta開發(fā)的用於構建用戶界面的JavaScript庫,其核心是組件化開發(fā)和虛擬DOM技術。 1.組件與狀態(tài)管理:React通過組件(函數(shù)或類)和Hooks(如useState)管理狀態(tài),提升代碼重用性和維護性。 2.虛擬DOM與性能優(yōu)化:通過虛擬DOM,React高效更新真實DOM,提升性能。 3.生命週期與Hooks:Hooks(如useEffect)讓函數(shù)組件也能管理生命週期,執(zhí)行副作用操作。 4.使用示例:從基本的HelloWorld組件到高級的全局狀態(tài)管理(useContext和

React的未來:Web開發(fā)的趨勢和創(chuàng)新 React的未來:Web開發(fā)的趨勢和創(chuàng)新 Apr 19, 2025 am 12:22 AM

React的未來將專注於組件化開發(fā)的極致、性能優(yōu)化和與其他技術棧的深度集成。 1)React將進一步簡化組件的創(chuàng)建和管理,推動組件化開發(fā)的極致。 2)性能優(yōu)化將成為重點,特別是在大型應用中的表現(xiàn)。 3)React將與GraphQL和TypeScript等技術深度集成,提升開發(fā)體驗。

React的前端開發(fā):優(yōu)勢和技術 React的前端開發(fā):優(yōu)勢和技術 Apr 17, 2025 am 12:25 AM

React的優(yōu)勢在於其靈活性和高效性,具體表現(xiàn)在:1)組件化設計提高了代碼重用性;2)虛擬DOM技術優(yōu)化了性能,特別是在處理大量數(shù)據更新時;3)豐富的生態(tài)系統(tǒng)提供了大量第三方庫和工具。通過理解React的工作原理和使用示例,可以掌握其核心概念和最佳實踐,從而構建高效、可維護的用戶界面。

反應,vue和Netflix前端的未來 反應,vue和Netflix前端的未來 Apr 12, 2025 am 12:12 AM

Netflix主要使用React作為前端框架,輔以Vue用於特定功能。 1)React的組件化和虛擬DOM提升了Netflix應用的性能和開發(fā)效率。 2)Vue在Netflix的內部工具和小型項目中應用,其靈活性和易用性是關鍵。

React與後端框架:比較 React與後端框架:比較 Apr 13, 2025 am 12:06 AM

React是前端框架,用於構建用戶界面;後端框架用於構建服務器端應用程序。 React提供組件化和高效的UI更新,後端框架提供完整的後端服務解決方案。選擇技術棧時需考慮項目需求、團隊技能和可擴展性。

See all articles