fix(商品): 添加规格值改行内输入并修复隐藏页签 SKU 行裁切

This commit is contained in:
From-wh 2026-10-16 16:42:36 +08:00 committed by 吴昊天
parent a2c423a860
commit 4e56f2fece
2 changed files with 31 additions and 40 deletions

View File

@ -69,7 +69,6 @@
@handleBlur="handleBlur"
@handleSelImg="handleSelImg"
@handleRemoveImg="handleRemoveImg"
@handleShowPop="handleShowPop"
@createAttr="createAttr"
@handleAddRole="handleAddRole"
@handleSaveAsTemplate="handleSaveAsTemplate"
@ -747,9 +746,6 @@ function handleSelImg(item) {
function handleRemoveImg(item) {
item.pic = '';
}
function handleShowPop(index) {
specStock.value.$refs['inputRef_' + index][0].focus();
}
function handleAddRole() {
attrs.value.push({
value: formDynamic.value.attrsName,
@ -775,6 +771,7 @@ function handleSaveAsTemplate() {
})
.catch(() => {});
}
// 添加属性(行内输入框回车/失焦触发,num 为空时忽略)
function createAttr(num, idx) {
if (num) {
const isExist = attrs.value[idx].detail.some((item) => item.value === num);
@ -788,10 +785,7 @@ function createAttr(num, idx) {
} else {
generateAttr(attrs.value);
}
specStock.value.$refs['popoverRef_' + idx][0].doClose();
clearAttr();
} else {
specStock.value.$refs['popoverRef_' + idx][0].doClose();
}
}
function addOneAttr(val, val2) {

View File

@ -105,25 +105,18 @@
</div>
</template>
<template #footer>
<el-popover
:ref="'popoverRef_' + index"
placement="bottom"
width="210"
trigger="click"
@after-enter="handleShowPop(index)"
>
<div class="mr10 spec" v-if="addingIndex === index">
<el-input
:ref="'inputRef_' + index"
placeholder="请输入规格值"
ref="attrInputRef"
style="width: 120px"
placeholder="规格值"
v-model="formDynamic.attrsVal"
@keyup.enter="createAttr(formDynamic.attrsVal, index)"
@blur="createAttr(formDynamic.attrsVal, index)"
@keyup.enter="onAttrEnter(index)"
@blur="onAttrBlur(index)"
maxlength="30"
show-word-limit
>
</el-input>
<template #reference><div class="addfont" type="text" v-db-click>添加规格值</div></template>
</el-popover>
></el-input>
</div>
<div class="addfont" type="text" v-db-click v-else @click="clickAddAttr(index)">添加规格值</div>
</template>
</draggable>
</div>
@ -140,15 +133,8 @@
</el-col>
<el-col :span="24" v-if="formValidate.spec_type === 1">
<el-form-item label="商品属性:" class="labeltop" v-if="manyFormValidate.length">
<VirtualScroll
class="spec-table-scroll"
:data="manyFormValidate"
:buffer="50"
:height="62"
key-prop="index"
@change="(renderData) => (virtualList = renderData)"
>
<!-- <el-table row-key="id" :data="virtualList" height="500px"> </el-table> -->
<!-- 表格使用完整数据和原生滚动,避免隐藏页签中的虚拟滚动高度缓存裁切 SKU 行。 -->
<div class="spec-table-scroll">
<el-table
row-key="index"
max-height="700px"
@ -419,7 +405,7 @@
</template>
</el-table-column>
</el-table>
</VirtualScroll>
</div>
</el-form-item>
</el-col>
<!-- ------------------------------------------------- -->
@ -592,9 +578,8 @@
</template>
<script setup>
import { ref } from 'vue';
import { nextTick, ref } from 'vue';
import draggable from 'vuedraggable';
import VirtualScroll from './virtualTabel.vue';
defineOptions({ name: 'SpecStock' });
@ -652,7 +637,6 @@ const emit = defineEmits([
'attrDetailChangeValue',
'handleBlur',
'attrChangeValue',
'handleShowPop',
'handleSelImg',
'handleSaveAsTemplate',
'addGoodsCoupon',
@ -664,8 +648,6 @@ const emit = defineEmits([
'createAttr',
]);
const virtualList = ref([]);
// vuedraggable4 item-key(数据无唯一 id,用索引)
const attrItemKey = (element) => props.attrs.indexOf(element);
// key 必须稳定:若直接用 element.value 作 key,输入时值一变节点即被重建导致输入框失焦
@ -718,8 +700,23 @@ function handleBlur(e) {
function attrChangeValue(val, index) {
emit('attrChangeValue', val, index);
}
function handleShowPop(e) {
emit('handleShowPop', e);
// 行内添加规格值:点击后原位出现输入框,回车提交并继续输入,失焦收起
const addingIndex = ref(-1);
const attrInputRef = ref();
function clickAddAttr(index) {
addingIndex.value = index;
nextTick(() => {
// 输入框在外层 v-for 内,ref 为数组;同一时刻只有一个输入框存在
const inst = Array.isArray(attrInputRef.value) ? attrInputRef.value[0] : attrInputRef.value;
inst?.focus?.();
});
}
function onAttrEnter(index) {
emit('createAttr', props.formDynamic.attrsVal, index);
}
function onAttrBlur(index) {
emit('createAttr', props.formDynamic.attrsVal, index);
addingIndex.value = -1;
}
function handleSelImg(e) {
emit('handleSelImg', e);