中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

漢網(wǎng)可以建設(shè)網(wǎng)站不網(wǎng)站建設(shè)制作公司

漢網(wǎng)可以建設(shè)網(wǎng)站不,網(wǎng)站建設(shè)制作公司,天河網(wǎng)站建設(shè)信科網(wǎng)絡(luò),陜西網(wǎng)站建設(shè)托管本文由 TinyVue 組件庫核心成員鄭志超分享,首先分享了實現(xiàn)跨框架組件庫的必要性,同時通過演示Demo和實際操作向我們介紹了如何實現(xiàn)一個跨框架的組件庫。 前言 前端組件庫跨框架是什么? 前端組件庫跨框架是指在不同的前端框架(如…

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

前言

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

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

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

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

第一個階段:

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

第二個階段:

2021年初,當時 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ā),并且完全復用了 renderless 無渲染層的邏輯。

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

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

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

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

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

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

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

如何開發(fā)

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

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

因為 TinyVue 組件庫已具備同時兼容 Vue2 和 Vue3 的能力,所以本文以 React 和 Solid 為例,介紹如何開發(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ù)邏輯,然后復用這部分邏輯。

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 標簽的 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標簽的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標簽的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 導出的 api 進行適配 React 的處理,以下這兩段代碼主要是分別從三個方面來處理這個問題。

  • 抹平響應(yīng)式數(shù)據(jù): 為 React(Solid 本身具有響應(yīng)式能力)提供響應(yīng)式數(shù)據(jù)能力,從而可以復用 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 為例,采用無渲染邏輯的復用方式

首先看下 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 入口文件,它負責去對接 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ù)被重復執(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:當點擊按鈕時會觸發(fā) handleClick 內(nèi)層函數(shù),如果用戶傳遞的重置時間大于零,則在點擊之后會設(shè)置按鈕的 disabled 屬性為 true 禁用按鈕,并在重置時間后解除按鈕禁用,然后打印出當前邏輯觸發(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' // 復用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' // 復用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         # 跨框架復用的跨框架無渲染邏輯層
│  │  ├─ solid                 # solid組件庫及其適配層
│  │  ├─ theme              # 跨框架復用的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個子工程分別引入了不同框架的組件庫,但是不同框架的組件庫復用了同一份交互邏輯代碼和樣式文件。

效果如下圖所示:

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

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

可以看到不同框架代碼都已觸發(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標簽,一起參與開源貢獻~

http://www.risenshineclean.com/news/59046.html

相關(guān)文章:

  • 蘇州網(wǎng)絡(luò)銷售公司寧波seo咨詢
  • 快速建立平臺網(wǎng)站開發(fā)網(wǎng)站模板設(shè)計seo網(wǎng)站關(guān)鍵詞優(yōu)化工具
  • 中國監(jiān)理建設(shè)協(xié)會網(wǎng)站今日重大軍事新聞
  • jsp網(wǎng)站購物車怎么做網(wǎng)站建設(shè)方案設(shè)計書
  • 網(wǎng)頁制作中網(wǎng)站名稱怎么做谷歌查詢關(guān)鍵詞的工具叫什么
  • 宮免費網(wǎng)站網(wǎng)絡(luò)服務(wù)合同
  • 常德網(wǎng)站設(shè)計公司寧波百度關(guān)鍵詞推廣
  • 煙臺專門做網(wǎng)站的公司網(wǎng)站設(shè)計方案
  • 網(wǎng)站備案 費用百度上怎么打廣告宣傳
  • 如何分析競爭對手的網(wǎng)站開網(wǎng)店3個月來虧了10萬
  • 做網(wǎng)站去哪好百度網(wǎng)站提交入口
  • 找人做網(wǎng)站維護多少錢代發(fā)qq群發(fā)廣告推廣
  • 爬取數(shù)據(jù)做網(wǎng)站網(wǎng)站seo內(nèi)容優(yōu)化
  • 做企業(yè)網(wǎng)站的意義優(yōu)化網(wǎng)站排名技巧
  • 做網(wǎng)站搞笑口號中國國家培訓網(wǎng)
  • 下載免費軟件哪個網(wǎng)站好百度提交入口的網(wǎng)址
  • 杭州網(wǎng)站建設(shè)案例網(wǎng)址查詢?nèi)肟?/a>
  • 自制個人網(wǎng)站網(wǎng)站seo收錄工具
  • 獨立網(wǎng)站建設(shè)推廣有什么好方法
  • 學校建設(shè)網(wǎng)站的結(jié)論網(wǎng)站搜索優(yōu)化價格
  • 品牌網(wǎng)站建設(shè)磐石網(wǎng)絡(luò)優(yōu)等好搜搜索
  • 國內(nèi)外公司網(wǎng)站差異安卓優(yōu)化大師hd
  • 網(wǎng)上購物有哪些網(wǎng)站?seo根據(jù)什么具體優(yōu)化
  • b2c電子商務(wù)網(wǎng)站源碼網(wǎng)絡(luò)推廣深圳有效渠道
  • 上海網(wǎng)站建設(shè)方法保定百度seo公司
  • 境外企業(yè)網(wǎng)站推廣網(wǎng)絡(luò)服務(wù)有限公司
  • 順德網(wǎng)站建設(shè)價格國家認可的教育培訓機構(gòu)
  • 網(wǎng)頁策劃案什么是seo推廣
  • 簡單的j網(wǎng)站建設(shè)方案書磁力庫
  • 網(wǎng)站開發(fā)掙錢嗎百度學術(shù)官網(wǎng)入口