文章缩略图

一淘模板教程:使用Vue搞定无法解决的“动态挂载”

2022-09-04 00:00:00 技术教程 11188 阅读需56分钟
图标

本文最后更新于2022-09-04 00:00:00已经过去了966天 请注意内容时效性

热度 151 评论 0 点赞59
钞能力。你在哪?此处内容已经被作者隐藏,请输入验证码查看内容
验证码:
请关注本站微信公众号,回复“验证码”,获取验证码。在微信里搜索“钞能力。你在哪?”或者“mdyc919293”或者微信扫描右侧二维码关注公众号。

 一淘模板教程:使用Vue搞定无法解决的“动态挂载” 技术教程

在一些特殊场景下,使用组件的时机无法确定,或者无法在Vue的template中确定要我们要使用的组件,这时就需要动态的挂载组件,或者使用运行时编译动态创建组件并挂载。

今天我们将带大家从实际项目出发,看看在实际解决客户问题时,如何将组件进行动态挂载,并为大家展示一个完整的解决动态挂载问题的完整过程。

 

无法解决的“动态挂载”

我们的电子表格控件SpreadJS在运行时,存在这样一个功能:当用户双击单元格会显示一个输入框用于编辑单元格的内容,用户可以根据需求按照自定义单元格类型的规范自定义输入框的形式,集成任何Form表单输入类型。

这个输入框的创建销毁都是通过继承单元格类型对应方法实现的,因此这里就存在一个问题——这个动态的创建方式并不能简单在VUE template中配置,然后直接使用。

 

而就在前不久,客户问然询问我:你家控件的自定义单元格是否支持Vue组件比如ElementUI的AutoComplete?

由于前面提到的这个问题:

 一淘模板教程:使用Vue搞定无法解决的“动态挂载” 技术教程

沉思许久,我认真给客户回复:“组件运行生命周期不一致,用不了”,但又话锋一转,表示可以使用通用组件解决这个问题。

问题呢,是顺利解决了。

但是这个无奈的"用不了",却也成为我这几天午夜梦回跨不去的坎。

 

后来,某天看Vue文档时,我想到App是运行时挂载到#app上的。,从理论上来说,其他组件也应该能动态挂载到需要的Dom上,这样创建时机的问题不就解决了嘛!

正式开启动态挂载

让我们继续查看文档,全局APIVue.extend( options )是通过extend创建的。Vue实例可以使用$mount方法直接挂载到DOM元素上——这正是我们需要的。

// 创建构造器var Profile = Vue.extend({  template: '

{{firstName}} {{lastName}} aka {{alias}}

', data: function () { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } }})// 创建 Profile 实例,并挂载到一个元素上。new Profile().$mount('#mount-point')

按照SpreadJS自定义单元格示例创建AutoCompleteCellType,并设置到单元格中:

function AutoComplateCellType() {}AutoComplateCellType.prototype = new GC.Spread.Sheets.CellTypes.Base();AutoComplateCellType.prototype.createEditorElement = function (context, cellWrapperElement) {//   cellWrapperElement.setAttribute("gcUIElement", "gcEditingInput");  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) {      // 创建构造器      var Profile = Vue.extend({        template: '

{{firstName}} {{lastName}} aka {{alias}}

', data: function () { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } } }) // 创建 Profile 实例,并挂载到一个元素上。 new Profile().$mount(editorContext.firstChild); }};

运行,双击进入编辑状态,结果却发现报错了

[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

根据报错提示,此时候我们有两种解决办法:

开启runtimeCompiler,在vue.config.js中加入runtimeCompiler: true的配置,允许运行时编译,这样可以动态生成template,满足动态组件的需求

提前编译模板仅动态挂载,autocomplete的组件是确定的,我们可以使用这种方法

新建AutoComplete.vue组件用于动态挂载,这样可以挂载编译好的组件。

      

{{ firstName }} {{ lastName }} aka {{ alias }}

export default { data: function () { return { firstName: "Walter", lastName: "White", alias: "Heisenberg", }; },};
import AutoComplate from './AutoComplate.vue'  AutoComplateCellType.prototype.activateEditor = function (editorContext, cellStyle, cellRect, context) {    let width = cellRect.width > 180 ? cellRect.width : 180;    if (editorContext) {      // 创建构造器      var Profile = Vue.extend(AutoComplate);      // 创建 Profile 实例,并挂载到一个元素上。      new Profile().$mount(editorContext.firstChild);    }};

双击进入编辑状态,看到组件中的内容

 一淘模板教程:使用Vue搞定无法解决的“动态挂载” 技术教程

下一步,对于自定义单元格还需要设置和获取组件中的编辑内容,这时通过给组件添加props,同时在挂载时创建的VueComponent实例上直接获取到所有props内容,对应操作即可实现数据获取设置。

更新AutoComplate.vue,添加props,增加input用于编辑

      

{{ firstName }} {{ lastName }} aka {{ alias }}

export default { props:["value"], data: function () { return { firstName: "Walter", lastName: "White", alias: "Heisenberg", }; },};

通过this.vm存储VueComponent实例,在getEditorValue 和setEditorValue 方法中获取和给VUE组件设置Value。编辑结束,通过调用$destroy()方法销毁动态创建的组件。

AutoComplateCellType.prototype.activateEditor = function (editorContext, cellStyle, cellRect, context) {    let width = cellRect.width > 180 ? cellRect.width : 180;    if (editorContext) {      // 创建构造器      var Profile = Vue.extend(MyInput);      // 创建 Profile 实例,并挂载到一个元素上。      this.vm = new Profile().$mount(editorContext.firstChild);    }}; AutoComplateCellType.prototype.getEditorValue = function (editorContext) {    // 设置组件默认值    if (this.vm) {        return this.vm.value;    }};AutoComplateCellType.prototype.setEditorValue = function (editorContext, value) {    // 获取组件编辑后的值    if (editorContext) {      this.vm.value = value;    }};AutoComplateCellType.prototype.deactivateEditor = function (editorContext, context) {    // 销毁组件    this.vm.$destroy();    this.vm = undefined;};

 一淘模板教程:使用Vue搞定无法解决的“动态挂载” 技术教程

整个流程跑通了,下来只需要在AutoComplate.vue中,将input替换成ElementUI 的el- autocomplete并实现对应方法就好了。

结果

让我们看看效果吧。

 一淘模板教程:使用Vue搞定无法解决的“动态挂载” 技术教程

其实动态挂载并不是什么复杂操作,理解了Vue示例,通过vm来操作实例,灵活的运用动态挂载或者运行时编译的组件就不是什么难事了。

其实一切的解决方案就在Vue教程入门教程中,但是脚手架的使用和各种工具的使用让我们忘记了Vue的初心,反而把简单问题复杂化了。

你可能想看:
继续阅读本文相关话题
模板模板读音模板图片模板素材模板尺寸规格及价格模板的拼音模板的尺寸是多少模板厂家批发市场ppt免费模板尺寸模板免费模板王模板规格尺寸模板ppt免费模板王字库模板之家模板支撑模板工程专项施工方案模板ppt模板 英文模板方法模式模板元编程模板模式模板类模板匹配模板字符串模板函数模板特化教程教程是什么意思教程的英文教程视频教程之家教程网教程手工教程魔方教程拼音教程画画教程自学网教程学习之家教程网官网教程资源网教程之家官网教程网论坛教程英语单词教程 英文教程网站教程资源教程是什么教程学分班教程 英语使用的英文使用灭火器对准火焰的什么部位使用灭火器时人应站在上风口还是下风口使用灭火器时人应该站在什么位置使用造句使用的拼音使用伪造变造的行驶证一次记几分使用其他机动车号牌行驶证扣几分使用造句二年级使用化学消毒法消毒液多久换一次使用权资产使用权资产账务处理新会计准则使用说明书使用灭火器是站在上风口还是下风口使用权资产是什么意思使用灭火器灭火时先将灭火器从设置点提至距离燃烧物2-5米,站什么风向使用权资产的账务处理使用权资产的确认条件使用网盘的感受如何使用流程图来描述医院"自助挂号算法"。使用代码生成器应用生成一个代码并在下方输入使用后不予退还使用了不受支持的协议使用point dollar使用此iphone重设你的apple账户密码使用英语的国家使用欧元的国家使用 cnki 保存时发生错误。改为尝试用 doi 保存。母猪人工授精技术教程多箱体养蜂技术教程凹陷修复技术教程汽车喷漆技术教程母牛人工授精技术教程鹅孵化技术教程修鞋补鞋技术教程鹅苗孵化技术教程ai技术入门教程技术开锁教程视频技术教程资源网技术教室技术员技术学习技术分析 教学
更多推荐
发表评论

共有[ 0 ]人发表了评论

🥰 😎 😀 😘 😱 🤨 🥵 😔 😤 😡 😭 🥱 🤡 ☠️ 💖 🤖 💢 💥

评论列表
暂无评论

暂时没有评论,期待您的声音!

品牌认证 W3C认证 MYSSL认证 TrustAsia 安全签章
扫码访问手机版
二维码图片