You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3中编辑表单时autocomplete组件无法回显已保存值的问题

Vue3 CRUD表格中vue3-simple-typeahead回显问题解决

问题描述

我正在开发一个可复用的CRUD表格,整体进展顺利,但遇到了autocomplete组件的问题:用vue3-simple-typeahead实现国家选择功能后,编辑表格行时,该组件无法回显已保存的国家值,之前选中的国家会消失。

问题根源

  • 未绑定初始值:simple-typeahead组件没有绑定当前行已保存的国家值,进入编辑模式后无初始回显内容。
  • 数据同步缺失:仅通过onBlur事件更新数据,没有双向绑定同步组件值与行数据。
  • 模板循环冗余:formData循环嵌套在header循环内,渲染逻辑混乱,影响组件正确绑定。

修改方案

1. 给simple-typeahead添加双向绑定

在CrudTable.vue中,为组件绑定v-model到当前行的country字段,调整事件监听确保数据实时同步。

2. 简化模板循环结构

移除不必要的formData嵌套循环,直接通过字段匹配表单类型,优化渲染逻辑。

3. 修正编辑模式的数据处理

确保切换编辑模式时,行数据的country字段保留已保存的正确值。

修改后的代码

CrudTable.vue(关键修改部分)

<template>
    <div>
        <table>
            <thead>
                <tr>
                    <th v-for="h in headers" :key="h.field" v-html="h.label"></th>
                    <th></th>
                </tr>
            </thead>

            <tbody>
                <tr v-for="(r, rowIndex) in rows" :key="r.id || rowIndex">
                    <!-- 查看模式 -->
                    <td v-if="!r.edit" v-for="h in headers" :key="h.field" v-html="renderTable(h, r)"></td>

                    <!-- 编辑模式 -->
                    <td v-if="r.edit" v-for="h in headers" :key="h.field">
                        <!-- 文本输入框 -->
                        <input
                            v-if="getFormType(h.field) === 'text'"
                            type="text"
                            :name="h.field"
                            :id="h.field"
                            v-model="r[h.field]"
                            :disabled="getFormDisabled(h.field)"
                            class="form-control">

                        <!-- 自动完成组件 -->
                        <simple-typeahead
                            v-if="getFormType(h.field) === 'autocomplete'"
                            class="form-control"
                            :id="`typeahead_${r.id}_${h.field}`"
                            :items="countryOptions"
                            v-model="r[h.field]"
                            @input="editChanges(r.id, h.field, $event)"
                        >
                        </simple-typeahead>
                    </td>

                    <!-- 操作列 -->
                    <td>
                        <div class="dropdown">
                            <button class="btn btn-default" type="button" data-bs-toggle="dropdown" aria-expanded="false">
                                <i class="fa fa-ellipsis-h"></i>
                            </button>
                        
                            <ul class="dropdown-menu">
                                <li v-for="a in actions" :key="a.label">
                                    <a 
                                        :class="'dropdown-item'" 
                                        href="#" 
                                        @click.prevent="a.action(r, !r.edit)"
                                        v-show="(a.edit && r.edit) || (!a.edit && !r.edit)"
                                    >
                                        <i :class="a.icon"></i> {{ a.label }}
                                    </a>
                                </li>
                            </ul>
                        </div>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</template>

<script setup>
import SimpleTypeahead from 'vue3-simple-typeahead';
import 'vue3-simple-typeahead/dist/vue3-simple-typeahead.css';

const props = defineProps({
    headers: Array,
    rows: Array,
    countryOptions: Array,
    formData: Array,
    actions: {
        type: Array,
        default: []
    },
});

const emit = defineEmits(['editTableRow']);

const renderTable = (header, row) => {
    return row[header.field];
}

// 根据字段获取表单类型
const getFormType = (field) => {
    const formItem = props.formData.find(item => item.field === field);
    return formItem ? formItem.type : '';
}

// 根据字段获取是否禁用
const getFormDisabled = (field) => {
    const formItem = props.formData.find(item => item.field === field);
    return formItem ? formItem.disabled : false;
}

const editChanges = (id, fieldName, value) => {
    emit('editTableRow', {
        id: id,
        field: fieldName,
        value: value
    });
}
</script>

Index.vue(关键修改部分)

<script>
export default{
    // ... 其他代码不变
    methods: {
        // ... 其他方法不变
        editRow(row, edit) {
            row.edit = edit;
            // 移除无关的role赋值逻辑,确保country字段保留原始值
        },
    }
}
</script>

内容的提问来源于stack exchange,提问作者Starla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 12:37:25