1.问题背景
主要是自己写了一个组件库,其中涉及到弹出面板的组件遇到兼容性问题。
举个例子,
日期选择组件例如 DaterPicker组件
大概的代码如下(省略了细节实现)
<template>
<label>日期</label>
<input />
<Calendar v-if='' />
</template>
<script></script>
主要是点击input,然后弹出Calendar组件用来选择日期,然后回显到input里,
然后这个组件就可以单独使用了,
当然样式上Calendar必须用position:fixed,z-index:9999,然后出现时计算位置,
否则当这个组件的父元素时overflow:hidden时会遮住。。。
but
在chrome49中,无效。。。。无论如何,都还是会遮住(除非overflow不写,默认visible)
2.分析问题
问题的根源出在将Calendar组件写在DaterPicker组件内部
之所以要写在内部,主要是需要实现组件化,
也考虑过将Calendar组件放在全局的app根组件下,然后通过vuex或者data透传控制
但是这样就无法实现组件化了。。。
遇到问题可以学习一下其他组件库是如何处理的,
打开elementUI官网,查看date-picker组件,f12,点击弹出的日期选择器,
发现居然是独立的vue实例,也就是说,在点击弹出日期选择器的时候,elementUI对body上添加了一个元素并挂在了vue实例然后渲染了日期选择器组件上去
思路有了,现在还有几个问题,
如何实现Vue实例挂载
实现挂载后如何与Calendar组件通信
其他问题例如滚动检测,位置处理都是常规问题此处不展开了(顺便一提,elementUI的焦点检测即何时关闭弹窗用的是mouseup不在弹出面板上,感兴趣的可以试一下)
3.实现vue多实例及其通信
2中提到的两个问题
如何实现Vue实例挂载
看下main.js就清楚了
new Vue({
render: h => h(Calendar)
}).$mount('#id')
以上方法可以实现组件挂载到元素上
实现挂载后如何与Calendar组件通信
其实仅仅是props传递的问题,props可以传递任何东西,包括值,方法,甚至对象。
<template>
<label>日期</label>
<input @click= />
</template>
<script>
....
methods:{
getDate(v){
this.date=v
},
openCalendar(){
let _this=this;
//把实例赋值给组件,以便后续销毁时也可以释放
this._dateVue=new Vue({
render: h => h(Calendar,{
props:{
//发挥你的想象力吧,
getDate:_this.getDate //date-picker获取选择的日期函数
config:_this.calendarConfig //calendar的位置,包括left,top...
}
})
}).$mount('#id')
}
</script>
4.总结
通过vue手动挂载实例,并通过render函数传递props进行组件通信的方式,可以实现任意的弹出面板,兼容性强,不用考虑烦人的overflow问题。