上面图片展示了下面的英文句子动态的对齐了他上一级的父元素,怎么实现呢?
解决方法:
<!-- PC端 -->
<div class="gptBox-2" ref="gptBox2Ref" id="gptBox2Id" @click="gptBox2Btn(spans.start, spans.end, spans.label)">
<template v-for="(item, index) in words" :key="index">
<span class="sentence" :id="`${item}${index}`" :style="fontBold(index)" @click="gptWordBrn($event, spans.start, spans.end, spans.label)">{{ item }}</span>
</template>
</div>
</div>
<!-- PC端 -->
<div class="tree-box2" v-if="spans.children.length > 0">
<TreeNode v-for="(node, index) in spans.children" :key="index" :node="node" :words="words" :answerFirstRef="answerFirstRef" />
</div>
<div class="tree-node">
<div class="box-1" ref="box1Ref">
{{ props.node.label }}
</div>
<div class="box-2" ref="box2Ref" :style="changStyle(props.node.label)" :id="`${words[props.node.start]}${props.node.start}`" @click="box2Btn(props.node.start, props.node.end, props.node.label)">
<!-- {{ words.slice(props.node.start, props.node.end).join(' ') }} -->
<span v-for="(item1, index1) in words.slice(props.node.start, props.node.end)" :key="index1" class="box2Word" :style="changeBold(props.node.start + index1, props.node.highlight,props.node.gray)" @click="wordBtn($event, props.node.start, props.node.end, props.node.label)">{{ item1 }}</span>
</div>
<div v-if="props.node.children && props.node.children.length > 0" class="tree-children">
<TreeNode v-for="(childNode, index) in props.node.children" :key="index" :node="childNode" :words="words" :answerFirstRef="answerFirstRef" />
</div>
</div>
首先先给首句子增加动态id,然后给他的子组件传入children的数据,让子组件也是递归渲染出数据。然后就会呈现出上下级关系。
之后怎么动态定位句子位置呢?那就要在子组件加载的时候动态给pina中动态给数组增加元素,这个元素就是每一句首单词的id,要跟首句子的单词id匹配
function findWordPosition() {
// 获取当前单词所在的 DOM 元素
let currentWordElement = box2Ref.value
// console.log(currentWordElement);
if (currentWordElement.id) {
profileStore.indexArray.push(currentWordElement.id)
// console.log(currentWordElement.id);
}
}
之后在父组件中去watch深度监听pina中数据的变化,之后在里面再去首句子找到该元素匹配的id的位置,在给他重新组成一个对象里面是各个元素为key,他的x轴位置就是value.
watch(
() => profileStore.indexArray,
(newVal, oldVal) => {
if (newVal.length > 0) {
console.log(newVal)
const gptBox2Element = gptBox2Ref.value
newVal.forEach(word => {
if (words.value && gptBox2Element) {
let myElement = gptBox2Element.querySelector('#' + word)
if (myElement) {
profileStore.indexObject[word] = myElement.getBoundingClientRect().x
}
}
})
}
},
{ deep: true }
)
之后再去watch这个对象的变化,动态的去给子元素的位置动态变化
watch(
() => profileStore.indexObject,
newVal => {
if (newVal) {
let keys = Object.keys(newVal)
if (keys.length > 0) {
keys.forEach(key => {
let currentWordElement = box2Ref.value
if (currentWordElement.id == key) {
// console.log(key,currentWordElement.getBoundingClientRect().x)
let bothDis = newVal[key] - currentWordElement.getBoundingClientRect().x
// console.log(bothDis);
if (!((bothDis > 5 && bothDis < 6) || bothDis < 0)) {
currentWordElement.style.marginLeft = bothDis + 'px'
box1Ref.value.style.width = box2Ref.value.getBoundingClientRect().width + 'px'
box1Ref.value.style.marginLeft = bothDis + 'px'
box2Ref.value.style.marginLeft = bothDis + 'px'
// if (isAppMoile.value == true) {
// box2Ref.value.style.position = 'absolute'
// }
}
}
})
}
}
},
{ deep: true }
)