在上篇中,我們介紹瞭如何通過設定runtimeCompiler為true,在Vue中實現了動態建立電子表格元件。想了解具體內容可看點選檢視使用VUE元件建立SpreadJS自定義單元格(一)。
但是在實際場景中,我們可能只需要動態建立VUE元件,而元件的template內容並不需要動態載入。面對這種情況, autoComplete就是一個很典型使用場景。
autoComplete可以讓我們自由將任何接受接收到的輸入內容轉化成含有標籤\<input\>、\<textarea\>和帶有contenteditable屬性的元素。在完成鍵盤輸入時,外掛開始搜尋匹配的條目並顯示可供選擇的值列表。通過輸入更多字元,使用者可以過濾列表以更好地匹配。
在前端電子表格中,我們可以直接用它對內容進行選擇,例如輸入文章的標籤或輸入地址簿中的電子郵件地址。;自動完成功能還可用於填充相關資訊,例如輸入城市名稱和獲取郵政編碼。而現在想在純前端表格中實現這一功能,我們就可以將動態建立的Component固化,按需import 然後掛載即可。
這樣就簡化了我們在上篇中提到的,需要開啟runtimeCompiler來實現了。
接下來為大家介紹具體做法:
- 封裝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其他強大功能感興趣,可以實際來體驗一下。