Vue 的构造器——extend 与手动挂载$mount
发布时间:2025-05-19 13:51:22 发布人:远客网络
一、Vue 的构造器——extend 与手动挂载$mount
参考资料:掘金小册《Vue组件精讲》八九课
2.常规组件只能在规定的地方渲染组件,在一些特殊场景就比较局限了,例如:
创建一个Vue实例时,都会有个选项el,来指定实例的根节点,如果不写el选项,那组件就处于未挂载状态。Vue.extend的作用,就是基于Vue构造器,创建一个子类,它的参数跟 new Vue的基本一样,但data要跟组件一样,是个函数,再配合$mount,就可以让组件渲染,并且挂载到任意指定节点,比如body。
实现同样的效果,除了用extend,还可以直接创建Vue实例,并且用Render函数来渲染一个.vue组件。这样既可以用.vue来写复杂的组件,还可以根据需要传入适当的props。渲染后想操作渲染的实例也很简单。
需要注意的是,手动用 mount渲染的组件,要销毁需要用$destroy来手动销毁实例。必要时可以用removeChild把节点从DOM中移除。
三、实战1——如何动态渲染.vue文件的组件
1.接口设计:常规的.vue文件包含3个部分,template、script、style。用extend构造组件实例时,它的选项template就对应<template>部分,其余选项对应<script>部分,样式可以先不管。所以拿到一个.vue文件,只需要把<template>、<script>、<style>分别用正则分割出来,对应传给extend就可以创建实例了。
(1)创建display目录,并新建display.vue文件
(2)父级传递的code被分割,并保存在data的html、js、css中。
(3) this.js是字符串,可以通过 new Function(this.js)转成对象类型
(4)用extend构造实例并挂载到组件的节点上
(5)加载css,就是创建一个style标签,然后把css写进去,再插入到页面的head中。为了便于后面在this.code变化或组件销毁时移除动态创建的style标签,给每个style标签加一个随机id用于标识。
(6)在beforeDestroy钩子中手动销毁extend创建的实例及css
3.这样动态渲染的Display组件可以用来干什么?
比如要写一套Vue组件库的文档,传统方法是在开发环境写一个一个.vue的文件,然后编译打包、上传资源、上线,如果要修改,哪怕一个标点符号,都要重新上线。但是有了Display组件,只需要提供一个服务来在线修改文档的.vue,就能实时更新,不用打包上传、上线。
还可以用来做在线写示例、实时运行的网站。
四、实战2——如何通过命令式调用组件
二、egg.js使用指南
官方教程有点跳跃,很多东西没讲清楚,不太适合小白理解,特此整理、归纳一下。
打开这篇博客的正确方式是:先读一遍官方教程,读不懂的可以略过,然后再带着问题来看这篇文章。然后再回去读官方文档,去理解。最终目的是理解官方文档,我的文章并不权威,只是起到帮助理解文档的作用。
使用koa时,你要写一个项目,要往里面加很多中间件,要写脚本加载routes文件夹下面的所有路由以及model文件夹下面的所有sequelize模型,koa仅仅是一个骨架,其他的都是你来完成,自由度高,但集成度低,每创建一个新项目都要做很多重复工作。egg.js是封装了一套koa,可以理解成大礼包版koa,集成度高,可以轻松创建一个项目而不用做很多繁琐的初期工作,解放生产力,更可贵的是有一套现成的规范提供给我们,不需要我们自己再去探索一套规范,比如router放哪里,controller放哪里,需不需要service,哪些放在service等等。
根据egg.js目录结构先了解其项目规范,为了了解这些目录/文件是做什么,先从我们最熟悉的request讲起:
在进行下面的阅读前请保证已经理解了egg.js中的内置对象。
内置对象可以被方便地获取到,不过功能有限,我们可以通过egg.js的扩展(Extend)功能去进一步加强、定制框架的能力。
egg.js中有非常多新鲜的特性:“扩展”、“插件”、“多环境配置”,这些特性名称虽然不一样,但本质都是一样的:有则覆盖,无则增加。类似于 lodash中的defaults函数,也类似于继承。
因此,如果我们想扩展Application对象,根据egg.js规范,应该在projectDir/app/extend/下增加application.js:
以后就可以方便地调用 app.specialName获取这个值。
Extend特性可以扩展上层框架的内置对象,而插件则可以扩展除router和controller之外的整个app。插件拥有自己的package.json,因此可以独立发布到npm,每个人都可以install,享用你的扩展。
如果我要为项目写一个管理微信公众号的功能,我会写一个WxService:
很多项目都可以用到这个Service,因此我会提取为一个插件,然后通过引入插件的形式去引入,我在应用中同样可以调用这个Service,等于是把插件中的文件往应用中复制了一份,和写在应用中没什么两样。
关于如何提取插件,请参见:渐进式开发
定制自己的框架可以确定项目的技术选型、减少项目初期的工作,定制框架的思想其实和扩展内置对象、开插件是一样的,但是前置工作会比较多一些,参见: egg.js框架开发。
这些前置工作比较重复、有固定格式,没有必要自己写,建议用骨架搭建。
当我们基于自己定制的框架framework1,并且在应用中依赖了插件plugin2、plugin3,开发了一个应用:
其中framework1直接基于egg并且内置了plugin1,此时整个app的加载顺序是怎样的呢?
加载原则总结一句话是:从被依赖到依赖。
先来分析一下,谁被依赖,谁依赖:
为了最大程度利用多核、增强Node进程健壮性,一般我们会使用PM2一类的工具,如果使用egg.js,就完全不需要担心了,egg利用cluster模块(了解cluster原理请看这篇文章)已经创建了一个非常稳定的多进程模型。