作为近五年都冲在热门框架排行榜首的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自定义单元格(一)的更多相关文章

  1. 使用VUE组件创建SpreadJS自定义单元格(二)

    在上篇中,我们介绍了如何通过设置runtimeCompiler为true,在Vue中实现了动态创建电子表格组件.想了解具体内容可看点击查看使用VUE组件创建SpreadJS自定义单元格(一). 但是在 ...

  2. Swift - 自定义单元格实现微信聊天界面

    1,下面是一个放微信聊天界面的消息展示列表,实现的功能有: (1)消息可以是文本消息也可以是图片消息 (2)消息背景为气泡状图片,同时消息气泡可根据内容自适应大小 (3)每条消息旁边有头像,在左边表示 ...

  3. iOS:UITableViewCell自定义单元格

    UITableViewCell:自定义的单元格,可以在xib中创建单元格,也可以在storyBorad中创建单元格.有四种创建方式 <1>在storyBorad中创建的单元格,它是静态的单 ...

  4. 浅谈DevExpress<五>:TreeList简单的美化——自定义单元格,加注释以及行序号

    今天就以昨天的列表为例,实现以下效果:预算大于110万的单元格突出显示,加上行序号以及注释,如下图:

  5. jQuery MiniUI自定义单元格

    监听处理"drawcell"事件 使用"drawcell"事件,可以自定义单元格内容.样式.行样式等. grid.on("drawcell" ...

  6. 如何让elemengUI中的表格组件相同内容的单元格自动合并

    1. 前言 这两天在工作中遇到这样一个需求:将某个Excel中的数据在页面上以表格形式展示出来,并且尽量保持数据层级与Excel中一致.在原始Excel文件中,对每一行相同的数据都进行了合并,使得数据 ...

  7. 黑马vue---56-58、vue组件创建的三种方式

    黑马vue---56-58.vue组件创建的三种方式 一.总结 一句话总结: 不论是哪种方式创建出来的组件,组件的 template 属性指向的模板内容,必须有且只能有唯一的一个根元素 1.使用 Vu ...

  8. NPOI 自定义单元格背景颜色-Excel

    NPOI针对office2003使用HSSFWorkbook,对于offce2007及以上使用XSSFWorkbook:今天我以HSSFWorkbook自定义颜色为例说明,Office2007的未研究 ...

  9. vue中 表头 th 合并单元格,且表格列数不定的动态渲染方法

    吐槽 今天,在vue中遇到 复杂表格的渲染 ,需要合并表头th的单元格,且合并单元格的那列的表头数据是动态数据,也就是不知道会有多少个表头列,而这几个表头列还分了好几个子表头. 这个需求在js里用Ju ...

随机推荐

  1. oracle中分组中的ROLLUP和CUBE选项

    在进行多列分组统计时,如果直接使用GROUP BY子句指定分组列,则只能生成基于所有分组列的统计结果.如果在GROUP BY子句中使用ROLLUP语句或CUBE语句,除了生成基于所有指定列的分组统计外 ...

  2. SpringBoot(1):初始SpringBoot

    一. SpringBoot 简介 1. SpringBoot介绍 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用的初始搭建以及开发过程.该框架使用了特 ...

  3. 基于jar的Spring Boot工程

    一.Spring Boot简介 Spring Boot是由Pivotal[ˈpɪvətl]团队(一家做大数据的公司)提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架 ...

  4. Mybatis通用Mapper介绍和使用

    Mybatis通用Mapper介绍与使用 前言 使用Mybatis的开发者,大多数都会遇到一个问题,就是要写大量的SQL在xml文件中,除了特殊的业务逻辑SQL之外,还有大量结构类似的增删改查SQL. ...

  5. 如何利用EL表达式获取list,map,对象等值

    <%@ page import="com.hopetesting.domain.User" %><%@ page import="java.util.* ...

  6. freeswitch APR库线程读写锁

    概述 freeswitch的核心源代码是基于apr库开发的,在不同的系统上有很好的移植性. 线程读写锁在多线程服务中有重要的作用.对于读数据比写数据频繁的服务,用读写锁代替互斥锁可以提高效率. 由于A ...

  7. axb_2019_fmt32

    一道格式字符串的题目,拿到题目例行检查一下 32位的程序开机了nx的保护,将程序放入ida中 发现没有system函数于是进入main主函数进行代码审计 可以看到printf存在明显的格式字符串漏洞 ...

  8. dart系列之:如丝滑般柔顺,操作文件和目录

    目录 简介 File 读取整个文件 以流的形式读取文件 随机访问 文件的写入 处理异常 总结 简介 文件操作是IO中非常常见的一种操作,那么对应dart语言来说,操作文件是不是很简单呢?实际上dart ...

  9. TURN协议(RFC5766详解)

    如果一台主机处于NAT后面,那么在一定条件下两台主机无法之间进行通讯.在这种条件下,那么使用中继服务提供通讯是有必要的. 这个规范定义了一个名为TURN(使用中继穿越NAT)的协议,它允许一台主机使用 ...

  10. UDP&串口调试助手用法(4)

    接收配置用法 概览 保存文件 可将数据保存到文件和文件夹 如果选择的时文件,则需要自己手动选择保存的文件. 如果选择的时文件夹,则需要指定文件夹的类型和文件的后缀 支持保存文件类型: 文本文件和二进制 ...