Browse Source

编辑组件列表优化

dsy 1 week ago
parent
commit
f9824c40b9
1 changed files with 41 additions and 10 deletions
  1. 41 10
      src/views/book/courseware/create/components/CreateCanvas.vue

+ 41 - 10
src/views/book/courseware/create/components/CreateCanvas.vue

@@ -19,7 +19,7 @@
       <span class="drag-line" data-row="-1"></span>
       <!-- 行 -->
       <template v-for="(row, i) in data.row_list">
-        <div :key="i" class="row" :style="computedRowStyle(i)">
+        <div :key="row.row_id || `row-${i}`" class="row" :style="computedRowStyle(i)">
           <el-checkbox
             v-if="row?.row_id"
             v-model="rowCheckList[row.row_id]"
@@ -30,17 +30,17 @@
           <template v-for="(col, j) in row.col_list">
             <span
               v-if="j === 0"
-              :key="`start-${i}-${j}`"
+              :key="`start-${row.row_id || 'r' + i}-${col.col_id || 'c' + j}`"
               class="drag-vertical-line col-start"
               :data-row="i"
               :data-col="j"
             ></span>
-            <div :key="j" :class="['col', `col-${i}-${j}`]" :style="computedColStyle(col)">
+            <div :key="col.col_id || `col-${i}-${j}`" :class="['col', `col-${i}-${j}`]" :style="computedColStyle(col)">
               <!-- 网格 -->
               <template v-for="(grid, k) in col.grid_list">
                 <span
                   v-if="k === 0"
-                  :key="`start-${i}-${j}-${grid.id}`"
+                  :key="`start-${grid.id}`"
                   class="drag-line grid-line drag-row"
                   :style="{ gridArea: 'grid-top' }"
                   :data-row="i"
@@ -50,7 +50,7 @@
                 ></span>
                 <span
                   v-if="grid.row > 1 && grid.row !== col.grid_list[k - 1].row"
-                  :key="`middle-${i}-${j}-${grid.id}`"
+                  :key="`middle-${grid.id}`"
                   :style="{ gridArea: `middle-${grid.grid_area}` }"
                   :data-row="i"
                   :data-col="j"
@@ -59,7 +59,7 @@
                   class="drag-line grid-line"
                 ></span>
                 <span
-                  :key="`left-${i}-${j}-${grid.id}`"
+                  :key="`left-${grid.id}`"
                   :style="{ gridArea: `left-${grid.grid_area}` }"
                   :data-row="i"
                   :data-col="j"
@@ -85,7 +85,7 @@
                   @changeData="changeData"
                 />
                 <span
-                  :key="`right-${i}-${j}-${grid.id}`"
+                  :key="`right-${grid.id}`"
                   :style="{ gridArea: `right-${grid.grid_area}` }"
                   :data-row="i"
                   :data-col="j"
@@ -95,7 +95,7 @@
                 ></span>
                 <span
                   v-if="k === col.grid_list.length - 1"
-                  :key="`end-${i}-${j}-${grid.id}`"
+                  :key="`end-${grid.id}`"
                   class="drag-line grid-line drag-row"
                   :style="{ gridArea: `grid-bottom` }"
                   :data-row="i"
@@ -105,10 +105,20 @@
                 ></span>
               </template>
             </div>
-            <span :key="`end-${i}-${j}`" class="drag-vertical-line col-end" :data-row="i" :data-col="j + 1"></span>
+            <span
+              :key="`end-${row.row_id || 'r' + i}-${col.col_id || 'c' + j}`"
+              class="drag-vertical-line col-end"
+              :data-row="i"
+              :data-col="j + 1"
+            ></span>
           </template>
         </div>
-        <span v-if="i < data.row_list.length - 1" :key="`row-${i}`" class="drag-line" :data-row="i"></span>
+        <span
+          v-if="i < data.row_list.length - 1"
+          :key="`row-${row.row_id || i}`"
+          class="drag-line"
+          :data-row="i"
+        ></span>
       </template>
       <span class="drag-line" :data-row="data.row_list.length - 1"></span>
     </template>
@@ -326,6 +336,8 @@ export default {
     ContentGetCoursewareContent({ id: this.courseware_id }).then(({ content, content_group_row_list }) => {
       if (content) {
         this.data = JSON.parse(content);
+        // 为旧数据补充 row_id / col_id,保证 v-for 使用稳定 key
+        this.normalizeRowColIds();
       }
       if (content_group_row_list) this.content_group_row_list = JSON.parse(content_group_row_list);
 
@@ -1083,6 +1095,7 @@ export default {
     calculateColObject() {
       const id = `ID-${getRandomNumber(12, true)}`;
       const letter = `L${getRandomNumber(6, true)}`;
+      const col_id = `C${getRandomNumber(8, true)}`;
 
       let row = this.data.row_list[this.curRow];
       let col = row.col_list;
@@ -1097,6 +1110,7 @@ export default {
       row.width_list.splice(this.curCol, 0, `${w}fr`);
 
       col.splice(this.curCol, 0, {
+        col_id,
         width: '100fr',
         height: 'auto',
         grid_list: [
@@ -1119,12 +1133,14 @@ export default {
       const id = `ID-${getRandomNumber(12, true)}`;
       const letter = `L${getRandomNumber(6, true)}`;
       const row_id = `R${getRandomNumber(6, true)}`;
+      const col_id = `C${getRandomNumber(8, true)}`;
 
       this.data.row_list.splice(this.curRow + 1, 0, {
         width_list: ['100fr'],
         row_id,
         col_list: [
           {
+            col_id,
             width: '100fr',
             height: 'auto',
             grid_list: [
@@ -1262,6 +1278,21 @@ export default {
       order += gridIndex + 1;
       return order;
     },
+    /**
+     * 归一化 row_list 中的 row_id / col_id(为后端旧数据补 id)
+     */
+    normalizeRowColIds() {
+      if (!this.data || !Array.isArray(this.data.row_list)) return;
+      this.data.row_list = this.data.row_list.map((row, ri) => {
+        if (!row.row_id) row.row_id = `R${getRandomNumber(6, true)}`;
+        if (!Array.isArray(row.col_list)) row.col_list = [];
+        row.col_list = row.col_list.map((col, ci) => {
+          if (!col.col_id) col.col_id = `C${getRandomNumber(8, true)}`;
+          return col;
+        });
+        return row;
+      });
+    },
   },
 };
 </script>