写本篇文章之前其实也关注过vue中的一个关于加载动态组件is的API,最开始研究它只是用来实现一个tab切换的功能,使用起来也蛮不错的。

is

预期:string | Object (组件的选项对象)

用于动态组件且基于 DOM 内模板的限制来工作。

示例:

<!-- 当 `currentView` 改变时,组件也跟着改变 -->
<component v-bind:is="currentView"></component>

详见vue API中关于is的定义和用法

至于用在tab切换中,大概就是:

<template>
<div>
  <div>#动态组件实现tab切换效果#</div><br><br><br>
    <nav>
<a href="javascript:void(0);" @click="toggleTabs('first');">{{first}}</a>
<a href="javascript:void(0);" @click="toggleTabs('second');">{{second}}</a>
<a href="javascript:void(0);" @click="toggleTabs('third');">{{third}}</a>
    </nav>      <first :is="currentView" keep-alive></first>
   </div>
</template> <script>
import first from 'components/first';
import second from 'components/second';
import third from 'components/third'; export default {
data () {
return {
first: "first",
second: "second",
third: "third",
currentView: 'first',
};
},
components: {
first,
second,
third
},
methods: {
toggleTabs (tabText) {
this.currentView = tabText;
}
}
}
</script>

但是今天,一个前端同行在群里问我“如果当前页面是根据传进来的参数的不同而显示不同的组件,而且当前页面中可能会import进来几十个子组件,而我又不想挨个去import这些组件,同时这些组件又是按需加载的,该咋实现?” 说实话,一开始我也懵了。

我在想,实在不行就用const demo = () => import ( './demo.vue'),或者在组件的components中按需引入:

components: {
demo: () => import ( './demo.vue')
}

但是我一想,也不对啊,这样虽然能实现按需加载,但是还是要挨个import这些组件,还是没有解决实际的问题。

经过查阅资料发现,vue有一个extend的方法可以实现。那么这个extend方法到底是干嘛的?



Vue.extend( options )

Vue.extend 返回的是一个“扩展实例构造器”,也就是预设了部分选项的Vue实例构造器。经常服务于Vue.component用来生成组件,可以简单理解为当在模板中遇到该组件名称作为标签的自定义元素时,会自动调用“扩展实例构造器”来生成组件实例,并挂载到自定义元素上。

只是,extend创建的是一个组件构造器,而不是一个具体的组件实例,所以他不能直接在new Vue中使用。

使用Vue.extend创建的组件构造器最终是可以通过Vue.component注册成全局组件或new实例化后注册为局部组件。

接下来就来实现一下使用Vue.extend和Vue.component注册全局组件:

import Vue from 'vue';

const globalComponent = Vue.extend({
template:"<p><a :href='url'>{{nama}}</a></p>",
data:function(){
return{
nama:'某度',
url:'http://www.moudu.com'
}
}
}); Vue.component('globalComponent', globalComponent);

使用这个全局注册的组件:

<template>
<globalComponent />
</template>

也可以传入一个选项对象,会自动调用Vue.extend:

const globalComponent = {
template:"<p><a :href='url'>{{nama}}</a></p>",
data(){
return{
nama:'某度',
url:'http://www.moudu.com'
}
}
}; Vue.component('globalComponent', globalComponent);

注册全局组件还是很简单的,但是有一个容易报错的问题需要说明一下。

报错的原因不是本文的重点,详情可参考:

https://www.cnblogs.com/xiangxinhouse/p/8447507.html

https://blog.csdn.net/wxl1555/article/details/83187647

接下来就来实现根据传参的不同加载不同组件的方法:

<template>
<button type="button" @click="toggle('test')">动态注册组件<button>
<p><div ref="currentView"></div>
</template> <script>
import Vue from 'vue' export default {
data(){
return {}
},
methods: {
toggle(componentName){
this.registerComponent(componentName).then(Component => {
// new Component().$mount(this.$refs.currentView) new Component({
el: this.$refs.currentView,
data: {
msg: "动态组件传值"
}
})
})
},
registerComponent(componentName) {
return import(`@/views/${componentName}.vue`).then(component => {
return Vue.extend(component.default);
});
}
},
}
</script>

这样,我们就可以根据动态传入的参数,通过import(@/views/${componentName}.vue)来加载不同的组件,注意,import返回一个Promise对象,在Promise的then函数中就可以使用 Vue.extend(component.default)来创建一个组件的构造器,然后通过new关键字就可以实现局部注册组件了。

还有一点需要说明:在实例化Vue.extend时,不光可以绑定el到具体的DOM节点,还可以定义要传给子组件的参数data,在子组件可以直接通过this来拿到父组件传过来的参数,如:

new Component({
el: this.$refs.currentView,
data: {
msg: "动态组件传值"
}
})

子组件就可以通过this.msg拿到父组件传过来的值,如果子组件本身在data中就已经定义了一个msg字段,那么父组件中定义的msg字段会覆盖子组件中定义的msg字段。

本文参考:

Vue2.0 - 构造器的延伸 Vue.extend

vue extend 的基本使用

Vue.extend动态注册子组件的更多相关文章

  1. Vue中通过Vue.extend动态创建实例

    Vue中通过Vue.extend动态创建实例 在Vue中,如果我们想要动态地来控制一个组件的显示和隐藏,比如通过点击按钮显示一个对话框或者弹出一条信息.我们通常会提前写好这个组件,然后通过v-if = ...

  2. vue通过extend动态创建全局组件(插件)学习小记

    测试环境:nodejs+webpack,例子是看文章的,注释为自己的理解 创建一个toast.vue文件: <template> <div class="wrap" ...

  3. vue中动态加载组件+开发者模式+JS参数值传递和引用传递

    今天写vue里面通过接口反参动态加载组件时候 跟着同学...学习到了 一.先说说vue 内置组件 component 的用法 component组件可以来专门用来进行组件的切换,使用is来绑定你的组件 ...

  4. Vue.js 动态挂载子组件

    直接来实例 父组件 <template> <div> <div :is="sub.content" :ref="sub.name" ...

  5. VUE组件 之 Toast (Vue.extend 方式)

    一.效果图 二.说明 这类提示框组件我们通常都会直接在 JS 代码中进行调用.像下面这样: this.$toast('别点啦,到头啦!') 但看到网上大多数还是通过 component  方式实现的, ...

  6. Vue.extend构造器和$mount实例构造组件后可以用$destroy()进行卸载,$forceUpdate()进行更新,$nextTick()数据修改

    html <div id="app"> </div> <p><button onclick="destroy()"&g ...

  7. Vue.extend提供自定义组件的构造器

    Vue.extend 返回的是一个“扩展实例构造器”,也就是预设了部分选项的Vue实例构造器.经常服务于Vue.component用来生成组件,可以简单理解为当在模板中遇到该组件名称作为标签的自定义元 ...

  8. vue extend 的基本使用

    vue.extend 局部注册 的应用2 请注意,extend创建的是一个组件构造器,而不是一个具体的组件实例.所以他不能直接在new Vue中这样使用: new Vue({components: f ...

  9. Vue学习笔记-Vue.js-2.X 学习(三)===>组件化高级

    (四) 组件化高级 1.插槽(slot)的基本使用 A:基本使用: <slot></slot> B:默认置:<slot><h1>中间可以放默认值< ...

随机推荐

  1. 【转】 Pro Android学习笔记(三九):Fragment(4):基础小例子-续

    目录(?)[-] Step 3实现简介显示类DetailFragment 创建实例 编写所需的生命周期代码 Step 4实现showDetailint index如何管理fragment fragme ...

  2. Python知识点: os.popen

    用例:f = os.popen("%s %s %s" % ("pkg-config", " ".join(args), mod)) pope ...

  3. GIF助手激活教程(购买+激活)图文版

    GIF助手首页==>设置(右上角) ==>输入激活码会弹出购买或者激活的对话框.(如果不明白操作,可以点击如何购买激活码先查看购买帮助指南再进行购买) 点击复制设备码并购买. 此时会进入到 ...

  4. fedora18下安装chrome

    ——杂言:这个fedora18是之前装着玩的,原本用的firefox来调试网站页面的,但是因为fedora上没有安装flash,以及一些其他plugin,所以还是没忍住装了chrome,一劳永逸,也好 ...

  5. 1、转载 bwa的使用方法

    http://bio-bwa.sourceforge.net/bwa.shtml http://www.plob.org/?p=25 bwa的使用需要两中输入文件: Reference genome ...

  6. iOS开发中,修改ASIHTTPRequest源码,禁止在POST时URL编码

    通过ASIHTTPRequest库进行POST时,会对POST的文本内容进行encodeURL,而且ASIHTTPRequest自身并没有配置项可以关闭这个转换. 本文提供一个方法关闭encodeUR ...

  7. 解决因为终端打印造成的java程序假死

    问题状态: java 程序 日志采用 log4j 运行时由另一个管理进程拉起,程序在后台运行. 现象: 程序后台运行时,运行一段时间后假死 分析原因: 尝试打印输出,定位假死的具体位置,发现出现假死的 ...

  8. 判断Java对象死亡的两种常用算法

    当对象不馁引用的时候,这个对象就是死亡的,等待GC进行回收. 1.引用计数法 概念: 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就增加1:当应用失效时,计数器值就减1:任何时刻计数器 ...

  9. Umbraco安装过程中出现的问题以及调试

    在VS2015中使用NuGet安装完UmbracoCms后,按Ctrl+F5运行程序来完成安装UmbracoCms的过程中,发现一直在安装但是没有反应 估计是出现了错误.所以我到项目所在的文件夹中查找 ...

  10. hdu1078

    #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; i ...