项目中使用到element UI组件库中的el-tooltip,发现用的时候会产生多个dom,为了改善这个问题就对其进行了封装(其实也是找的网上别的大佬的封装代码嘻嘻。
封装是参考的这篇帖子基于el-tooltip二次封装的tool-tip-ellipsis全局气泡提示 - 掘金
然后我就遇到了问题
报错是这样的:
大致意思就是说在子组件中改变了父组件传过来的prop里的值,我就很郁闷,因为我一开始也不知道是哪里改掉了父组件的值,这个组件的封装的原理就是将一个el-tooltip的组件的实例对象存储起来,后续通过鼠标事件去改这个实例对象的挂在dom及显示内容,所以我一直不明白哪里有父组件,后续通过访问保存起来的实例对象发现了父组件,然后通过触发父组件的函数改变content的值,就不用报错啦~
App.vue
<template>
<div id="app" >
<router-view />
<global-template-tool-tip></global-template-tool-tip>
</div>
</template>
<script>
import globalTemplateToolTip from '@/components/GlobalTooltip.vue'
GlobalTooltip.vue
<template>
<el-tooltip
ref="globalTemplateTip"
:content="toolTipContent"
@init="init"
:placement="toolTipPlacement"
popper-class="apple-tip"
>
</el-tooltip>
</template>
<script>
export default {
components: {
},
data() {
return {
toolTipContent: '',
toolTipPlacement: '',
}
},
methods: {
init(a,b){
this.toolTipContent=a
this.toolTipPlacement=b
}
},
mounted() {
//注册全局组件
this.$store.commit('MOUNT_TOOL_TIP', this.$refs.globalTemplateTip)
},
}
</script>
<style>
</style>
tool.js---vuex文件
import debounce from "throttle-debounce/debounce";
export default {
state: {
toolTip: {},
},
mutations: {
MOUNT_TOOL_TIP(state, node) {
state.toolTip = node
},
// 初始化
INIT_TOOL_TIP(state, obj) {
let activateTooltip = debounce(50, (tooltip) =>
tooltip.handleShowPopper()
)
state.toolTip.referenceElm = obj.node
// 先消掉之前的
state.toolTip.$refs.popper && (state.toolTip.$refs.popper.style.display = 'none')
state.toolTip.doDestroy()
// 设置组件内的条件变量为true,否则无法调用handleClosePopper
state.toolTip.setExpectedState(true)
// 展示新的tool-tip
activateTooltip(state.toolTip)
//直接修改会出发修改prop属性警告 所以这里不能直接修改state.tooltip的内容
// 填入内容及设置位置
state.toolTip.$parent.init(obj.contentText,obj.placementText)
},
// 关闭
CLOSE_TOOL_TIP(state) {
state.toolTip.setExpectedState(false)
state.toolTip.handleClosePopper()
}
},
actions: {
}
}
这个就是自己封装的组件文件-----my-tooltip.vue
<template>
<div @mouseenter="tipBoxEnter($event)" @mouseleave="tipBoxLeave($event)">
<p class="too-tip-content-p">
<slot></slot>
</p>
</div>
</template>
<script>
export default {
props: {
// 内容
toolTipContent: {
type: String,
default: '',
},
// 位置
placement: {
type: String,
default: 'top',
},
},
data() {
return {
contentText: this.toolTipContent,
toolTipContentText: '',
toolTipPlacement: '',
}
},
watch: {
},
mounted(){
},
methods: {
tipBoxEnter(e) {
// 获取挂载的p标签
let p_Node = e.target.querySelector('.too-tip-content-p')
// 初始化全局toolTip
this.$store.commit('INIT_TOOL_TIP', {
node: p_Node,
contentText: this.contentText,
placementText: this.placement,
})
},
tipBoxLeave(e) {
// 销毁toolTip
this.$store.commit('CLOSE_TOOL_TIP')
},
},
}
</script>
<style lang="scss" scoped>
.too-tip-content-p {
padding: 0;
margin: 0;
text-overflow: ellipsis;
overflow: hidden;
}
</style>
组件中使用
<my-tooltip
class="item"
popper-class="list-tip"
effect="dark"
:toolTipContent="点击"
placement="top"
>
<div
id="shop"
>aaa</div>
</my-tooltip>
完结~撒花~