作为近五年都冲在热门框架排行榜首的Vue,大家肯定会学到的一部分就是组件的应用。前端开发的模块化,能够让代码逻辑更加简略清晰,我的项目的扩展性大大增强。对于Vue而言,模块化的体现集中在组件之上,以组件为单位实现模块化。

通常咱们应用组件的形式是,在实例化Vue对象之前,通过Vue.component办法来注册全局的组件。

// 通知Vue,当初须要组件 todo-item,配置如下,蕴含props和templateVue.component('todo-item', {  props: ['todo'],  template: '<li>{{ todo.text }}</li>'}) // 实例化一个Vue对象,挂载在#app-7元素下,定它的属性,数组groceryList var app7 = new Vue({  el: '#app-7',  data: {    groceryList: [      { text: 'Vegetables' },      { text: 'Cheese' },      { text: 'Whatever else humans are supposed to eat' }    ]  }})

在泛滥组件之中,作为办公必备的电子表格,在前端组件中也占据了重要位置。除了以表格的模式展现数据,电子表格还有一个十分重要的性能,即反对自定义性能拓展和各种定制化的数据展现成果,比方checkbox,Radio button等;还须要实现当单元格进入编辑状态时,应用下拉菜单(或其余输出控件)输出的成果。咱们称之为"自定义单元格",一种嵌入组件内的组件。SpreadJS目前领有8种下拉列表,在关上列表之前,咱们只须要在单元格款式中设置选项数据。 你能够参考以下代码应用列表:

在线体验地址

  // The way of click the dropdown icon to open list.    var style = new GC.Spread.Sheets.Style();   style.cellButtons = [       {           imageType: GC.Spread.Sheets.ButtonImageType.dropdown,           command: "openList",           useButtonStyle: true,       }   ];   style.dropDowns = [       {           type: GC.Spread.Sheets.DropDownType.list,           option: {               items: [                   {                       text: 'item1',                       value: 'item1'                   },                   {                       text: 'item2',                       value: 'item2'                   },                   {                       text: 'item3',                       value: 'item3'                   },                   {                       text: 'item4',                       value: 'item4'                   }               ],           }       }   ];   sheet.setText(2, 1, "Vertical text list");   sheet.setStyle(3, 1, style);   // The way open list with command rather then clicking the dropdown button.   spread.commandManager().execute({cmd:"openList",row:3,col:1,sheetName:"Sheet1"});

前端电子表格诚然好用, 但因为框架生命周期以及自定义单元格渲染逻辑的问题,目前的技术手段无奈间接在框架页面下间接通过template的形式应用框架下的组件。在之前的内容中,咱们提到了能够应用Svelte应用Web Conmponents封装其余组件能够应用的组件。
除了下面提到的办法之外,咱们如果想在Vue环境下应用自定义单元格,能够思考应用持动静渲染的形式来创立和挂载组件,从而将组件注入自定义单元格。

上面为大家演演示如何在VUE我的项目中,创立一个应用VUE 组件的自定义单元格。

实际

首先,在我的项目中开启运行时加载,在vue.config.js中增加runtimeCompiler: true。

    module.exports = {        devServer: {            port: 3000        },        <font color="#ff0000">runtimeCompiler: true</font>      }

援用ElementUI,须要留神要把element 的css援用放在APP import前,这样批改款式,能力笼罩原有我的项目内容。

import Vue from 'vue'import ElementUI from 'element-ui';import 'element-ui/lib/theme-chalk/index.css';import App from './App.vue'import router from './router'Vue.use(ElementUI);new Vue({  el: '#app',  router,  render: h => h(App)})Vue.config.productionTip = false

创立AutoComplateCellType,具体代码如下,须要留神几点。
1、自定义的元素,须要增加gcUIElement属性,如果元素或者其父元素没有该属性,点击创立的组件便会间接退出编辑状态无奈编辑。
对于ElementUI 的autocomplete,默认下拉选项内容是注入到body中的,须要给组件模板中设置:popper-append-to-body="false",让弹出的下拉选项在gcUIElement的Div中渲染。
如果应用其余组件没有相似选项,也能够跟进理论状况在弹出时在增加gcUIElement属性。
2、应用动静挂载组件的 this.vm 设置和获取单元格的值。
3、在deactivateEditor中销毁组件。

import Vue from 'vue'import * as GC from "@grapecity/spread-sheets"import DataService from './dataService'function AutoComplateCellType() {}AutoComplateCellType.prototype = new GC.Spread.Sheets.CellTypes.Base();AutoComplateCellType.prototype.createEditorElement = function (context, cellWrapperElement) {  cellWrapperElement.style.overflow = 'visible'  let editorContext = document.createElement("div")  editorContext.setAttribute("gcUIElement", "gcEditingInput");  let editor = document.createElement("div");  // 自定义单元格中editorContext作为容器,须要在创立一个child用于挂载,不能间接挂载到editorContext上  editorContext.appendChild(editor);  return editorContext;}AutoComplateCellType.prototype.activateEditor = function (editorContext, cellStyle, cellRect, context) {    let width = cellRect.width > 180 ? cellRect.width : 180;    if (editorContext) {                // 动态创建VUE 组件并挂载到editor        const AutoCompleteComponent = {            props: ['text','cellStyle'],            template: `<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>`,            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);                }            }        };      // create component constructor      const AutoCompleteCtor = Vue.extend(AutoCompleteComponent);      this.vm = new AutoCompleteCtor({        propsData: {          cellStyle: {width: width+"px"}        }      }).$mount(editorContext.firstChild);    }    return editorContext;};AutoComplateCellType.prototype.updateEditor = function(editorContext, cellStyle, cellRect) {    // 给定一个最小编辑区域大小    let width = cellRect.width > 180 ? cellRect.width : 180;    let height = cellRect.height > 40 ? cellRect.height : 40;    return {width: width, height: height};};AutoComplateCellType.prototype.getEditorValue = function (editorContext) {    // 设置组件默认值    if (this.vm) {        return this.vm.text;    }};AutoComplateCellType.prototype.setEditorValue = function (editorContext, value) {    // 获取组件编辑后的值    if (editorContext) {      this.vm.text = value;    }};AutoComplateCellType.prototype.deactivateEditor = function (editorContext, context) {    // 销毁组件    this.vm.$destroy();    this.vm = undefined;};export {AutoComplateCellType};

成果如图:

一个完满的单元格新鲜出炉~

这里介绍的形式只是诸多实现计划的一种。如果大家有其余更好的想法办法,欢送一起探讨 ~

如果你对其余更多前端电子表格中乏味性能感兴趣,能够查看 SpreadJS更多实例演示

咱们也会在之后,继续为大家带来更多带来更多庄重和乏味的内容 ~