題主描述的這個問題,其實在前端表格領域是最常見的需求之一。這里簡單羅列幾點表格組件中最常用的功能:
- 怎樣讓表格樣式豐富多變的同時,又能實現數據驅動?
- 怎樣給單元格中優雅地嵌入諸如checkbox、button、autocomplete、超鏈接,甚至圖片、圖表、二維碼、富文本等前端常見的元素?
- 怎樣高效地實現排序、篩選、分組、樹、數據校驗,甚至數據匯總等能力?
以上是不是還能命中幾個題目沒提到的潛在需求呢?
要設計表格組件,這些問題都不得不考慮,下面我以目前市場上比較成熟的表格組件SpreadJS為例,談一談部分需求的設計思路。SpreadJS是純前端的表格控件,本身的實現不依賴任何插件、框架或后端庫,比較能說明問題:
怎樣讓表格樣式豐富多變的同時,又能實現數據驅動?
SpreadJS采用了數據與視圖分離、并與數據源綁定的設計。跟樣式相關的內容保存在單元格屬性中,與數據源(JSON)分離開,通過數據綁定關系保存數據和單元格位置的映射。渲染引擎再根據這些信息,實現數據展示、交互的能力:
表格模板與數據源雙向綁定
可以實際操作一下SpreadJS的表格綁定功能。
通過這樣的設計,數據驅動所需的元素就都有了,接下來實現渲染內容隨數據源變更、新數據追加推送、條件改變、公式計算等因素聯動都已不是難題。
怎樣給單元格中優雅地嵌入諸如checkbox、button、autocomplete、超鏈接,甚至圖片、圖表、二維碼、富文本等前端常見的元素?
SpreadJS是采用Canvas渲染的表格區域,當需要修改單元格內容時,會響應操作事件,創建一個input元素在單元格上,填寫后執行回填,將數據返回數據源。渲染層把基礎功能進行了封裝,并暴露了原型接口。
這樣的設計為擴展和豐富輸入形式提供了可能。比如我們可以定義,當雙擊單元格時,不彈出input,而是彈出Autocomplete組件,我們要做的只是重寫“彈出input”的方法即可。如圖:
SpreadJSAutoComplete
模態窗同理:
SpreadJS模態窗
參考示例:SpreadJS自定義單元格——模態窗
怎樣高效地實現排序、篩選、分組、樹、數據校驗,甚至數據匯總等能力
實際上有了以上兩個案例的支撐,不難理解在這幾個需求中,基本上都是對數據源本身的操作。主要不斷地實現同一個接口(JavaScript里通過繼承或重寫prototype),可以優雅高效地實現。
相關資料:
SpreadJS官方主頁SpreadJS產品文檔在線Excel編輯器