fire

读在最前面:

  1、本文适用于有一定基础的vue开发者,需要了解基本的vue渲染流程

  2、本文知识点涉及vue构造器以及选项策略合并、<component> 渲染逻辑

问题描述:

Child继承自App,主程序通过true 和false来控制显示 Child 还是 App,在动态<component /> 中渲染出来的始终是App,代码如下

 Vue.config.productionTip = false;
Vue.config.devtools = false; // ----------------options---------------------
const optionsA = {
render: (h) => h('span', '我是options - 父'),
}; const optionsB = {
render: (h) => h('span', '我是options - 子'),
}; const App = Vue.extend({
template: `<div>
当前组件: {{name}}
<br/>
<component :is="node" />
</div>`,
data() {
return {
name: 'App',
node: optionsA,
}
}
}); const Child = App.extend({
name: 'Child',
data() {
return {
name: 'Child',
node: optionsB,
}
}
}); const vm = new Vue({
el: '#app',
data() {
return {
isSuper: true,
};
},
components: { App, Child },
render(h) {
const that = this;
return h('div', {}, [
h('button', {
on: {
click: () => {
this.isSuper = true;
}
},
}, '父类'),
h('button', {
on: {
click: () => {
this.isSuper = false;
}
},
}, '子类'),
h(this.isSuper ? 'App' : 'Child')
]);
},
});

  

点击查看实例代码

如下图(点击父/子类切换,始终显示的是 父文本):

关键执行顺序分析:

1、App通过继承Vue生成构造,Child通过继承App生成构造

2、默认isSuper:true,渲染出App(<component :is="node" /> 编译为render: _C(node),这个时候会在App的node中生成.Ctor)

3、切换isSuper:false,渲染出Child(这里渲染的时候,生成的实例是App,这里是不符合预期的,按理应该是Child)

  3.1、生成Child实例的时候进行了data合并,这个时候data中node变量合并了App的node中的.Ctor($options合并策略),参照下图

  3.2、在_createElement的时候 node 当为component options / constructor 时,会验证是否 node 是否为object,如果是会转换为构造器 使用vue.extend

  3.2、在Child中动态调用 new Ctor() (这个Ctor是App的),生成实例

最后附上大致流程图:

备注:  

   1、Vue.extend会生成VueComponent构造器,内部包含一个Ctor,组件生成的时候就是调用这个new Ctor() 进行实例生成

 2、选项中data的生成是延迟到实例生成的时候

   3、createComponent在分支<component>渲染时,传入Ctor为对象的时候,会转换为构造器,这也是我们这个使用 const optionsA = {render: (h) => h('span', '我是options - 父'), }; 这种方式的问题根源所在

  4、知道了问题所在,解决方式就比较多了,比如直接传入构造器,比如绕开data值合并策略,使用method方式。

by:海豚湾-丰

  

Vue 动态组件渲染问题分析的更多相关文章

  1. Vue动态组件

    前面的话 让多个组件使用同一个挂载点,并动态切换,这就是动态组件.本文将详细介绍Vue动态组件 概述 通过使用保留的 <component> 元素,动态地绑定到它的 is 特性,可以实现动 ...

  2. Vue动态组件&异步组件

    在动态组件上使用keep-alive 我们之前曾经在一个多标签的界面中使用is特性来切换不同的组件: Vue.js的动态组件模板 <component v-bind:is="curre ...

  3. Vue - 动态组件 & 异步组件

    动态组件 <div id="app"> <components :is="com[2]"></components> < ...

  4. Vue 动态组件和异步组件

    基础案例 动态组件切换类比"bilibili-个人中心"的横向菜单切换不同的标签页的功能. 在Vue中可以使用 component 标签,并加一个特殊的属性(attribute) ...

  5. Vue动态组件的实践与原理探究

    我司有一个工作台搭建产品,允许通过拖拽小部件的方式来搭建一个工作台页面,平台内置了一些常用小部件,另外也允许自行开发小部件上传使用,本文会从实践的角度来介绍其实现原理. ps.本文项目使用Vue CL ...

  6. vue动态组件切换(选项卡)

    vue的动态组件 <template :is='变量'></template> 可以通过改变变量,来改变template的替换内容.达到选项卡的功能 如果想要切换保持不重新创建 ...

  7. vue 动态组件、父子组件传参

    1.vue中的自定义属性并获得属性的值 自定义属性::data-id语法为 :data-属性  获取属性的值:ev.target.dataset.id 2.vue父子组件传值 3.动态组件使用

  8. Vue 动态组件、动画、插件

    1 动态组件 ①简单来说: 就是几个组件放在一个挂载点下,然后根据父组件的某个变量来决定显示哪个,或者都不显示. ②动态切换: 在挂载点使用component标签,然后使用v-bind:is=”组件名 ...

  9. vue 动态组件

    动态组件 多个组件通过同一个挂载点进行组件的切换,is的值是哪个组件的名称,那么页面就会显示哪个组件 内置组件 (内置组件不会被渲染到页面上) component is属性     keep-aliv ...

随机推荐

  1. django rest framework serializers小结

    注:转载至https://blog.csdn.net/l_vip/article/details/79156113 引言 serializers是什么?官网是这样的”Serializers allow ...

  2. MT【184】$\epsilon$助力必要性

    已知满足不等式$|x^2-4x+a|+|x-3|\le5$的最大值为$3$,求实数$a$的值,并解该不等式. 证明:1)当$x=3$时,$|a-3|\le5$,得$a\in[-2,8]$2)$\for ...

  3. 【刷题】LOJ 6013 「网络流 24 题」负载平衡

    题目描述 G 公司有 \(n\) 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 \(n\) 个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬运. 输入格式 ...

  4. VUE.JS 窗口发生变化时,获取当前窗口的高度。

    VUE.JS # 窗口发生变化时,获取当前窗口的高度. mounted () { const that = this; window.onresize = () => { return (() ...

  5. [Java] I/O底层原理之二:网络IO及网络编程

    首先我们来看一下当访问一个域名时它的过程 查找 DNS 首先,浏览器检查缓存中有没有 浏览器缓存中没有,则查找操作系统中有没有配置这个对应关系 如果操作系统中也没有,则去 DNS 查找,即发送DNS报 ...

  6. 在CentOS上导出JVM内存信息

    首先看下Tomcat的进程Id: [root@iZ25Z ~]# ps aux | grep java www 2111 4.0 23.5 1637648 452756 ? Sl 10:12 4:35 ...

  7. CentOS6.8下安装Nginx-1.9.15

    1. 简介 Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器. Nginx是一款轻量级的Web服务器/反向代理服务器以及电子邮件代理服务器,并在一个BS ...

  8. bzoj千题计划237:bzoj1492: [NOI2007]货币兑换Cash

    http://www.lydsy.com/JudgeOnline/problem.php?id=1492 dp[i] 表示 第i天卖完的最大收益 朴素的dp: 枚举从哪一天买来的在第i天卖掉,或者是不 ...

  9. Git与GitHub学习笔记(三).gitignore文件忽略和删除本地以及远程文件

    一.Git提供了文件忽略功能.当对工作区某个目录或者某些文件设置了忽略后,git将不会对它们进行追踪 HELP:如何在IntelliJ IDEA中使用.ignore插件忽略不必要提交的文件 问题:最近 ...

  10. [整理]IIS 6.0 下部署 Asp.net MVC Web Api 后 HTTP PUT and DELETE 请求失败

    http://guodong.me/?p=1560 ASP.NET MVC 4 has a new feature called WebAPI which makes it much easier t ...