请选择 进入手机版 | 继续访问电脑版
 找回密码
 立即注册

QQ登录

只需一步,快速开始

dexteryao 讲师达人认证 悬赏达人认证 SpreadJS 开发认证

超级版主

124

主题

8928

帖子

1万

积分

超级版主

Rank: 8Rank: 8

积分
13548

讲师达人悬赏达人元老葡萄SpreadJS 认证SpreadJS 高级认证微信认证勋章

dexteryao 讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2021-9-22 18:07  /   查看:4523  /  回复:15
本帖最后由 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属性,原因在上一篇有说明

  1. <template>
  2.   <div>
  3.     <el-autocomplete
  4.       :style="cellStyle"
  5.       popper-class="my-autocomplete"
  6.       v-model="text"
  7.       :fetch-suggestions="querySearch"
  8.       placeholder="请输入内容"
  9.       :popper-append-to-body="false"
  10.       value-key="name"
  11.       @select="handleSelect"
  12.     >
  13.       <i
  14.         class="el-icon-edit el-input__icon"
  15.         slot="suffix"
  16.         @click="handleIconClick"
  17.       >
  18.       </i>
  19.       <template slot-scope="{ item }">
  20.         <div class="name">{{ item.name }}</div>
  21.         <span class="addr">{{ item.phone }}</span>
  22.       </template>
  23.     </el-autocomplete>
  24.   </div>
  25. </template>
  26.   <script>

  27. import DataService from '../static/dataService'

  28. export default {
  29.     props: ['text','cellStyle'],
  30.     mounted() {
  31.         this.items = DataService.getEmployeesData();
  32.     },
  33.     methods: {
  34.         querySearch(queryString, cb) {
  35.             var items = this.items;
  36.             var results = queryString ? items.filter(this.createFilter(queryString)) : items;
  37.             // 无法设置动态内容的位置,可以动态添加gcUIElement
  38.             // setTimeout(() => {
  39.             //   let popDiv = document.getElementsByClassName("my-autocomplete")[0];
  40.             //   if(popDiv){
  41.             //     popDiv.setAttribute("gcUIElement", "gcEditingInput");
  42.             //   }
  43.             // }, 500);
  44.             // 调用 callback 返回建议列表的数据
  45.             cb(results);
  46.         },
  47.         createFilter(queryString) {
  48.             return (restaurant) => {
  49.             return (restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
  50.             };
  51.         },
  52.         handleSelect(item) {
  53.             console.log(item);
  54.         },
  55.         handleIconClick(ev) {
  56.             console.log(ev);
  57.         }
  58.     }
  59. }
  60. </script>
复制代码
2 .autoCompleteCellType直接挂在组件,不需要动态声明了
  1. import AutoComplete from '../components/AutoComplete'
复制代码
  1. AutoComplateCellType.prototype.activateEditor = function (editorContext, cellStyle, cellRect, context) {
  2.     let width = cellRect.width > 180 ? cellRect.width : 180;
  3.     if (editorContext) {
  4.        // create component constructor
  5.        const AutoCompleteCtor = Vue.extend(AutoComplete);
  6.         this.vm = new AutoCompleteCtor({
  7.         propsData: {
  8.           cellStyle: {width: width+"px"}
  9.         }
  10.       }).$mount(editorContext.firstChild);
  11.     }
  12. };
复制代码



其余代码不变,参考前一篇文章,这样不仅不需要runtimeCompiler,代码可维护行也提高了。




15 个回复

倒序浏览
梅梅梅梅
中级会员   /  发表于:2022-7-22 15:27:12
沙发
请问这个是把第一篇的 image.png575606383.png 替换成上面的组件吗?
另外这个import DataService from '../static/dataService'文件指的是什么?
回复 使用道具 举报
Derrick.Jiao讲师达人认证 悬赏达人认证 SpreadJS 开发认证
论坛元老   /  发表于: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讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2022-7-26 17:52:42
5#
目前没有vue3的demo,您可以参考上述思路自己实现下。
回复 使用道具 举报
sanyue
中级会员   /  发表于:2023-6-1 09:36:31
6#
孙志强 发表于 2022-7-26 16:02
请问有基于vue3的demo吗

请问基于vue3的您实现了吗?
回复 使用道具 举报
孙志强讲师达人认证
金牌服务用户   /  发表于:2023-7-18 11:42:21
7#
sanyue 发表于 2023-6-1 09:36
请问基于vue3的您实现了吗?

实现了,我做了一些改造,直接使用组件挂载到#gcEditingInput下更方便
回复 使用道具 举报
Joestar.XuSpreadJS 开发认证
超级版主   /  发表于:2023-7-18 15:17:01
8#
孙志强 发表于 2023-7-18 11:42
实现了,我做了一些改造,直接使用组件挂载到#gcEditingInput下更方便

您好,您是如何实现的呢?能否提供一下您的代码,让大家一起学习学习
回复 使用道具 举报
孙志强讲师达人认证
金牌服务用户   /  发表于:2023-7-19 10:24:15
9#
本帖最后由 孙志强 于 2023-7-19 10:36 编辑
Joestar.Xu 发表于 2023-7-18 15:17
您好,您是如何实现的呢?能否提供一下您的代码,让大家一起学习学习

大概流程是:activateEditor激活了,将放置在#gcEditingInput下的自定义组件显示,并将当前的值传递到组件中,修改完毕后在getEditorValue返回组件的值,然后在deactivateEditor里隐藏组件
image.png837668762.png
image.png937097778.png

评分

参与人数 1金币 +500 收起 理由
Lynn.Dou + 500 很给力!

查看全部评分

回复 使用道具 举报
Lynn.Dou讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2023-7-19 18:35:10
10#
孙志强 发表于 2023-7-19 10:24
大概流程是:activateEditor激活了,将放置在#gcEditingInput下的自定义组件显示,并将当前的值传递到组 ...

感谢分享,给您送上金币奖励
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 立即注册
返回顶部