1.问题复现场景
拿官网实例截个图说明一下
由于需要替换第三方插件的颜色选择器,所以打算用element-ui
直接替换,故在第三方插件初始化颜色选择器的类中返回element-ui
的color-picker
组件
typescript
import { ColorPicker } from 'element-ui';
class ColorController {
constructor(parent, object, property, rgbScale) {
const Picker = Vue.extend(ColorPicker)
const instance = new Picker({
propsData: {
value: object[property],
showAlpha: true
}
})
instance.$on('change', (v) => {
console.log('color-change', v)
this._setValueFromHexString(v);
})
let div = document.createElement('div')
this.$widget.appendChild(div) // this.$widget为第三方插件生成颜色选择器的dom节点
instance.$mount(div)
}
... // 省略第三方插件其他源代码
}
2.问题根源
1.el-color-picker
颜色选择器弹窗基于父级组件dom动态计算所在位置,显示定位; 2.由于第三方插件ColorController
类构造函数内生成el-color-picker
组件实例所挂载的dom节点被替换,导致获取到this.$parent.$el
为空,在渲染颜色选择器弹窗时,无法得到有效的位置,所以弹窗只能显示在页面左上角
3.解决方案
1.自定义一个颜色选择器组件,导入el-color-picker
组件进行包装套壳,确保颜色选择器弹窗能获取正确的父级节点
xml
// 自定义颜色选择器组件 color-picker
<template>
<div class="color-picker">
<ColorPicker v-model="color" :showAlpha="showAlpha"></ColorPicker>
</div>
</template>
<script>
import { ColorPicker } from 'element-ui';
export default {
name: 'color-picker',
props: {
value: {
type: String,
default: '#ffffff',
},
showAlpha: {
type: Boolean,
default: true
}
},
components: {
ColorPicker,
},
data() {
return {
};
},
computed: {
color: {
get() {
return this.value;
},
set(val) {
this.$emit('change', val);
},
},
},
methods: {},
};
</script>
<style lang="scss" scoped>
.color-picker {
background-color: transparent;
}
</style>
2.修改第三方组件库ColorController
类
javascript
import ColorPicker from './color-picker.vue'; // 引入包装过的自定义组件
class ColorController {
... // 其它代码保持不变
}