dexteryao 发表于 2021-9-22 18:07:43

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

本帖最后由 dexteryao 于 2022-1-10 15:26 编辑

前一篇通过设置runtimeCompiler为true,动态编译组件让SpreadJS支持了动态创建VUE组件。

但是实际场景我们可能只需要动态创建VUE组件,而组件的template内容并需要动态。其实autoComplete也属于这种场景。
那我们就可以将动态创建的Component固化,按需import 然后挂载即可。这样就不需要开启runtimeCompiler了

具体做法
1. 封装AutoComplete组件封装的组件,需要注意一下几点

[*]组件提供text(或者value)属性,用于对应单元格需要编辑的值,组件中如果不是用model双向绑定,操作后需要主动更新text
[*]提供cellStyle,用户CellType根据单元格大小控制组件的大小
[*]组件如果有注入的DOM元素不在template div内部,需要添加gcUIElement属性,原因在上一篇有说明

<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>
</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");
            //   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>
2 .autoCompleteCellType直接挂在组件,不需要动态声明了
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,代码可维护行也提高了。




梅梅梅梅 发表于 2022-7-22 15:27:12

请问这个是把第一篇的替换成上面的组件吗?
另外这个import DataService from '../static/dataService'文件指的是什么?

Derrick.Jiao 发表于 2022-7-22 17:24:45

梅梅梅梅 发表于 2022-7-22 15:27
请问这个是把第一篇的替换成上面的组件吗?
另外这个import DataService from '../static/dataService'文 ...

AutoCompleteCtor从第一篇文章引入即可。

import DataService from '../static/dataService'这个文件可以忽略,这个对自定义单元格没有作用。

孙志强 发表于 2022-7-26 16:02:53

请问有基于vue3的demo吗

Lynn.Dou 发表于 2022-7-26 17:52:42

目前没有vue3的demo,您可以参考上述思路自己实现下。

sanyue 发表于 2023-6-1 09:36:31

孙志强 发表于 2022-7-26 16:02
请问有基于vue3的demo吗

请问基于vue3的您实现了吗?

孙志强 发表于 2023-7-18 11:42:21

sanyue 发表于 2023-6-1 09:36
请问基于vue3的您实现了吗?

实现了,我做了一些改造,直接使用组件挂载到#gcEditingInput下更方便

Joestar.Xu 发表于 2023-7-18 15:17:01

孙志强 发表于 2023-7-18 11:42
实现了,我做了一些改造,直接使用组件挂载到#gcEditingInput下更方便

您好,您是如何实现的呢?能否提供一下您的代码,让大家一起学习学习{:3_59:}

孙志强 发表于 2023-7-19 10:24:15

本帖最后由 孙志强 于 2023-7-19 10:36 编辑

Joestar.Xu 发表于 2023-7-18 15:17
您好,您是如何实现的呢?能否提供一下您的代码,让大家一起学习学习
大概流程是:activateEditor激活了,将放置在#gcEditingInput下的自定义组件显示,并将当前的值传递到组件中,修改完毕后在getEditorValue返回组件的值,然后在deactivateEditor里隐藏组件


Lynn.Dou 发表于 2023-7-19 18:35:10

孙志强 发表于 2023-7-19 10:24
大概流程是:activateEditor激活了,将放置在#gcEditingInput下的自定义组件显示,并将当前的值传递到组 ...

:hjyzw: 感谢分享,给您送上金币奖励
页: [1] 2
查看完整版本: 使用VUE组件创建SpreadJS自定义单元格(二)