🐛[优化] 优化tooltip动态位置显示问题,以及为滑块拉动提供显示属性

This commit is contained in:
xumi 2021-12-15 23:53:56 +08:00
parent 81afabf411
commit b704cba9bc
4 changed files with 47 additions and 19 deletions

View File

@ -121,5 +121,7 @@
| position | 显示位置 | `top`(默认值)、`bottom`、`left`、`right` | | position | 显示位置 | `top`(默认值)、`bottom`、`left`、`right` |
| isDark | 是否为黑色主题 | `true`(默认值)、`false`(浅色) | | isDark | 是否为黑色主题 | `true`(默认值)、`false`(浅色) |
| disabled | 是否禁用 | `false`(默认值)、`true`(禁用) || | disabled | 是否禁用 | `false`(默认值)、`true`(禁用) ||
| visible | 控制是否显示 | `true`(默认值)、`false` ||
| isCanHide | 控制是否可以隐藏,可参考`lay-slider`组件 | `true`(默认值)、`false` ||
::: :::

View File

@ -1,5 +1,5 @@
<template> <template>
<transition v-show="visible"> <transition v-show="innerVisible">
<div ref="popper" :class="['layui-popper', {'layui-dark' : innnerIsDark}]" :style="style" :position="innnerPosition"> <div ref="popper" :class="['layui-popper', {'layui-dark' : innnerIsDark}]" :style="style" :position="innnerPosition">
<slot>{{content.value}}</slot> <slot>{{content.value}}</slot>
<div class="layui-popper-arrow"></div> <div class="layui-popper-arrow"></div>
@ -21,18 +21,19 @@
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
el : any, el : any,
content ?: Ref<string>, content ?: Ref<string|Number>,
position ?: Ref<string>, position ?: Ref<string>,
trigger ?: string, trigger ?: string,
enterable ?: boolean, enterable ?: boolean,
isDark ?: Ref<boolean>, isDark ?: Ref<boolean>,
disabled ?: Ref<boolean>, disabled ?: Ref<boolean>,
modelValue ?: boolean visible ?: Ref<boolean>,
isCanHide ?: Ref<boolean>,
updateVisible ?: Function
}>(), }>(),
{ {
enterable : true, enterable : true,
trigger : 'hover', trigger : 'hover'
modelValue : true
} }
); );
@ -53,31 +54,32 @@
const innnerPosition = ref(tempPosition.value); const innnerPosition = ref(tempPosition.value);
const innnerIsDark = ref(props.isDark??true); const innnerIsDark = ref(props.isDark??true);
const innnerDisabled = ref(props.disabled??false); const innnerDisabled = ref(props.disabled??false);
const visible = ref(props.modelValue && !innnerDisabled.value); const innerVisible = ref(props.visible??true);
const emit = defineEmits(['update:modelValue']) watch(innerVisible, (val)=>{
watch(visible, (val)=>{ invokeShowPosistion();
emit('update:modelValue', val); props.updateVisible && props.updateVisible(val);
val && (popper.value.offsetWidth === 0 ? setTimeout(showPosistion, 0) : showPosistion());
}) })
watch(innnerDisabled, (val)=>{ watch(innnerDisabled, (val)=>{
visible.value = false; innerVisible.value = false;
}) })
watch(()=>props.content?.value, (val)=>{ watch(()=>props.content?.value, (val)=>{
visible.value && setTimeout(showPosistion, 5); innerVisible.value && invokeShowPosistion();
}) })
const doShow = function(){ const doShow = function(){
if (!innnerDisabled.value) { if (!innnerDisabled.value) {
visible.value = true; innerVisible.value = true;
} }
} }
const doHidden = function(e : MouseEvent){ const doHidden = function(e : MouseEvent){
if ((checkTarget.value && props.el.contains(e.target)) || (props.enterable && popper.value.contains(e.target as Node))) return; if ((checkTarget.value && props.el.contains(e.target)) || (props.enterable && popper.value.contains(e.target as Node))) return;
style.value = {top: (-window.innerHeight) + 'px',left:0}; // style.value = {top: (-window.innerHeight) + 'px',left:0};
// popper.value.remove(); // popper.value.remove();
visible.value = false; if (props.isCanHide?.value !== false) {
innerVisible.value = false;
}
innnerPosition.value = tempPosition.value; innnerPosition.value = tempPosition.value;
} }
@ -90,7 +92,14 @@
const showPosistion = function(){ const showPosistion = function(){
postionFns[tempPosition.value] && (style.value = postionFns[tempPosition.value](props.el, popper.value, innnerPosition)); postionFns[tempPosition.value] && (style.value = postionFns[tempPosition.value](props.el, popper.value, innnerPosition));
} }
const invokeShowPosistion = function(){
if (innerVisible.value) {
popper.value.offsetWidth === 0 ? setTimeout(showPosistion, 0) : showPosistion();
//
setTimeout(()=>innerVisible.value && showPosistion(), 2);
};
}
onMounted(()=>{ onMounted(()=>{
visible.value && (popper.value.offsetWidth === 0 ? setTimeout(showPosistion, 0) : showPosistion()); invokeShowPosistion();
}) })
</script> </script>

View File

@ -1,4 +1,4 @@
import { h, ref, render, watchEffect} from "vue"; import { h, ref, render, watchEffect, watch} from "vue";
import popper from "./index.vue"; import popper from "./index.vue";
import { once } from "../../tools/domUtil"; import { once } from "../../tools/domUtil";
const EVENT_MAP : any = { const EVENT_MAP : any = {
@ -14,11 +14,20 @@ const usePopper = {
for (const key in props) { for (const key in props) {
_props[key] = ref(props[key]); _props[key] = ref(props[key]);
} }
_props.updateVisible = function(val:boolean) {
_props.visible && (_props.visible.value = val);
}
_this.renderPopper(_props); _this.renderPopper(_props);
watchEffect(() => { watchEffect(() => {
for (const key in _props) { for (const key in _props) {
if (key === 'visible') {
continue;
}
_props[key].value = props[key]; _props[key].value = props[key];
} }
});
watch(() => props.visible, (val: boolean)=> {
_props.updateVisible(val);
}) })
}) })
}, },

View File

@ -5,7 +5,7 @@ export default defineComponent({
name: "LayTooltip", name: "LayTooltip",
props: { props: {
content: { content: {
type: String, type: [Number, String],
required: true, required: true,
}, },
position: { position: {
@ -19,6 +19,14 @@ export default defineComponent({
disabled: { disabled: {
type: Boolean, type: Boolean,
default: false, default: false,
},
visible: {
type: Boolean,
default: true
},
isCanHide: {
type: Boolean,
default: true
} }
}, },
render() { render() {