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

如何在Vue3中使用useForm动态创建表单元素并绑定表单数据

解决方案

核心问题说明

你当前通过原生DOM API手动创建输入元素的方式,无法被Vue响应式系统识别,自然不能实现双向绑定。同时初始化的useForm仅配置了单组固定字段,无法存储多组动态生成的输入数据。

改造步骤

第一步:调整useForm初始化结构

将单组字段改为支持多组存储的数组结构:

setup() {
    const form = useForm({
        title: null,
        regions: [] // 所有动态输入组都存在这个数组中,每组包含selectedText、start、stop三个字段
    })
    return {form}
}

第二步:修改模板为动态列表渲染

把region_block内硬编码的固定region块删除,替换为v-for循环渲染:

<div id="region_block" ref="reg_block" >
    <div class="region" v-for="(region, index) in form.regions" :key="region.id">
        <div class="regionTitle" :style="{color: region.titleColor, fontWeight: 'bold'}">
            {{ region.id }}
        </div>
        <div class="copyTextButton">
            <Button @click="getText(index)" type="button" class="inline-flex items-center px-4 py-2 bg-gray-800 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 active:bg-gray-900 focus:outline-none focus:border-gray-900 focus:ring focus:ring-gray-300 disabled:opacity-25 transition">Copy Marked Text</Button>
        </div>
        <div class="pp_new_transcript flex flex-col">
            <label style="font-weight: bold">
                New Transcript:
            </label>
            <textarea rows="5" class="selectedTextInput h-full" v-model="form.regions[index].selectedText" />
        </div>
        <div class="pp_start-stop">
            <label for="start" style="font-weight: bold">
                Start:
            </label>
            <input v-model="form.regions[index].start" disabled/>
            <label for="stop" style="font-weight: bold">
                Stop:
            </label>
            <input v-model="form.regions[index].stop" disabled/>
        </div>
        <div class="submit_button">
            <Button class="inline-flex items-center px-4 py-2 bg-gray-800 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 active:bg-gray-900 focus:outline-none focus:border-gray-900 focus:ring focus:ring-gray-300 disabled:opacity-25 transition">Submit</Button>
        </div>
    </div>
</div>

第三步:替换手动创建DOM的逻辑

删除region-created事件中所有手动创建DOM的代码,改为往regions数组新增对象:

wavesurfer.on('region-created', (region, e) => {
    const color = () => Math.random() * 256 >> 0;
    const r = color(), g = color(), b = color()
    this.form.regions.push({
        id: region.id,
        selectedText: '',
        start: region.start,
        stop: region.end,
        titleColor: `rgb(${r},${g},${b})`
    })
    region.color = `rgba(${r},${g},${b}, 0.1)`
})

第四步:改造方法适配多组数据

修改方法支持按索引更新对应组的数据:

methods: {
    getText(index) {
        this.newTranscript = window.getSelection().toString();
        this.form.regions[index].selectedText = this.newTranscript;
        this.form.title = this.title;
    },
    copyValues(index, start, stop) {
        this.form.regions[index].start = start;
        this.form.regions[index].stop = stop;
    },
    // 剩余goBack方法不变
}

第五步:适配region点击事件

点击region时找到对应索引更新时间:

wavesurfer.on('region-click', (region, e) => {
    e.stopPropagation();
    if (play) {
        wavesurfer.pause();
        play = false;
    } else {
        region.play();
        play = true;
    }
    // 找到当前region对应的数组索引
    const activeIndex = this.form.regions.findIndex(item => item.id === region.id)
    if(activeIndex > -1) {
        this.copyValues(activeIndex, region.start, region.end);
    }
});

提交说明

表单提交时,form.regions数组会自动携带所有组的输入数据,后端直接解析该数组即可获取全部录入内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 14:00:04