教你如何使用VUE组件创建SpreadJS自定义单元格

SpreadJS纯前端表格控件是基于HTML5的Java电子表格和网格功能控件,适用于.NET、Java和移动端等各平台在线编辑类Excel功能的表格程序开发。

本文介绍了如何使用VUE组件创建SpreadJS自定义单元格功能。

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

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

// 告诉Vue,现在需要组件 todo-item,配置如下,包含props和template
Vue.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更多实例演示

到此这篇关于教你如何使用VUE组件创建SpreadJS自定义单元格的文章就介绍到这了,更多相关vue SpreadJS自定义单元格内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • antd vue table跨行合并单元格,并且自定义内容实例

    ant-design-vue版本:~1.3.8 需求:表格实现跨行合并,并且在合并完的单元格中显示图片 效果图: 源码: export default { data() { return { pic95: require('@/assets/produit/95.png'), pic99: require('@/assets/produit/99.png'), varTable: { cloumns: [ { title: '置信度', dataIndex: 'confidence ', cla

  • 教你如何使用VUE组件创建SpreadJS自定义单元格

    SpreadJS纯前端表格控件是基于HTML5的Java电子表格和网格功能控件,适用于.NET.Java和移动端等各平台在线编辑类Excel功能的表格程序开发. 本文介绍了如何使用VUE组件创建SpreadJS自定义单元格功能. 作为近五年都冲在热门框架排行榜首的Vue,大家一定会学到的一部分就是组件的使用.前端开发的模块化,可以让代码逻辑更加简单清晰,项目的扩展性大大加强.对于Vue而言,模块化的体现集中在组件之上,以组件为单位实现模块化. 通常我们使用组件的方式是,在实例化Vue对象之前,通

  • Vue组件创建和传值的方法

    ## 创建组件的3种方法 # 第一种:  + Vue.extend()函数返回一个组件的构造器,里面包含一个参数,参数是对象,对象里面是一些配置项 + Vue.component()函数利用Vue.extend()返回的构造器创建一个组件的实例,有两个参数.; 参数1:组件名字,参数2:组件构造器 注意:       模板template中只能有一个根节点 组建的名字采用驼峰命名的话,使用时,就要加上"-"; 例如:组件名字indexA-->index-a; ## 第二种:  +

  • vue组件创建的三种方式小结

    1.使用Vue.extend创建全局的Vue组件 //1.1 使用vue.extend创建组件 var com1 = Vue.extend({ //通过template属性指定组件要展示的html结构 template : "<h3>使用vue.extend创建的组件</h3>" }) //1.2使用Vue.component('组件名称',创建出来的组件模板对象) Vue.component('myCom1',com1) 把名称以标签的形式放到页面中<m

  • Vue组件中的自定义事件你了解多少

    主要介绍组件的自定义事件的概念,使用等. 何为组件自定义事件: 组件自定义事件是一种组件间的通信方式,方向是 子组件====>父组件. 使用场景:A是子组件,B是父组件,如果要把B的数据传给A,可以使用props配置项,如果要把A的数据转给B,就要用到组件自定义事件或者使用props加回调函数也可实现. 先使用props加回调函数实现子组件传递数据给父组件. main.js: //引入vue依赖 import Vue from 'vue' //引入组件App import App from '.

  • 动态创建的表格单元格中的事件实现代码

    代码如下 var tableElem = document.getElementById("MyTable"); var tbodyElem = tableElem.getElementsByTagName("tbody")[0]; var trElem = document.createElement("tr"); var td1 = document.createElement("td"); td1.onclick = &

  • 解读Vue组件注册方式

    概述 组件化的概念让前端页面开发有了更清晰的结构. Vue 中的组件就是一个 Vue 的实例对象.因此,Vue 组件的构造选项和 new Vue() 方法构造 Vue 实例的构造选项是一样的,其可接收的构造选项都是一样的.除了 el 这样 根实例 特有的选项.但是,Vue 组件必须得是可以复用的,因此,就必须要求构造选项中的 data 选项必须是一个函数,该函数返回一个对象. 为什么 data 选项是个返回对象的函数就可以保证组件的可复用性呢? 因为无论是 new Vue() 的方式还是定义 V

  • vue 封装自定义组件之tabal列表编辑单元格组件实例代码

    vue 封装自定义组件 tabal列表编辑单元格组件 <template> <div class="editable-cell"> <div class="editable-cell-input-wrapper" v-if='editable'> <el-input class="editInput" v-model="cellValue" placeholder="请输入内

  • 一步步教你用Vue.js创建一个组件(附代码示例)

    目录 前言 到底什么是组件? 为什么你一定要使用组件 在Vue中创建一个组件 模板部分 脚本部分 选项API:旧的方式 合成API:现在和未来 风格部分 总结 前言 Vue.js是一个渐进式框架,旨在以一种非常简单.直接的方式构建用户界面.它被设计成易于使用,并且足够灵活,可以处理各种各样的应用. 在本教程中,我们将向你展示如何用Vue.js创建一个简单的组件.我们还将介绍一些在使用组件时需要知道的基本概念. 我们将介绍在Vue中创建一个组件的基本语法,以及一些关于组件用途的理论.在这篇文章的最

  • vue 怎么创建组件及组件使用方法

    什么是组件? 组件 (Component) 是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能.在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展. 我知道vue中核心就是组件,但是组件是什么呢?组件有什么用呢? 这里来说说怎么用组件?怎么样创建自己的组件?: 1)创建自己的组件 通过vue.extend("template");通过vue构造器去拓展一个模板,

  • 详解auto-vue-file:一个自动创建vue组件的包

    auto-vue-file auto create .vue file by shell command 通过终端自动创建vue文件 前言: 1: 我们在写xxx.vue页面文件的时候,一般都要写这些重复的代码: <template> <div class="zlj-comp-ct"> zlj组件 </div> </template> <script> export default { name: 'zlj' } </s

随机推荐