专栏首页前端知否以编程方式创建Vue.js组件实例

以编程方式创建Vue.js组件实例

最近参与了一个Vue.js项目,项目中需要能够以编程方式创建组件。通过编程,意思是使用JavaScript创建和插入组件,而无需在模板中编写任何内容。

本文接下来将介绍在模板中使用组件的各个方面,例如实例化,传递Props,插槽,挂载,转换为JavaScript代码。

通常,会推荐使用"单个文件组件"。比如一个Button组件,如下所示:

<template>
 <button :class="type"><slot /></button>
</template>

<script>
export default {
  name: 'Button',
  props: [ 'type' ],
}
</script>

要在另一个组件中使用它,您要做的就是导入Button组件并将其标签插入模板中:

<template>
  <Button type="primary">Click me!</Button>
</template>

<script>
import Button from 'Button.vue'

export default {
  name: 'App',
  components: { Button }
}
</script>

就项目需求而言,我不知道在模板中插入哪个组件以及在哪里插入。因此,我需要一种能在运行时为任何组件动态创建组件实例并将其插入DOM的方法。

创建实例

最初想法是使用new。但是,它将导出一个简单的对象,而不是类(构造函数)。如果我这样做:

import Button from 'Button.vue'

const instance = new Button()

上面的代码将失败。Button是一个对象,不是构造函数,不能new。我们需要的是一个Class,构造函数。我将组件对象传递给Vue.extend以创建Vue构造函数的子类。现在,我们可以使用new关键字从中创建一个实例:

import Button from 'Button.vue'
import Vue from 'vue'

const ComponentClass = Vue.extend(Button)
const instance = new ComponentClass()

完美!现在我们需要将其插入DOM中。

插入DOM

每个Vue实例都有一个名为$mount的方法,该方法将组件实例安装到传递给它的元素上(即,它将传递的元素替换为组件实例)。这不是我想要的效果。我想将组件实例插入某些DOM元素中。有一种方法可以做到这一点。从官方文档上看到:

如果未提供elementOrSelector参数,则该模板将呈现为文档外元素,并且必须使用浏览器DOM API自己将其插入文档中。

代码如下:

import Button from 'Button.vue'
import Vue from 'vue'

const ComponentClass = Vue.extend(Button)
const instance = new ComponentClass()

instance.$mount()
this.$refs.container.appendChild(instance.$el)

上面的代码中有两点需要注意。

首先,推荐使用$refs来引用Vue.js中的DOM元素。在要引用的DOM元素上指定一个属性(在本例中为<div ref =“ container”> </ div>),然后该元素在组件的$refs属性上就可以访问到。

其次,要从Vue组件实例获取文档上DOM元素引用,可以使用$el属性。

将Props传递给实例

接下来,我可以将一些Props传递给Button实例。比如,type属性。Vue构造函数接受一个options对象,我们可以使用该对象来传递和初始化相关内容。对于传递Props,有一个名为propsData的键,我们可以使用它,如下所示:

import Button from 'Button.vue'
import Vue from 'vue'

const ComponentClass = Vue.extend(Button)
const instance = new ComponentClass({
    propsData: { type: 'primary' }
})

instance.$mount()
this.$refs.container.appendChild(instance.$el)

我们几乎完成了,剩下最后一点。通过普通的模板方法,我们使用了如下按钮:<Button> Click me!</ Button>。标签之间的文本需要能够自定义,我们可以使用slot插槽来灵活设置将其渲染在最终按钮标签中。

设置插槽

如果您在Vue.js中使用了插槽,则可能知道在任何实例上都可以通过$slots属性访问这些插槽。而且,如果未使用命名插槽,则$slots.default中的插槽可以作为数组使用。这就是我们将在实例上修改的确切键,以设置按钮的内部文本。请记住,这需要在安装实例之前完成。

另外,在我们的例子中,我们只是在插槽中放入了一个简单的字符串。但是您还可以使用createElement函数以虚拟节点或VNode的形式将更复杂的DOM传递给它。您可以在Vue.js文档中阅读有关创建虚拟节点的信息。

import Button from 'Button.vue'
import Vue from 'vue'

const ComponentClass = Vue.extend(Button)
const instance = new ComponentClass({
    propsData: { type: 'primary' }
})

instance.$slots.default = [ 'Click me!' ]

instance.$mount()
this.$refs.container.appendChild(instance.$el)

本文分享自微信公众号 - 前端知否(qianduanzhifou),作者:QETHAN

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 如何使用Vue.js渲染JSON中定义的动态组件

    json数据content里边有个body数组,每个元素中都有一个component的字段,这个字段决定了使用哪个组件去渲染。

    前端知否
  • 构建Vue.js组件的10个技巧

    Vue.js提供了两种加载组件的方法:一种在Vue实例全局,另一种在组件级别。两种方法都有其自身的优点。

    前端知否
  • Vue.js应用性能优化二

    在Vue.js中的延迟加载和代码拆分文章中,我们了解了代码拆分是什么,它如何与Webpack一起工作以及如何在Vue应用程序中使用延迟加载来使用它。

    前端知否
  • 如何在SAP云平台上创建Redis实例

    Jerry Wang
  • 还学的动吗? 盘点下Vue.js 3.0.0 那些让人激动的功能

    路漫漫其修远兮,吾将上下而求索。——献给所有为 Vue的发展而默默付出的开发者们。

    葡萄城控件
  • 「技术」SEO中的技术挑战指南

    黄伟SEO
  • Linux上面安装JDK

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.n...

    林老师带你学编程
  • Java并发编程之原子变量

    原子变量最主要的一个特点就是所有的操作都是原子的,synchronized关键字也可以做到对变量的原子操作。只是synchronized的成本相对较高,需要获...

    哲洛不闹
  • linux之自定义命令 原

        本人使用的是ubuntu系统,不喜欢建各种桌面快捷链接,但是每次启动个软件,去查找又麻烦,所以自定义了命令,来快捷的启动应用:

    克虏伯
  • Django的登录功能(六)

    发现上一篇里面忘了对勾选我同意协议的校验了。虽然也没啥协议,但是样子还是要做一下的。 找到register.html里面的对应区域:

    zx钟

扫码关注云+社区

领取腾讯云代金券