看到弹窗,给我的第一印象就是要找popup组件,其次是所在内容的组件。
基础
- 基于vue编写公共popup组件
面临的问题
- 显示隐藏
- 弹窗位置
- 渲染数据
- 组件通信
解决思路
显示隐藏
组件是放在全局的,既然是统一的公共组件,必然就要有统一的调用方法。
首先想到的是统一规范约定的路由参数,通过监听参数变化控制popup的显示和隐藏以及数据的渲染。这种方式的弊端在于,参数加的莫名其妙,我们不需要去记录每一步的弹窗操作,如果在参数较多的情况下,会增加架构设计的复杂度,这种参数变化会显得多余。
1
url?popup=/popupType/:id
第二种解决方案是通过vue组件之间的通信方式,在popup组件内通过bus.$on()监听其他组件通过bus.$emit()触发操作,触发时可以传入需要的参数,在监听的回调可以接收这个参数,然后就能根据参数去做其他事情了。这也是目前的处理方式。
1
2
3
4
5
6
7
8// import Vue from 'vue'
const bus = new Vue()
// 触发
bus.$emit('popup-show', params)
// 监听
bus.$on('popup-show', callback)
// 回收
bus.$off('popup-show')
组件通信
组件之间的通信也是通过vue实例对事件的监听和触发来完成的。这一步操作是在你编写的popup组件内部完成的。
渲染数据
渲染数据是在组件内部完成的,在控制popup显示的时候可以传入需要查询数据的id或其他标识,然后在你编写的组件内部去做数据的渲染处理。
弹窗位置
前面的几点都是基础,这一条才问题的关键。
分析
- 触发popup显示的DOM元素和popup不在一个组件内。也就是说触发popup显示的DOM元素不是唯一的,可以是任意位置。
- 获取DOM元素在浏览器里的绝对位置和相对位置
- 获取popup组件的宽高
- 计算定位
- 监听resize,浏览器窗口大小改变时重新计算定位
抽象组件
- 组件符合开闭原则,可扩展不可修改
- 组件只负责数据,不包含任何业务逻辑