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. ql Server 2012完全卸载方法

    第一步,在控制面板里面找到程序——卸载程序这一项,打开之后就会是这样的了 第二步,经过第一步打开卸载程序后,在里面找到Microsoft SQLserver 2012 (64-bit)这一项,可以通过 ...

  2. bzoj5301[CQOI2018]异或序列

    题意 已知一个长度为 n 的整数数列 a[1],a[2],-,a[n] ,给定查询参数 l.r ,问在 [l,r] 区间内,有多少连续子 序列满足异或和等于 k . 也就是说,对于所有的 x,y (l ...

  3. 【设计模式】—— 备忘录模式Memento

    前言:[模式总览]——————————by xingoo 模式意图 这个模式主要是想通过一个对象来记录对象的某种状态,这样有利于在其他需要的场合进行恢复. 该模式还有跟多可以扩展的地方,比如可以记录多 ...

  4. Java基础整理之字节、数组、字符串、面向对象

    一.字节(8个)8bit = 1B或1byte1024B = 1Kb 二.强制类型转换顺序及其大小顺序遵循向上转换的规则byte,short,char -> int -> long -&g ...

  5. Java 8新特性之 Nashorn(八恶人-6)

    Joe Gage 盖奇·乔 “First time in my life I made a pretty penny.And, figured I'd come home and spend time ...

  6. MT【187】余弦的线性组合

    已知$\alpha+\beta+\gamma=\pi,(\alpha,\beta,\gamma\ge0)$ 求:$3\cos\alpha+4\cos\beta+5\cos\gamma$的最大值____ ...

  7. Graham's Scan法求解凸包问题

    概念 凸包(Convex Hull)是一个计算几何(图形学)中的概念.用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有点的.严谨的定义和相关概念参 ...

  8. non-transactional

    this.getHibernateTemplate().getSessionFactory().getCurrentSession().createQuery(queryString)报错No Hib ...

  9. vue-devtools/安装vue-devtools

    一.在github上下载压缩包,github下载地址:https://github.com/vuejs/vue-devtools 二.解压到本地的某盘 三.用你的npm中进入该文件夹下 在npm中执行 ...

  10. Asp.net MVC3 CSS 模板

    http://www.cnblogs.com/huyq2002/archive/2011/12/16/2289795.html Asp.net MVC3 CSS 模板 如果你现在正在用asp.net ...