Organized by:安南City
Completion time:2020-05-13
Send error to email:city@nanzc.com
Description在最近开发个人博客时,少不了用到命令式弹窗组件,于是...
顺便记录下吧。
要实现命令式弹窗组件,需要涉及: Vue.extend、vm.mount、vm.el
涉及知识
Vue.extend( options )
params:
options{Object}- 组件选项的对象
使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。
如果 Vue 实例在实例化时没有收到
el选项,则它处于“未挂载”状态,没有关联的 DOM 元素。可以使用
vm.$mount()手动地挂载一个未挂载的实例。
vm.$mount( [elementOrSelector] )
params:
[elementOrSelector]{Element | String}- 元素或选择器
[hydrating]{boolean}return:
vm- 实例自身
可以使用该方法手动挂载一个未挂载的实例。
如果没有提供 elementOrSelector 参数,模板将被渲染为文档之外的的元素,并且你必须使用原生 DOM API 把它插入文档中。
这里在后面代码中,我们将采用原生 API 插入文档末尾。
当然你也可以直接提供
elementOrSelector参数,那就无需使用vm.$el。
vm.$el
type:
Element
Vue 实例使用的根 DOM 元素。
使用
vm.$mount()手动挂载后,并且没有提供elementOrSelector参数,需要手动插入文档。还有一个知识,将在使用组件时讲到,为了可读流程就暂不讲。
这里我们将以一个简洁的提示框为例。
目录结构
- message:组件目录
- index.vue:组件布局、样式、交互逻辑
- index.js: 组件实例化、挂载方法、暴露安装函数
组件规划
这是一个命令式调用组件,所以我们需要定义形参
| 形参 | key | 说明 | 默认值 |
|---|---|---|---|
| options | |||
| title | 提示信息 | "" | |
| time | 存在时间 (ms) | 4000 |
代码实践
由于这里只是示例,我就不过多解释了,大家拿出平时的基操就行。
具体重点看代码中文注释(英文注释的作用就是练单词)。
自由编码没有固定的格式,练的就是随机应变。
-
index.vue
/** * @author City * @description 消息组件 * TODO: 这里仅供参考,不细封。 */ <template> <div class="message" :style="{top}">{{title}}</div> </template> <script> export default { name: "Message", data() { return { /* style */ top: "-40px" /* params */ // 1.可传参数 // 不传则为此处定义默认值,传递将被使用的 Object.assign() 方法覆盖; title: "", time: 4000, }; }, methods: { /* show message */ // 2.show 方法将在初始化实例挂载组件、DOM 追加到文档之后调用 show() { // trigger start transition setTimeout(() => { this.top = "40px"; }, 50); // time out hide setTimeout(() => this.hide(), this.time - 1000); }, /* hide message */ hide() { // trigger end transition this.top = "-40px"; // destroy component setTimeout(() => { // 3.删除 DOM 节点,并销毁组件 document.body.removeChild(this.$el); this.$destroy(); }, 1000); } } }; </script> <style lang="stylus" scoped> .message position fixed top -40px right 80px z-index 1001 padding 0 30px height 40px line-height @height border-radius 15px transition top 1s text-align center background #3d86af color white </style>这里没有使用
mounted生命周期,而是在命令调用组件时触发show方法,当然你可以不这样。 -
index.js
/** * @author City * @description 组件实例化 挂载方法 暴露安装函数 */ import Vue from "vue"; import message from "./index.vue"; /* extend message create constructor */ // 1.创建组件构造函数 const MessageConstructor = Vue.extend(message); /* init instance function */ const init = options => { // instantiation constructor // 2.实例化组件 const instance = new MessageConstructor(); // merge data property // 3.将传递参数直接覆盖原实例 data 定义参数 Object.assign(instance, options); // create virtual DOM and append to document // 4.渲染为文档之外元素,也可理解为虚拟 DOM,然后追加到文档 document.body.appendChild(instance.$mount().$el); // return this instance // 5.返回组件实例 return instance; }; /* caller */ // 5.创建命令调用函数,并接受参数 // 形参需要为对象形式,并且命名需要和 data 定义参数一致,当然你也可以细化封装 const caller = options => { // init instance // 6.初始化 DOM const instance = init(options); // call show function // 7.调用实例 show 方法 instance.show(); }; /* export install function */ // 8.导出安装方法 export default function(vue) { // 9.在 Vue 原型上挂载命令调用函数 vue.prototype.$message = caller; };这里面重点为 传参方式 体现在第
3步。这里封装的并不是很好,这里为了示例没有修改,按照实际需求走就行。
使用组件
使用组件需要知道 Vue.use() 方法的知识。
Vue.use( plugin )
params:
plugin{Object | Function}
安装 Vue.js 插件。如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。
该方法需要在调用 new Vue() 之前被调用。
当 install 方法被同一个插件多次调用,插件将只会被安装一次。
这里我们就直接在 main.js 中使用,你也可以在项目中将UI当做插件引入,在UI中处理组件 install 方法。
-
main.js
import massage from "./components/massage"; // 示例目录 // ... Vue.use(massage) // ...
命令式调用组件
this.$message({title: "信息内容"})
好了调用就是这么简单,还一个 time 我们不传则为默认值。