使用VUE元件建立SpreadJS自定義單元格(二)

葡萄城技術團隊發表於2022-01-12

在上篇中,我們介紹瞭如何通過設定runtimeCompiler為true,在Vue中實現了動態建立電子表格元件。想了解具體內容可看點選檢視使用VUE元件建立SpreadJS自定義單元格(一)

但是在實際場景中,我們可能只需要動態建立VUE元件,而元件的template內容並不需要動態載入。面對這種情況, autoComplete就是一個很典型使用場景。

autoComplete可以讓我們自由將任何接受接收到的輸入內容轉化成含有標籤\<input\>、\<textarea\>和帶有contenteditable屬性的元素。在完成鍵盤輸入時,外掛開始搜尋匹配的條目並顯示可供選擇的值列表。通過輸入更多字元,使用者可以過濾列表以更好地匹配。

前端電子表格中,我們可以直接用它對內容進行選擇,例如輸入文章的標籤或輸入地址簿中的電子郵件地址。;自動完成功能還可用於填充相關資訊,例如輸入城市名稱和獲取郵政編碼。而現在想在純前端表格中實現這一功能,我們就可以將動態建立的Component固化,按需import 然後掛載即可。

這樣就簡化了我們在上篇中提到的,需要開啟runtimeCompiler來實現了。

接下來為大家介紹具體做法:

  1. 封裝AutoComplete元件封裝的元件
  <div>
    <el-autocomplete
      :style="cellStyle"
      popper-class="my-autocomplete"
      v-model="text"
      :fetch-suggestions="querySearch"
      placeholder="請輸入內容"
      :popper-append-to-body="false"
      value-key="name"
      @select="handleSelect"
    >
      <i
        class="el-icon-edit el-input__icon"
        slot="suffix"
        @click="handleIconClick"
      >
      </i>
      <template slot-scope="{ item }">
        <div class="name">{{ item.name }}</div>
        <span class="addr">{{ item.phone }}</span>
      </template>
    </el-autocomplete>
  </div>
</template>
  <script>

import DataService from '../static/dataService'

export default {
    props: ['text','cellStyle'],
    mounted() {
        this.items = DataService.getEmployeesData();
    },
    methods: {
        querySearch(queryString, cb) {
            var items = this.items;
            var results = queryString ? items.filter(this.createFilter(queryString)) : items;
            // 無法設定動態內容的位置,可以動態新增gcUIElement
            // setTimeout(() => {
            //   let popDiv = document.getElementsByClassName("my-autocomplete")[0];
            //   if(popDiv){
            //     popDiv.setAttribute("gcUIElement", "gcEditingInput");
            //   }
            // }, 500);
            // 呼叫 callback 返回建議列表的資料
            cb(results);
        },
        createFilter(queryString) {
            return (restaurant) => {
            return (restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
            };
        },
        handleSelect(item) {
            console.log(item);
        },
        handleIconClick(ev) {
            console.log(ev);
        }
    }
}
</script>

需要注意一下幾點

  • 元件提供text(或者value)屬性,用於對應單元格需要編輯的值,元件中如果不是用model雙向繫結,操作後需要主動更新text
  • 提供cellStyle,使用者CellType,根據單元格大小控制元件的大小
  • 元件如果有注入的DOM元素不在template div內部,需要新增gcUIElement屬性,原因在上一篇有詳細說明

2、autoComplete直接掛載元件,不再需要額外動態宣告

import AutoComplete from '../components/AutoComplete'

AutoComplateCellType.prototype.activateEditor = function (editorContext, cellStyle, cellRect, context) {
    let width = cellRect.width > 180 ? cellRect.width : 180;
    if (editorContext) {
       // create component constructor
       const AutoCompleteCtor = Vue.extend(AutoComplete);
        this.vm = new AutoCompleteCtor({
        propsData: {
          cellStyle: {width: width+"px"}
        }
      }).$mount(editorContext.firstChild);
    }
};

其餘程式碼不變,這樣不僅不需要runtimeCompiler,程式碼可維護行也提高了。

這系列兩篇文章詳細為大家介紹使用兩種不同的方式,解決由於框架生命週期以及自定義單元格渲染邏輯的問題,目前無法直接在框架頁面下直接通過template的方式使用框架下的元件的問題。而我們使用Vue順利解決了這個問題,並在第二種方式中進行了優化,有效提高程式碼的易維護性。

後續我們也會從其他角度,為大家帶來更有有趣的內容~如果你對純前端電子表格SpreadJS其他強大功能感興趣,可以實際來體驗一下。

相關文章