一、概述
前面的文章 https://mp.weixin.qq.com/s?__biz=MzU5NDM5MDg1Mw==&tempkey=MTA2M19WeHNUZGZ1VHVqRzFZcjZ0S2l0U014cnFwVDRtVkdfQ2dsaTVrOGdEVVU5WjZIUzdnYWR2aklESmoyc3BRMUREanYtQldtMENFSlZQX1lpb091RW1mS3lNYnBGUlhhTzRNUGpUbmh2b3JZVDJoUm5KMlBxbVk5NTlaNVptWnJ2SUF1Z0MwT0dMVUc0a2x6alBZS1RlNWU2UjVpVy1pQlpON19ZYXBBfn4%3D&chksm=7e00beb1497737a70f8df5b6cce5222f8c6c35cdec15438766837cf0d8b4602e0b0cef410fb8#rd
中我们谈到用Vue.extend创建出Vue的子类构造函数后,通过new 得到子类的实例,然后通过$mount挂载到节点,如代码:
<div id="mount-point"></div>
<!-- 创建构造器 -->
var Profile = Vue.extend({
template:'<p>{
{firstName}} {
{lastName}} aka{
{alias}}</p>',
data:function(){
return{
firstName:'Walter',
lastName:'White',
alias:'Heisenberg'
}
}
})
<!-- 创建Profile实例,并挂载到一个元素上 -->
new Profile().$mount('#mount-point');
我们没有讲$mount方法是怎么实现的,这篇文章就来讲一下
二、使用方式
vm.$mount( [elementOrSelector] )
(1)参数
{ Element | string } [elementOrSelector]
(2)返回值
vm,即实例本身。
(3)用法
1、如果Vue.js实例在实例化时没有收到el选项,则它处于“未挂载”状态,没有关联的DOM元素。
2、可以使用vm.$mount手动挂载一个未挂载的实例。
3、如果没有提供elementOrSelector参数,模板将被渲染为文档之外的元素,并且必须使用原生DOM的API把它插入文档中。
4、这个方法返回实例自身,因而可以链式调用其他实例方法。
(4)例子
var MyComponent = Vue.extend({
template:'<div>Hello!</div>',
})
<!-- 创建并挂载到#app(会替换#app) -->
new MyComponent().$mount('#app');
<!-- 创建并挂载到#app(会替换#app) -->
new MyComponent().$mount({
el:'#app'});
<!-- 创建并挂载到#app(会替换#app) -->
var component = new MyComponent().$mount();
document.getElementById('app').appendChild(component.$el);
1、在不同的构建版本中,vm.$mount的表现都不一样。其差异主要体现在完整版(vue.js)和只包含运行时版本(vue.runtime.js)之间。
2、完整版和只包含运行时版本之间的差异在于是否有编译器,而是否有编译器的差异主要在于vm.$mount方法的表现形式。
3、在只包含运行时的构建版本中,vm. m o u n t 的 作 用 如 前 面 所 述 。 而 在 完 整 的 构 建 版 本 中 , v m . mount的作用如前面所述。而在完整的构建版本中,vm. mount的作用如前面所述。而在完整的构建版本中,vm.mount的作用会稍有不同,它首先会检查template或el选项所提供的模板是否已经转换成渲染函数(render函数)。如果没有,则立即进入编译过程,将模板编译成渲染函数,完成之后再进入挂载与渲染的流程中。
4、只包含运行时版本的vm.$mount没有编译步骤,它会默认实例上已经存在渲染函数,如果不存在,则会设置一个。并且,这个渲染函数在执行时会返回一个空节点的VNode,以保证执行时不会因为函数不存在而报错。同时如果是开发环境下运行,Vue.js会触发警告,提示我们当前使用的是只包含运行时的版本,会让我们提供渲染函数,或者去使用完整的构建版本。
5、从原理的角度来讲,完整版和只包含运行时版本之间是包含关系,完整版包含只包含运行时版本。
三、完整版vm.$mount的实现原理
(1)实现代码
const mount = Vue.prototype.$mount;
Vue.prototype.$mount = function(el){
<!-- 做些什么 -->
return mount.call(this,el);
}
1、将Vue原型上的$mount方法保存在mount中,以便后续使用。
2、然后Vu