自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

低代碼平臺(tái)的屬性面板該如何設(shè)計(jì)?

開發(fā) 架構(gòu)
今天我們來探討的是選中畫布中指定組件,右側(cè)屬性面板展示與該組件關(guān)聯(lián)的表單,修改右側(cè)表單,畫布中的組件樣式會(huì)同步更新。

我們先對(duì)整個(gè)平臺(tái)的設(shè)計(jì)做一下簡(jiǎn)單回顧:

這里是我平時(shí)自己維護(hù)的一個(gè)低代碼平臺(tái),技術(shù)棧是Vue。后續(xù)的分享也是基于該平臺(tái)的一些具體實(shí)現(xiàn)細(xì)節(jié)展開

和市面上大部分可視化搭建系統(tǒng)基本類似。左側(cè)對(duì)應(yīng)組件區(qū)域,中間是畫布區(qū)域,右側(cè)是屬性區(qū)域。

大致操作流程就是拖動(dòng)左側(cè)的組件到中間的畫布,選中組件,右側(cè)屬性面板就會(huì)展示與該組件關(guān)聯(lián)的屬性。編輯右側(cè)屬性,畫布中對(duì)應(yīng)的組件樣式就會(huì)同步更新。頁(yè)面拼接完成,可通過預(yù)覽按鈕進(jìn)行頁(yè)面預(yù)覽。預(yù)覽無(wú)誤,即可通過發(fā)布按鈕進(jìn)行活動(dòng)的發(fā)布。

當(dāng)然其中也有撤銷、重做等操作。

今天我們來探討的是選中畫布中指定組件,右側(cè)屬性面板展示與該組件關(guān)聯(lián)的表單,修改右側(cè)表單,畫布中的組件樣式會(huì)同步更新。

首先來看一下編輯器全局的數(shù)據(jù)結(jié)構(gòu):

const editorModule = {
state: {
components: [],
currentElement: "",
},
mutations: {
addComponentToEditor(state, component) {
component.id = uuidv4();
state.components.push(component);
},
setActive(state, id) {
state.currentElement = id;
},
updateComponent(state, { id, key, value, isProps }) {
const updatedComponent = state.components.find(
(component) => component.id === (id || state.currentElement)
);
if (updatedComponent) {
if (isProps) {
updatedComponent.props[key] = value;
} else {
updatedComponent[key] = value;
}

}
},
},
getters: {
getCurrentElement: (state) => {
return state.components.find(
(component) => component.id === state.currentElement
);
},
}
}

editor中存儲(chǔ)了components(所有組件數(shù)據(jù))和currentElement(當(dāng)前選中的組件信息)。

當(dāng)點(diǎn)擊左側(cè)業(yè)務(wù)組件,會(huì)觸發(fā)業(yè)務(wù)組件的點(diǎn)擊事件,進(jìn)而觸發(fā)addComponentToEditor,向editor store的components添加一條組件。我們這里添加一個(gè)普通的文本組件,然后看下他的初始props:

{
actionType: "",
backgroundColor: "",
borderColor: "#000",
borderRadius: "0",
borderStyle: "none",
borderWidth: "0",
boxShadow: "0 0 0 #000000",
color: "#000000",
fontFamily: "",
fontSize: "14px",
fontStyle: "normal",
fontWeight: "normal",
height: "36px",
left: "97.5px",
lineHeight: "1",
opacity: 1,
paddingBottom: "0px",
paddingLeft: "0px",
paddingRight: "0px",
paddingTop: "0px",
position: "absolute",
right: "0",
tag: "p",
text: "正文內(nèi)容",
textAlign: "center",
textDecoration: "none",
top: "232px",
url: "",
width: "125px"
}

當(dāng)在畫布中選中該文本組件時(shí),就會(huì)觸發(fā)setActive,更新currentElement。(通過getCurrentElement可以獲取到當(dāng)前正在被操作的組件)。

這個(gè)時(shí)候,應(yīng)該如何添加屬性和表單的基礎(chǔ)對(duì)應(yīng)關(guān)系呢?

這個(gè)也是本篇文章的主題:低代碼平臺(tái)的屬性面板該如何設(shè)計(jì)?

1.屬性面板應(yīng)該包含哪些內(nèi)容?

我們的Choba Lego平臺(tái)中有很多業(yè)務(wù)組件,而每個(gè)富交互的頁(yè)面都是由這些業(yè)務(wù)組件堆積拼裝而成,而每個(gè)組件都包含了一些通用屬性和組件特有屬性,這些屬性反映了當(dāng)前組件的各種狀態(tài),非常復(fù)雜。

對(duì)于單獨(dú)的組件來說,屬性面板應(yīng)該是語(yǔ)義化的,無(wú)論是開發(fā)還是非開發(fā)同學(xué),通過屬性面板的操作區(qū),就可以直觀的知道一個(gè)組件的屬性是什么,應(yīng)該如何使用和編輯。

那么屬性面板應(yīng)該包含哪些內(nèi)容呢?

  • label:屬性名稱。這個(gè)可以顯式的告訴具體的屬性的作用,比如元素的寬高、邊框、背景顏色等。
  • description:屬性的描述信息。對(duì)于一些特殊屬性,可能第一下通過label并不能直觀的識(shí)別屬性的含義,添加描述信息可以進(jìn)行詳細(xì)的闡述。
  • content:屬性渲染器。用戶可以基于此實(shí)現(xiàn)對(duì)屬性的修改。最常見的有 textarea、input、select 等。
  • error:屬性校驗(yàn)信息。當(dāng)用戶輸入了不合法的或者類型不匹配時(shí),可給予適當(dāng)?shù)腻e(cuò)誤提示信息。

通過以上描述,我們會(huì)發(fā)現(xiàn),這其實(shí)就是我們常用的表單。

2.屬性和組件的映射關(guān)系

其實(shí)上面的四塊內(nèi)容,內(nèi)容渲染器應(yīng)該是最復(fù)雜的。采用合適的渲染器來渲染對(duì)應(yīng)的屬性才是最重要的。

但存在一些場(chǎng)景,一些屬性可以被多種渲染器來渲染,像字體大小-fontSize,既可以用input-number,又可以用slider。那么這種場(chǎng)景應(yīng)該如何選用最合適的渲染器呢?其實(shí)這種我覺得完全可以看開發(fā)者和使用者的綜合意愿,沒有絕對(duì)的對(duì)錯(cuò)之分。

對(duì)應(yīng)上面組件的props信息,我們可以對(duì)這些屬性做一些歸類,那歸類的標(biāo)準(zhǔn)又是什么呢?我認(rèn)為應(yīng)該把屬性與js中的數(shù)據(jù)類型做一下映射,然后在具體的分類下選用合適的渲染器。

我們知道在JavaScript中,一共有七種數(shù)據(jù)類型,字符串(String)、數(shù)字(Number)、布爾(Boolean)、空(Null)、未定義(Undefined)、Symbol和對(duì)象(Object)。其中對(duì)象類型包括:數(shù)組(Array)、函數(shù)(Function)、還有兩個(gè)特殊的對(duì)象:正則(RegExp)和日期(Date)。

這里面的空(Null)、未定義(Undefined)、Symbol和正則(RegExp)在渲染器中基本用不到。

我們先來看一下字符串(String)、數(shù)字(Number)、布爾(Boolean)和日期(Date)可能渲染的方式:

字符串(String)

渲染器類型

組件

input

textarea


數(shù)字(Number)

渲染器類型

組件

input-number

slider

布爾(Boolean)

渲染器類型

組件

switch

日期(Date)

渲染器類型

組件

date

除了這幾種,還有對(duì)象(Object)、數(shù)組(Array)、函數(shù)(Function)。

對(duì)象和數(shù)組屬于較復(fù)雜的類型,不過我們可以把它抽象為多層級(jí)(可以理解為嵌套)的基礎(chǔ)數(shù)據(jù)類型:

渲染器類型

組件

array

像數(shù)組一般是用下拉框的形式來展現(xiàn)。

至于函數(shù)(Function),可以采用預(yù)定義的形式:

渲染器類型

組件

function

到這里,不難想到,我們要維護(hù)一個(gè)屬性和表單組件的對(duì)應(yīng)關(guān)系。屬性對(duì)應(yīng)上面的key,像borderColor、text、width、fontFamily這些,那組件呢?組件其實(shí)就是對(duì)屬性的具體呈現(xiàn),像width可以用數(shù)字輸入框、text可以用普通輸入框,但是對(duì)于一些比較復(fù)雜的特性,我們自己去實(shí)現(xiàn)這些組件,就顯得捉襟見肘了,這個(gè)時(shí)候我們就可以考慮和現(xiàn)有的組件庫(kù)做一下結(jié)合了(這里我采用的是Ant Design Vue)。

那么這樣,屬性prop和component基礎(chǔ)的對(duì)應(yīng)關(guān)系就有了:

const mapPropsToComponents = {
text: {
component: "a-input",
},
width: {
component: "a-input-number",
},
borderWidth: {
component: "a-slider",
},
// ...
}

但這只是滿足了常規(guī)的基礎(chǔ)組件設(shè)計(jì),像一些獨(dú)有的屬性或者基礎(chǔ)組件不能滿足的情況,我們需要對(duì)其做一定擴(kuò)展:

渲染器類型

組件

upload

color-picker

上面提到的上傳組件和顏色選擇組件是需要我們單獨(dú)去實(shí)現(xiàn)的。

3.屬性分類

僅僅有屬性和組件的對(duì)應(yīng)關(guān)系還不夠,每個(gè)組件都會(huì)對(duì)應(yīng)大量的表單屬性,對(duì)他們按功能做一下歸類還是很有必要的。

基本屬性也就是每個(gè)組件獨(dú)有的一些屬性,除基礎(chǔ)屬性以外,剩余的就是所有組件的通用屬性了。

屬性分類雖然是一個(gè)比較簡(jiǎn)單的實(shí)現(xiàn),但是能對(duì)使用者帶來很大的收益,可以清晰的知道每種屬性更改對(duì)組件帶來的不同影響。

4.更新表單將數(shù)據(jù)更新到屬性

有了上面的準(zhǔn)備,最重要的一步來了,那就是選中組件,屬性面板展示該組件關(guān)聯(lián)的表單屬性,修改屬性,組件數(shù)據(jù)會(huì)同步更新。

以我以往的經(jīng)驗(yàn)來看:表單組件在設(shè)計(jì)時(shí),有兩點(diǎn)是必須的:

  • 表單初始值(默認(rèn)value),供初始展示使用
  • 表單屬性更改的事件(默認(rèn)為 change)

對(duì)于不同的表單,初始值和屬性更改后,參數(shù)的處理是不一樣的:

  • 像高度、寬度這種數(shù)字類型的,傳入表單時(shí)應(yīng)保證是number(24)類型,屬性更改后,事件參數(shù)應(yīng)該是string(24px)類型的
  • 字體加粗與否、傾斜與否、加下劃線與否,傳入表單時(shí)應(yīng)保證是boolean(true/false)類型,屬性更改后,事件參數(shù)應(yīng)該是string(bold/normal)類型的

所以給每一個(gè)屬性在傳入表單和事件更改后都要加一個(gè)額外的轉(zhuǎn)化函數(shù)去處理值:

  • initialValueConvert
  • eventChangeValueConvert

還有對(duì)屬性進(jìn)行賦值時(shí),不是所有的表單控件接收的都是value,像checkbox就是checked,這種單獨(dú)抽一個(gè)屬性valueProp去控制即可。

其次,像上面提到的父子層級(jí)的渲染,除了component還要多加一個(gè)subComponent。

上面配置完成后,屬性和組件的對(duì)應(yīng)關(guān)系就有了:

const mapPropsToComponents = {
width: {
component: "a-input-number",
eventName: "change",
valueProp: "value",
initialValueConvert: (v) => (v ? parseInt(v) : ""),
eventChangeValueConvert: (e) => (e ? `${e}px` : ""),
text: "寬度",
},
textAlign: {
component: "a-radio-group",
subComponent: "a-radio-button",
eventName: "change",
valueProp: "value",
eventChangeValueConvert: (e) => e.target.value,
text: "對(duì)齊",
options: [
{ value: "left", text: "左" },
{ value: "center", text: "中" },
{ value: "right", text: "右" },
],
},
// ...
}

我們的數(shù)據(jù)始終保持自上而下的順序,也就是說表單更新最終要反射回到總體的 store 當(dāng)中去。這個(gè)時(shí)候我們?cè)趯?duì)應(yīng)的組件當(dāng)中發(fā)射出一個(gè)事件(change),當(dāng) change 發(fā)生的時(shí)候,我們能夠知道是哪個(gè)元素的哪個(gè)屬性,以及新的值是什么,我們就用這些信息更新這個(gè)值,這樣 store完成更新,元素的 props 發(fā)生更新,那么整個(gè)數(shù)據(jù)流動(dòng)就完成了。

5.參考鏈接

https://mp.weixin.qq.com/s/u2AkeXiL0pi4799ccjR_Tg

責(zé)任編輯:武曉燕 來源: 前端森林
相關(guān)推薦

2022-04-21 12:00:13

低代碼平臺(tái)組件代碼

2021-10-21 06:52:18

低代碼無(wú)代碼開發(fā)

2023-03-31 13:53:00

低代碼平臺(tái)選型

2021-07-26 09:00:00

開發(fā)編程工具

2020-09-03 10:06:53

低代碼平臺(tái)編碼低代碼

2021-09-24 16:30:28

無(wú)代碼低代碼機(jī)器學(xué)習(xí)

2021-09-26 09:48:55

低代碼

2022-08-28 21:41:19

低代碼/無(wú)代碼

2021-05-31 19:04:50

低代碼平臺(tái)低代碼開發(fā)

2022-06-08 08:23:18

低代碼無(wú)代碼網(wǎng)絡(luò)安全

2020-09-08 12:51:35

低代碼開 發(fā)代碼平臺(tái)

2023-08-29 15:14:32

2022-06-30 07:48:06

Dooring低代碼零代碼

2021-04-08 15:07:51

低代碼開發(fā)平臺(tái)

2022-07-27 09:29:13

低代碼物聯(lián)網(wǎng)

2021-07-05 12:36:22

低代碼編程語(yǔ)言開發(fā)平臺(tái)

2023-11-23 08:07:31

Css?Web?

2022-12-22 08:51:40

vivo代碼

2023-04-03 11:01:26

低代碼平臺(tái)場(chǎng)景

2023-03-01 18:12:16

平臺(tái)架構(gòu)設(shè)計(jì)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)