国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

大鵬網(wǎng)站建設(shè)韶關(guān)seo

大鵬網(wǎng)站建設(shè),韶關(guān)seo,網(wǎng)站開發(fā)者常見問題,中國建設(shè)基礎(chǔ)設(shè)施公司網(wǎng)站本文由 TinyVue 組件庫核心成員鄭志超分享,首先分享了實現(xiàn)跨框架組件庫的必要性,同時通過演示Demo和實際操作向我們介紹了如何實現(xiàn)一個跨框架的組件庫。 前言 前端組件庫跨框架是什么? 前端組件庫跨框架是指在不同的前端框架(如…

本文由 TinyVue 組件庫核心成員鄭志超分享,首先分享了實現(xiàn)跨框架組件庫的必要性,同時通過演示Demo和實際操作向我們介紹了如何實現(xiàn)一個跨框架的組件庫。

前言

前端組件庫跨框架是什么?

前端組件庫跨框架是指在不同的前端框架(如 React、Vue、Solid 等)之間共享和復(fù)用組件的能力。這種能力可以讓開發(fā)者在不同的項目中使用同一套組件庫,從而提高開發(fā)效率和代碼復(fù)用性。

為什么需要做前端組件庫跨框架?

首先,不同的前端框架有不同的語法和 API,如果每個框架都要寫一套組件庫,那么開發(fā)成本和維護成本都會很高。其次,跨框架的組件庫可以讓開發(fā)者更加靈活地選擇框架,而不必擔(dān)心組件庫的兼容性問題。
而 TinyVue 組件庫在實現(xiàn)跨框架之前也經(jīng)歷了三個階段。

第一個階段:

2019年初,當(dāng)時 Vue 3.0 還未發(fā)布,TinyVue創(chuàng)始團隊 率先使用了 @vue/composition-api 和 renderless 無渲染函數(shù)隔離模板、樣式和邏輯代碼;經(jīng)過兩年的發(fā)展,支持的項目達到了800+,同時因為組件功能的豐富,代碼量也達到了20w+。

第二個階段:

2021年初,當(dāng)時 Vue 3.0 已經(jīng)發(fā)展了半年有余,各個方面已經(jīng)逐步完善,TinyVue 支持的項目由 Vue2.0 切換 Vue3.0 的意愿日漸強烈;但是又苦于沒有支持 Vue 3.0 的組件庫; 于是 TinyVue 基于@vue/composition-api 和 renderless的架構(gòu)的巨大優(yōu)勢體現(xiàn)了出來,在短短兩個月通過適配層 vue-common 將 20w+ 行代碼全部適配了 Vue3.0, 極大的減少了開發(fā)成本。2021年10月 TinyVue 組件庫實現(xiàn)了一套代碼同時支持 Vue2.0 和 Vue3.0 。

第三個階段:

2023年6月,TinyVue 團隊需要和開源的 openInula(完全兼容 React )框架合作共同開發(fā) Inula 組件庫,并且通過中科院軟件所的開源之夏活動與開發(fā)者共建 OpenTiny React 組件庫。在此過程中,充分利用 TinyVue 的模板與邏輯分離的架構(gòu),完成了開發(fā)可以適配 React 的 common 適配層,并已完成 4 個 React 組件的開發(fā),并且完全復(fù)用了 renderless 無渲染層的邏輯。

為了更好的理解,可以參考以下 TinyVue 組件庫的架構(gòu)圖:

通過前端組件庫跨框架,可以達到以下效果:

  1. 提高開發(fā)效率和代碼復(fù)用性,減少重復(fù)開發(fā)的工作量。

  2. 統(tǒng)一 UI 風(fēng)格和交互體驗,提高產(chǎn)品的一致性和可用性。

  3. 支持多種前端框架,讓開發(fā)者更加靈活地選擇框架。

  4. 降低維護成本,減少代碼冗余和重復(fù)的工作。

總之,前端組件庫跨框架可以幫助開發(fā)者更加高效地開發(fā)和維護前端應(yīng)用,提高產(chǎn)品的質(zhì)量和用戶體驗。

如何開發(fā)

要實現(xiàn)前端組件庫跨框架,需要使用一些技術(shù)手段。本文將要演示如何通過 common 適配層和 renderless 無渲染邏輯層實現(xiàn)跨框架組件庫。

溫馨提示: 本文涉及到的代碼較多,所以無法將所有代碼都羅列出來,因此演示流程主要以分析思路為主,如果想要運行完整流程建議下載演示 Demo 查看源碼和展示效果(文章最后會介紹如何下載和運行)

因為 TinyVue 組件庫已具備同時兼容 Vue2 和 Vue3 的能力,所以本文以 React 和 Solid 為例,介紹如何開發(fā)一套復(fù)用現(xiàn)有 TinyVue 代碼邏輯的跨框架組件庫

首先開發(fā) React 和 Solid 跨框架組件庫主要分為幾個步驟:

1、使用 pnpm 管理 monorepo 工程的組件庫,可以更好的管理本地和線上依賴包。

2、創(chuàng)建 React 框架和 Solid 框架的 common 適配層,目的是抹平不同框架之間的差異,并對接 renderless 無渲染邏輯層。

3、實現(xiàn)無渲染邏輯層 renderless,目的是抽離與框架和渲染無關(guān)的業(yè)務(wù)邏輯,然后復(fù)用這部分邏輯。

4、創(chuàng)建模板層去對接 common 適配層和 renderless 無渲染層,從而實現(xiàn)了框架、模板和業(yè)務(wù)邏輯的分離。

下面演示下如何開發(fā)一個跨框架的組件庫

一、使用 pnpm 管理 monorepo 工程的組件庫

1、創(chuàng)建 monorepo 工程文件夾,使用 gitbash 輸入以下命令(以下所有命令均在 gitbase 環(huán)境下運行

mkdir cross-framework-componentcd cross-framework-component# 創(chuàng)建多包目錄
mkdir packages

2、在根目錄下創(chuàng)建 package.json,并修改其內(nèi)容

npm init -y

package.json 內(nèi)容主要分為兩塊:

(1)定義包管理工具和一些啟動工程的腳本:

  • “preinstall”: “npx only-allow pnpm” – 本項目只允許使用 pnpm 管理依賴
  • “dev”: “node setup.js” – 啟動無界微前端的主工程和所有子工程
  • “dev:home”: “pnpm -C packages/home dev” – 啟動無界微前端的主工程(Vue3 框架)
  • “dev:react”: “pnpm -C packages/react dev” – 啟動無界微前端的 React 子工程
  • “dev:solid”: “pnpm -C packages/solid dev” – 啟動無界微前端的 Solid 子工程
  • “dev:vue2”: “pnpm -C packages/vue2 dev” – 啟動無界微前端的 Vue2 子工程
  • “dev:vue3”: “pnpm -C packages/vue3 dev” – 啟動無界微前端的 Vue3 子工程

(2)解決一些 pnpm 針對 Vue 不同版本(Vue2、Vue3)的依賴沖突,packageExtensions 項可以讓 Vue2 相關(guān)依賴可以找到正確的 Vue 版本,從而可以正常加載 Vue2 和 Vue3 的組件。

package.json 內(nèi)容如下:

{"name": "@opentiny/cross-framework","version": "1.0.0","description": "","main": "index.js","scripts": {"preinstall": "npx only-allow pnpm","dev": "node setup.js","dev:home": "pnpm -C packages/home dev","dev:react": "pnpm -C packages/react dev","dev:solid": "pnpm -C packages/solid dev","dev:vue2": "pnpm -C packages/vue2 dev","dev:vue3": "pnpm -C packages/vue3 dev"},"repository": {"type": "git"},"keywords": [],"author": "","license": "ISC","dependencies": {"eslint": "8.48.0"},"pnpm": {"packageExtensions": {"vue-template-compiler@2.6.14": {"peerDependencies": {"vue": "2.6.14"}},"@opentiny/vue-locale@2.9.0": {"peerDependencies": {"vue": "2.6.14"}},"@opentiny/vue-common@2.9.0": {"peerDependencies": {"vue": "2.6.14"}}}}
}

3、在根目錄創(chuàng)建 pnpm-workspace.yaml 文件并配置如下:

packages:- packages/**    # packages文件夾下所有包含package.json的文件夾都是子包

4、創(chuàng)建組件源代碼目錄

cd packages
mkdir components

二、 創(chuàng)建 React 框架和 Solid 框架的 common 適配層

將整個工程創(chuàng)建好之后,我們需要抹平不同框架之間的差異,這樣才能實現(xiàn)一套代碼能夠去支持不同的框架,那如何來抹平不同框架之間的差異呢?這里出現(xiàn)一個重要概念–common 適配層 。它用來對接純函數(shù) renderless 無渲染邏輯層。

下面以 React 框架及 Solid 框架為例詳細介紹如何構(gòu)造兩個框架的 common 適配層(Vue 的原理可以類比)

1、在上文創(chuàng)建的 components 文件夾中創(chuàng)建 React 和 Solid 文件夾,并初始化 package.json

mkdir react
mkdir solid
cd react
npm init -y
cd ../solid
npm init -y

package.json 的內(nèi)容主要是把 dependencies 項中@opentiny/react-button 、@opentiny/react-countdown、@opentiny/solid-button、@opentiny/solid-countdown 4個依賴指向本地組件包,這是 pnpm 提供的本地包加載方式。

具體的配置如下所示:

@opentiny/react

{"name": "@opentiny/react","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo "Error: no test specified" && exit 1"},"keywords": [],"author": "","license": "ISC","dependencies": {"@opentiny/react-button": "workspace:~","@opentiny/react-countdown": "workspace:~"}
}

@opentiny/solid

{"name": "@opentiny/solid","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo "Error: no test specified" && exit 1"},"keywords": [],"author": "","license": "ISC","dependencies": {"@opentiny/solid-button": "workspace:~","@opentiny/solid-countdown": "workspace:~"}
}

2、在上文創(chuàng)建的 React 和 Solid 文件夾中創(chuàng)建適配層文件夾 common 并初始化package.json(路徑:packages/components/react/common、packages/components/solid/common)

mkdir common
npm init -y

package.json 內(nèi)容中的一些重要依賴項及其說明:

  • “@opentiny/renderless”: “workspace:~” – 使用本地的 renderless 包
  • “@opentiny/theme”: “workspace:~” – 使用本地的 theme 主題包
  • “classnames”: “^2.3.2” – 處理 html 標(biāo)簽的 class 類名
  • “ahooks”: “3.7.8” – 提供 React 響應(yīng)式數(shù)據(jù)能力,對齊 Vue 的響應(yīng)式數(shù)據(jù)

package.json 具體內(nèi)容如下所示:

@opentiny/react-comon

{"name": "@opentiny/react-common","version": "1.0.0","description": "","main": "src/index.js","keywords": [],"author": "","license": "ISC","dependencies": {"@opentiny/renderless": "workspace:~","@opentiny/theme": "workspace:~","// ---- 處理html標(biāo)簽的class類名 ----": "","classnames": "^2.3.2","// ---- 提供react響應(yīng)式數(shù)據(jù)能力,對齊vue的響應(yīng)式數(shù)據(jù) ----": "","ahooks": "3.7.8","react": "18.2.0"}
}

@opentiny/solid-common

{"name": "@opentiny/solid-common","version": "1.0.0","description": "","main": "src/index.js","keywords": [],"author": "","license": "ISC","dependencies": {"@opentiny/renderless": "workspace:~","@opentiny/theme": "workspace:~","// ---- 處理html標(biāo)簽的class類名 ----": "","classnames": "^2.3.2","solid-js": "^1.7.8"}
}

3、在上文創(chuàng)建的 common 文件夾中繼續(xù)創(chuàng)建適配層邏輯頁面(路徑:packages/components/react/common、packages/components/solid/common)

mkdir src
cd src
touch index.js

React 具體的目錄結(jié)構(gòu)如下:

├─ react
│  ├─ common   # react適配層
│  │  ├─ package.json
│  │  └─ src
│  │     ├─ index.js
│  ├─ index.js
│  ├─ package.json
│  ├─ README.md
│  ├─ README.zh-CN.md
│  └─ src
│     ├─ button  # react框架button組件的模板層
│     │  ├─ package.json
│     │  └─ src
│     │     └─ pc.jsx
│     └─ countdown  # react框架倒計時組件的模板層
│        ├─ package.json
│        └─ src
│           └─ pc.jsx

Solid 具體的目錄結(jié)構(gòu)如下:

├─ solid
│  ├─ common   # solid適配層
│  │  ├─ package.json
│  │  └─ src
│  │     ├─ index.js
│  ├─ index.js
│  ├─ package.json
│  ├─ README.md
│  ├─ README.zh-CN.md
│  └─ src
│     ├─ button  # solid框架button組件的模板層
│     │  ├─ package.json
│     │  └─ src
│     │     └─ pc.jsx
│     └─ countdown  # solid框架倒計時組件的模板層
│        ├─ package.json
│        └─ src
│           └─ pc.jsx

4、最后把 props 和無渲染邏輯層 renderless 導(dǎo)出的 api 進行適配 React 的處理,以下這兩段代碼主要是分別從三個方面來處理這個問題。

  • 抹平響應(yīng)式數(shù)據(jù): 為 React(Solid 本身具有響應(yīng)式能力)提供響應(yīng)式數(shù)據(jù)能力,從而可以復(fù)用 OpentinyVue 已經(jīng)寫好組件的 state 數(shù)據(jù)響應(yīng)能力,React 使用了 ahooks 去模擬了 Vue 的響應(yīng)式數(shù)據(jù),并且可以在響應(yīng)式數(shù)據(jù)變化的時候調(diào)用 React 的setState方法,從而觸發(fā)了視圖的渲染;而 Solid 只需要使用 createSignal 方法去創(chuàng)建響應(yīng)式對象,并且在模板中使用 state().xxx去使用 Solid 自帶的響應(yīng)式能力,從而觸發(fā)視圖渲染。
  • 抹平 Vue 的 nextTick: 使用微任務(wù) queueMicrotask 模擬 Vue 框架的 nextTick。
  • 抹平事件觸發(fā)機制: 使用自定義方法模擬 Vue 框架的事件觸發(fā)機制 emit。

其中 React 具體代碼如下所示(路徑:packages/components/react/common/src/index.js):

import * as hooks from 'react'
import '@opentiny/theme/base/index.less'
import { useReactive } from 'ahooks' 
// 使用ahooks提供的useReactive抹平vue框架的響應(yīng)式數(shù)據(jù)// 抹平vue框架的事件觸發(fā)機制
export const emit =(props) =>(evName, ...args) => {if (props[evName] && typeof props[evName] === 'function') {props[evName](...args)}}// 抹平vue框架的nextTick,等待 dom 更新后觸發(fā)回調(diào)
export const useNextTick = (callback) => {queueMicrotask(callback)
}export const useSetup = ({props, // 模板層傳遞過來的props屬性renderless, // renderless無渲染函數(shù)extendOptions = { framework: 'React' } // 模板層傳遞過來的額外參數(shù)
}) => {const render =typeof props.tiny_renderless === 'function'? props.tiny_renderless: renderlessconst utils = {parent: {},emit: emit(props)}const sdk = render(props,{ ...hooks, useReactive, useNextTick },utils,extendOptions)return {...sdk,type: props.type ?? 'default'}
}

其中 Solid 具體代碼如下所示(路徑:packages/components/solid/common/src/index.js):

import * as hooks from 'solid-js'
import { createSignal } from 'solid-js'
import '@opentiny/theme/base/index.less'const EVENTS_PREFIX = 'on'// 處理solid事件觸發(fā)機制
export const emit =(props) =>(evName, ...args) => {const eventsName = `${EVENTS_PREFIX}${evName[0].toLocaleUpperCase()}${evName.slice(1)}`if (props[eventsName] && typeof props[eventsName] === 'function') {props[eventsName](...args)}}export const useSetState = (initialState) => {// equals: false 配置非常重要,保證state對象屬性發(fā)生變化后視圖可以更新const [state, setState] = createSignal(initialState, { equals: false })return [state, setState]
}// props 應(yīng)該不用做處理, props 都是 . 訪問。
export const useReactive = (staticObject) => {const [state, setState] = useSetState(staticObject)return {state,// 這里提供代理對象提供給renderless無渲染層使用proxy: new Proxy(state(), {get(target, property) {if (typeof target[property] === 'function') {return target[property](target)} else {return target[property]}},set(target, property, value) {Reflect.set(target, property, value)setState((val) => val)return true}})}
}// nextTick, 等待 dom 更新后觸發(fā)回調(diào)
export const useNextTick = (callback) => {queueMicrotask(callback)
}// emitEvent, dispath, broadcast
export const emitEvent = () => {const broadcast = () => {return ''}return {dispatch: () => {return ''},broadcast}
}export const useSetup = ({props,renderless,extendOptions = { framework: 'Solid' }
}) => {const render =typeof props.tiny_renderless === 'function'? props.tiny_renderless: renderlessconst utils = {parent: {},emit: emit(props)}const sdk = render(props,{ ...hooks, useReactive, useNextTick },utils,extendOptions)return {...sdk,type: props.type ?? 'default'}
}

三、無渲染邏輯層 renderless 實現(xiàn)

接下來介紹下實現(xiàn)跨端組件庫的第二個重要概念:renderless 無渲染層 – 這塊分為兩部分:一個是與框架相關(guān)的入口函數(shù)文件(react.js、vue.js、solid.js)另外一個是與框架無關(guān)的純函數(shù)文件(index.js)。

1、在 components 文件夾中創(chuàng)建 renderless 文件夾,并初始化 package.json

mkdir renderless
npm init -y

package.json 文件內(nèi)容如下所示(其中 exports 項表示所有加載的資源都會從 randerless 目錄下的 src 文件夾中按文件路徑尋找):

{"name": "@opentiny/renderless","version": "3.9.0","sideEffects": false,"type": "module","exports": {"./package.json": "./package.json","./*": "./src/*"}
}

2、以 React 和 Solid 為例,采用無渲染邏輯的復(fù)用方式

首先看下 renderless 需要創(chuàng)建的文件夾和文件(注意:這里只是羅列了 renderless 文件夾中的文件結(jié)構(gòu),外部文件結(jié)構(gòu)省略了):

├─ renderless
│  ├─ package.json
│  ├─ README.md
│  ├─ README.zh-CN.md
│  └─ src
│     ├─ button
│     │  ├─ index.js  # 公共邏輯層
│     │  ├─ react.js  # react相關(guān)api層
│     │  ├─ solid.js  # solid相關(guān)api層
│     │  └─ vue.js    # vue相關(guān)api層

react.js 和solid.js 是@opentiny/react-button 組件和 @opentiny/solid-button組件的 renderless 入口文件,它負責(zé)去對接 React 和 Solid 的適配層@opentiny/react-common,主要功能是去調(diào)用一些 React 和 Solid 相關(guān)的 api,比如生命周期函數(shù)等,在 renderless 函數(shù)最后返回了 state 響應(yīng)式對象和一些方法,提供給 React 和 Solid 的函數(shù)式組件使用。

文件主要有兩個需要注意的點:

(1)使用 common 適配層傳遞過來的 useReactive 函數(shù)返回基于 React 和 Solid 的響應(yīng)式數(shù)據(jù),對齊 Vue 的響應(yīng)式數(shù)據(jù)

(2)使用雙層函數(shù)(閉包)保存了一些組件狀態(tài),方便用戶和模板層調(diào)用方法。

react.js 具體代碼內(nèi)容如下所示:

import { handleClick, clearTimer } from './index'export const api = ['state', 'handleClick']export default function renderless(props,{ useReactive },{ emit },{ framework }
) {// 利用ahooks提供的useReactive模擬vue的響應(yīng)式數(shù)據(jù),并且使用react的useRef防止響應(yīng)式數(shù)據(jù)被重復(fù)執(zhí)行定義const state = useReactive({timer: null,disabled: !!props.disabled,plain: props.plain,formDisabled: false})const api = {state,clearTimer: clearTimer(state),handleClick: handleClick({ emit, props, state, framework })}return api
}

solid.js具體代碼內(nèi)容如下所示:

import { handleClick, clearTimer } from './index'export const api = ['state', 'handleClick']export default function renderless(props,{ useReactive },{ emit },{ framework }
) {// prox是state執(zhí)行時候的原始對象的代理const { state, proxy } = useReactive({timer: null,disabled: !!props.disabled,plain: props.plain})const api = {state,clearTimer: clearTimer(proxy),handleClick: handleClick({ emit, props, state: proxy, framework })}return api
}

index.js 是和 React、Solid、Vue 三大框架無關(guān)只和業(yè)務(wù)邏輯有關(guān)的公共邏輯層,因此這部分代碼是和框架無關(guān)的純業(yè)務(wù)邏輯代碼。

index.js 邏輯層一般都是雙層函數(shù)(閉包:函數(shù)返回函數(shù)),第一層函數(shù)保存了一些組件狀態(tài),第二層函數(shù)可以很方便的讓用戶和模板層調(diào)用。

這里介紹下 button 組件的純邏輯層的兩個函數(shù):

(1)handleClick:當(dāng)點擊按鈕時會觸發(fā) handleClick 內(nèi)層函數(shù),如果用戶傳遞的重置時間大于零,則在點擊之后會設(shè)置按鈕的 disabled 屬性為 true 禁用按鈕,并在重置時間后解除按鈕禁用,然后打印出當(dāng)前邏輯觸發(fā)是來自哪個框架,并向外拋出 click 點擊事件;

(2)clearTimer:調(diào)用 clearTimer 方法可以快速清除組件的 timer 定時器。

具體內(nèi)容如下所示:

export const handleClick =({ emit, props, state, framework }) =>(event) => {if (props.nativeType === 'button' && props.resetTime > 0) {state.disabled = truestate.timer = setTimeout(() => {state.disabled = false}, props.resetTime)}console.log(`${framework}框架代碼已觸發(fā)!!!!!!!!!`)emit('click', event)}export const clearTimer = (state) => () => clearTimeout(state.timer)

四、創(chuàng)建模板層去對接 common 適配層和 renderless 無渲染層

由于需要創(chuàng)建的文件太多,為了方便操作,可以直接參考我們提供的示例源碼工程查看 (https://github.com/opentiny/cross-framework-component/tree/master/packages/components/react/src )

React 具體的目錄結(jié)構(gòu)如下:

├─ react
│  ├─ common   # react適配層
│  │  ├─ package.json
│  │  └─ src
│  │     ├─ index.js
│  ├─ index.js
│  ├─ package.json
│  ├─ README.md
│  ├─ README.zh-CN.md
│  └─ src
│     ├─ button  # react框架button組件的模板層
│     │  ├─ package.json
│     │  └─ src
│     │     └─ pc.jsx
│     └─ countdown  # react框架倒計時組件的模板層
│        ├─ package.json
│        └─ src
│           └─ pc.jsx

(https://github.com/opentiny/cross-framework-component/tree/master/packages/components/solid/src)

Solid 具體的目錄結(jié)構(gòu)如下:

├─ solid
│  ├─ common   # solid適配層
│  │  ├─ package.json
│  │  └─ src
│  │     ├─ index.js
│  ├─ index.js
│  ├─ package.json
│  ├─ README.md
│  ├─ README.zh-CN.md
│  └─ src
│     ├─ button  # solid框架button組件的模板層
│     │  ├─ package.json
│     │  └─ src
│     │     └─ pc.jsx
│     └─ countdown  # solid框架倒計時組件的模板層
│        ├─ package.json
│        └─ src
│           └─ pc.jsx

這里創(chuàng)建的模板層和一般的 React 和 Solid 函數(shù)式組件類似,都是接受使用組件的用戶傳遞過來的屬性,并返回需要渲染的 jsx 模板。不一樣的地方是:jsx 綁定的數(shù)據(jù)是通過適配層和 renderless 無渲染層處理后的數(shù)據(jù),并且數(shù)據(jù)發(fā)生變化的時候會觸發(fā)視圖渲染,比如下面代碼中 useSetup 方法。

pc.jsx 的具體實現(xiàn)如下所示(React 路徑:packages/components/react/src/button/src/pc.jsx):

import renderless from '@opentiny/renderless/button/react' // renderless無渲染層import { useSetup } from '@opentiny/react-common' // 抹平不同框架的適配層
import '@opentiny/theme/button/index.less' // 復(fù)用OpenTinyVue的樣式文件export default function Button(props) {const {children,text,autofocus,round,circle,icon: Icon,size,nativeType = 'button'} = props// 通過common適配層的useSetup處理props和renderless無渲染層const { handleClick, state, tabindex, type, $attrs } = useSetup({props: { nativeType: 'button', resetTime: 1000, ...props },renderless})const className = ['tiny-button',type ? 'tiny-button--' + type : '',size ? 'tiny-button--' + size : '',state.disabled ? 'is-disabled' : '',state.plain ? 'is-plain' : '',round ? 'is-round' : '',circle ? 'is-circle' : ''].join(' ').trim()return (<buttonclassName={className}onClick={handleClick}disabled={state.disabled}autoFocus={autofocus}type={nativeType}tabIndex={tabindex}{...$attrs}>{Icon ? <Icon className={text || children ? 'is-text' : ''} /> : ''}<span>{children || text}</span></button>)
}

(Solid 路徑:packages/components/solid/src/button/src/pc.jsx):

import renderless from '@opentiny/renderless/button/solid' // renderless無渲染層
import { useSetup } from '@opentiny/solid-common' // 抹平不同框架的適配層
import '@opentiny/theme/button/index.less' // 復(fù)用OpenTinyVue的樣式文件export default function Button(props) {const {children,text,autofocus,round,circle,icon: Icon,size,nativeType = 'button'} = props// 通過common適配層的useSetup處理props和renderless無渲染層const { handleClick, state, tabindex, type, $attrs } = useSetup({props: { nativeType: 'button', resetTime: 1000, ...props },renderless})// 這里需要注意在模板中需要調(diào)用state函數(shù)才能正常使用solid的響應(yīng)式能力return (<buttonclassName={['tiny-button',type ? 'tiny-button--' + type : '',size ? 'tiny-button--' + size : '',state().disabled ? 'is-disabled' : '',state().plain ? 'is-plain' : '',round ? 'is-round' : '',circle ? 'is-circle' : ''].join(' ').trim()}onClick={handleClick}disabled={state().disabled}autoFocus={autofocus}type={nativeType}tabIndex={tabindex}{...$attrs}>{Icon ? <Icon className={text || children ? 'is-text' : ''} /> : ''}<span>{children || text}</span></button>)
}

到此大體上描述了跨框架組件庫的實現(xiàn)原理。

Demo演示

如果想快速查看效果和源碼,可以克隆我們提供的跨框架示例 Demo,具體操作步驟如下:

1、使用如下命令把演示 Demo 克隆到本地:

git clone https://github.com/opentiny/cross-framework-component.git

2、使用 pnpm 下載依賴:

pnpm i# 如果沒有pnpm需要執(zhí)行以下命令
npm i pnpm -g

3、工程目錄結(jié)構(gòu)分析

整個工程是基于 pnpm 搭建的多包 monorepo 工程,演示環(huán)境為無界微前端環(huán)境,整體工程的目錄架構(gòu)如下所示(本文主要介紹 packages/components 文件夾):

├─ package.json
├─ packages     
│  ├─ components              # 組件庫文件夾
│  │  ├─ react                 # react組件庫及其適配層
│  │  ├─ renderless         # 跨框架復(fù)用的跨框架無渲染邏輯層
│  │  ├─ solid                 # solid組件庫及其適配層
│  │  ├─ theme              # 跨框架復(fù)用的pc端樣式層
│  │  ├─ theme-mobile         # 移動端模板樣式層
│  │  ├─ theme-watch           # 手表帶模板樣式層
│  │  └─ vue                           # vue組件庫及其適配層
│  ├─ element-to-opentiny            # element-ui切換OpenTiny演示工程
│  ├─ home                              # 基于vue3搭建無界微前端主工程
│  ├─ react                            # 基于react搭建無界微前端子工程
│  ├─ solid                              # 基于solid搭建無界微前端子工程
│  ├─ vue2                              # 基于vue2搭建無界微前端子工程
│  └─ vue3                              # 基于vue3搭建無界微前端子工程
├─ pnpm-workspace.yaml
├─ README.md
├─ README.zh-CN.md
└─ setup.js

4、啟動本地的無界微前端本地服務(wù)

pnpm dev

啟動后會總共啟動5個工程,1個主工程和4個子工程,其中4個子工程分別引入了不同框架的組件庫,但是不同框架的組件庫復(fù)用了同一份交互邏輯代碼和樣式文件。

效果如下圖所示:

如何證明 Vue2、Vue3、React、Solid 都共用了一套邏輯了呢?

我們可以點擊按鈕然后會在控制臺打印,當(dāng)前復(fù)用邏輯層是來自哪個框架的:

可以看到不同框架代碼都已觸發(fā)。

感興趣的朋友可以持續(xù)關(guān)注我們TinyVue組件庫。也歡迎給 TinyVue 開源項目點個 Star 🌟支持下:https://github.com/opentiny/tiny-vue

關(guān)于 OpenTiny

圖片

OpenTiny 是一套企業(yè)級 Web 前端開發(fā)解決方案,提供跨端、跨框架、跨版本的 TinyVue 組件庫,包含基于 Angular+TypeScript 的 TinyNG 組件庫,擁有靈活擴展的低代碼引擎 TinyEngine,具備主題配置系統(tǒng)TinyTheme / 中后臺模板 TinyPro/ TinyCLI 命令行等豐富的效率提升工具,可幫助開發(fā)者高效開發(fā) Web 應(yīng)用。


歡迎加入 OpenTiny 開源社區(qū)。添加微信小助手:opentiny-official 一起參與交流前端技術(shù)~更多視頻內(nèi)容也可關(guān)注B站、抖音、小紅書、視頻號

OpenTiny 也在持續(xù)招募貢獻者,歡迎一起共建

OpenTiny 官網(wǎng):https://opentiny.design/

OpenTiny 代碼倉庫:https://github.com/opentiny/

TinyVue 源碼:https://github.com/opentiny/tiny-vue

TinyEngine 源碼: https://github.com/opentiny/tiny-engine

歡迎進入代碼倉庫 Star🌟TinyEngine、TinyVue、TinyNG、TinyCLI~

如果你也想要共建,可以進入代碼倉庫,找到 good first issue標(biāo)簽,一起參與開源貢獻~

http://aloenet.com.cn/news/40179.html

相關(guān)文章:

  • wap購物網(wǎng)站源碼公司如何在百度宣傳
  • 佛山建站佛山網(wǎng)頁設(shè)計seo是一種利用搜索引擎的
  • 網(wǎng)上做調(diào)查問卷的網(wǎng)站最近熱點新聞事件2023
  • bbs網(wǎng)站模板怎么創(chuàng)作自己的網(wǎng)站
  • 云南熱搜科技做網(wǎng)站不給源碼如何做網(wǎng)站seo
  • 濟南建設(shè)銀行網(wǎng)站杭州網(wǎng)站定制
  • 業(yè)務(wù)外包服務(wù)公司朝陽seo排名
  • 最好的javascript視頻seo技巧是什么
  • 網(wǎng)站開發(fā)公司成本是什么愛站權(quán)重
  • 國際購物平臺都有哪些重慶百度快速優(yōu)化
  • 安順網(wǎng)站開發(fā)網(wǎng)站推廣公司大家好
  • 成都網(wǎng)站建設(shè)小程序整站seo外包
  • 自建個網(wǎng)站怎么做農(nóng)產(chǎn)品推廣方案
  • 網(wǎng)站做網(wǎng)頁廣告公司經(jīng)營范圍
  • 做網(wǎng)站入什么科目網(wǎng)絡(luò)營銷公司好不好
  • 開發(fā)高端網(wǎng)站開發(fā)哈爾濱企業(yè)網(wǎng)站seo
  • 專業(yè)網(wǎng)站建設(shè)詳細方案南陽網(wǎng)站優(yōu)化公司
  • wordpress添加商品蘭州seo推廣
  • 婚紗攝影網(wǎng)站建設(shè)網(wǎng)站關(guān)鍵詞優(yōu)化建議
  • 營銷技巧五步推銷法北京核心詞優(yōu)化市場
  • 惠州營銷型網(wǎng)站建設(shè)杭州專業(yè)seo服務(wù)公司
  • 做網(wǎng)站必看的外國書籍萬能引流軟件
  • 做網(wǎng)站應(yīng)該用多少分辨率志鴻優(yōu)化設(shè)計官網(wǎng)
  • 天津網(wǎng)約車優(yōu)化百度百科
  • 榆林網(wǎng)站建設(shè)天津谷歌優(yōu)化
  • wordpress分類靜態(tài)專業(yè)培訓(xùn)seo的機構(gòu)
  • 形象墻設(shè)計東莞seo靠譜
  • 備案 網(wǎng)站名稱 重復(fù)百度指數(shù)移動版
  • 帝國手機網(wǎng)站模板我想在百度發(fā)布信息
  • 網(wǎng)站數(shù)據(jù)分析工具有哪些網(wǎng)站推廣seo是什么