Browse Source

弃用 v-unwrap(异步数据/重复渲染下锚点同步会错位 => 子选项卡点了不变或堆积); 改为保留宿主 div(已核 #root 结构无 CSS 依赖, 对拍工具仍按透明处理); 验证 5 个子视图元素数回落 1126/13/3398/626/543

zhouyang.xie 6 days ago
parent
commit
89016b3de1

+ 19 - 13
app_frontEnd/web/src/lib/unwrap.ts

@@ -15,32 +15,38 @@
  */
 import type { Directive } from 'vue'
 
-const ANCHORS = new WeakMap<Element, Comment>()
+interface Rec { a: Comment; nodes: Node[] }
+const ANCHORS = new WeakMap<Element, Rec>()
 
 function unwrap(el: Element): void {
   const parent = el.parentNode
   if (!parent) return
-  const anchor = document.createComment('v-unwrap')
-  ANCHORS.set(el, anchor)
-  parent.insertBefore(anchor, el)
-  while (el.firstChild) parent.insertBefore(el.firstChild, anchor)
+  const rec: Rec = { a: document.createComment('v-unwrap'), nodes: [] }
+  ANCHORS.set(el, rec)
+  parent.insertBefore(rec.a, el)
+  while (el.firstChild) { const n = el.firstChild; parent.insertBefore(n, rec.a); rec.nodes.push(n) }
   parent.removeChild(el)
 }
 
-/** 把宿主当前(Vue 刚写入的)子节点移到锚点之前。 */
+/** 把宿主当前(Vue 刚写入的)子节点移到锚点之前;**先移除上次同步的节点**(否则旧子视图会堆积)。 */
 function resync(el: Element): void {
-  const anchor = ANCHORS.get(el)
-  const parent = anchor && anchor.parentNode
-  if (!anchor || !parent) return
-  while (el.firstChild) parent.insertBefore(el.firstChild, anchor)
+  const rec = ANCHORS.get(el)
+  const parent = rec && rec.a.parentNode
+  if (!rec || !parent) return
+  for (const n of rec.nodes) if (n.parentNode === parent) parent.removeChild(n)
+  rec.nodes = []
+  while (el.firstChild) { const n = el.firstChild; parent.insertBefore(n, rec.a); rec.nodes.push(n) }
 }
 
 export const vUnwrap: Directive<HTMLElement> = {
   mounted: (el) => unwrap(el),
   updated: (el) => resync(el),
   beforeUnmount: (el) => {
-    const anchor = ANCHORS.get(el)
-    if (anchor && anchor.parentNode) anchor.parentNode.removeChild(anchor)
-    ANCHORS.delete(el)
+    const rec = ANCHORS.get(el)
+    if (rec) {
+      const parent = rec.a.parentNode
+      if (parent) { for (const n of rec.nodes) if (n.parentNode === parent) parent.removeChild(n); parent.removeChild(rec.a) }
+      ANCHORS.delete(el)
+    }
   },
 }

+ 1 - 1
app_frontEnd/web/src/views/Assistant.vue

@@ -36,7 +36,7 @@ const hotHtml = computed(() => HOT.map((c) => `<a href="#" data-code="${c}">${c}
       <div :style="row">
         <input id="asstIn_fault" :placeholder="esc(t('asst.code_placeholder'))" :value="ASST.fault" style="flex:1 1 220px">
         <button class="btn" data-asst="fault">{{ t('ui.query') }}</button>
-        <span class="small muted">{{ t('asst.common') }} <span v-unwrap class="unwrap-host" v-html="hotHtml"></span></span>
+        <span class="small muted">{{ t('asst.common') }} <span class="unwrap-host" v-html="hotHtml"></span></span>
       </div>
       <div id="asstOut_fault" style="margin-top:10px">{{ ASST.out.fault }}</div>
     </div>

+ 1 - 1
app_frontEnd/web/src/views/Decision.vue

@@ -76,7 +76,7 @@ const mdlNoteHtml = computed(() => (effectiveModel.value ? mdlNote(effectiveMode
     <div class="panel mb">
       <h3>{{ t('ask.common_q', { cat: catName }) }}</h3>
       <p class="small muted">{{ t('cat.' + cat + '.hint') }}{{ '。' }}{{ t('ask.grounding') }}</p>
-      <div v-html="qs" v-unwrap class="unwrap-host"></div>
+      <div v-html="qs" class="unwrap-host"></div>
       <div style="display:flex;gap:8px;flex-wrap:wrap;margin:10px 0;align-items:center">
         <input id="askq" type="text" :placeholder="esc(t('ask.placeholder', { cat: catName }))" :value="q" style="flex:1;min-width:280px">
         <label class="small muted" for="askm">{{ t('ask.model') }}</label>

+ 1 - 1
app_frontEnd/web/src/views/Vibration.vue

@@ -50,6 +50,6 @@ const bodyHtml = computed(() => {
       <button v-for="s in FUS_SUBS" :key="s" class="pill" :class="{ on: s === sub }" :data-fsub="s"
               @click="emit('sub', s)">{{ t('fus.sub.' + s) }}</button>
     </div>
-    <div v-unwrap class="unwrap-host" v-html="bodyHtml"></div>
+    <div class="unwrap-host" v-html="bodyHtml"></div>
   </section>
 </template>

File diff suppressed because it is too large
+ 0 - 0
release/web/assets/index-DFf4k-UW.js


+ 1 - 1
release/web/index.html

@@ -4,7 +4,7 @@
   <meta charset="utf-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1" />
   <title>观澜 · 风电数据分析与决策支持</title>
-  <script type="module" crossorigin src="/web/assets/index-Cr3KcuZc.js"></script>
+  <script type="module" crossorigin src="/web/assets/index-DFf4k-UW.js"></script>
   <link rel="stylesheet" crossorigin href="/web/assets/index-DFl-J_Hd.css">
 </head>
 <body>

Some files were not shown because too many files changed in this diff