.NET Core开发者寻求Razor页面多记录录入的JavaScript库推荐
适合Razor页面多记录录入的JavaScript工具推荐
针对Razor页面中批量录入多条记录的需求,推荐几个实用且易上手的JS工具/方案,完全适配.NET Core的模型绑定逻辑:
1. 原生jQuery轻量实现(无额外依赖)
如果不想引入复杂框架,基于jQuery就能快速实现动态添加/删除表单行的功能,核心是利用Razor支持的索引式模型绑定(比如MenuItems[0].Price这类命名格式)。
示例代码:
<!-- 隐藏的模板行 --> <div class="menu-item-template d-none"> <div class="row mb-2"> <input type="text" name="MenuItems[__INDEX__].MenuName" class="form-control col" placeholder="菜单名称"> <input type="number" name="MenuItems[__INDEX__].Price" class="form-control col" placeholder="价格"> <textarea name="MenuItems[__INDEX__].Description" class="form-control col" placeholder="描述"></textarea> <button type="button" class="btn btn-danger col-auto remove-row">删除</button> </div> </div> <!-- 表单容器 --> <div id="menu-container"> <!-- 初始化第一行 --> <div class="row mb-2"> <input type="text" name="MenuItems[0].MenuName" class="form-control col" placeholder="菜单名称"> <input type="number" name="MenuItems[0].Price" class="form-control col" placeholder="价格"> <textarea name="MenuItems[0].Description" class="form-control col" placeholder="描述"></textarea> <button type="button" class="btn btn-danger col-auto remove-row">删除</button> </div> </div> <button type="button" id="add-row" class="btn btn-primary mt-2">添加菜单</button>
$(function() { let currentIndex = 1; // 添加新行 $('#add-row').click(function() { const templateHtml = $('.menu-item-template').html().replace(/__INDEX__/g, currentIndex); $('#menu-container').append(templateHtml); currentIndex++; }); // 删除行并重新索引(可选,不影响绑定但更规范) $(document).on('click', '.remove-row', function() { $(this).closest('.row').remove(); // 重新整理所有行的索引 $('#menu-container .row').each(function(i) { $(this).find('input, textarea').each(function() { const newName = $(this).attr('name').replace(/\[\d+\]/, `[${i}]`); $(this).attr('name', newName); }); }); currentIndex = $('#menu-container .row').length; }); });
优势:零额外依赖,直接适配Razor模型绑定,代码简单易懂,适合快速实现基础需求。
2. Vue.js(数据驱动,更整洁)
如果需要更优雅的表单管理,可以引入Vue.js的CDN,用双向绑定批量维护记录数组,提交时直接序列化数据给后端,无需手动处理DOM和命名。
示例代码:
<div id="menuApp" class="container"> <div v-for="(item, idx) in menuItems" :key="idx" class="row mb-2"> <input v-model="item.MenuName" type="text" class="form-control col" placeholder="菜单名称"> <input v-model.number="item.Price" type="number" class="form-control col" placeholder="价格"> <textarea v-model="item.Description" class="form-control col" placeholder="描述"></textarea> <button @click="removeItem(idx)" class="btn btn-danger col-auto">删除</button> </div> <button @click="addItem" class="btn btn-primary mt-2">添加菜单</button> <button @click="submitForm" class="btn btn-success mt-2 ms-2">提交</button> </div> <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> <script> const app = Vue.createApp({ data() { return { menuItems: [{ MenuName: '', Price: 0, Description: '' }] } }, methods: { addItem() { this.menuItems.push({ MenuName: '', Price: 0, Description: '' }); }, removeItem(idx) { this.menuItems.splice(idx, 1); }, async submitForm() { // 方式1:转为FormData适配Razor模型绑定 const formData = new FormData(); this.menuItems.forEach((item, idx) => { formData.append(`MenuItems[${idx}].MenuName`, item.MenuName); formData.append(`MenuItems[${idx}].Price`, item.Price); formData.append(`MenuItems[${idx}].Description`, item.Description); }); await fetch('/Menu/SaveBatch', { method: 'POST', body: formData }); // 方式2:提交JSON(后端用[FromBody]接收) // await fetch('/Menu/SaveBatchJson', { // method: 'POST', // headers: { 'Content-Type': 'application/json' }, // body: JSON.stringify(this.menuItems) // }); } } }).mount('#menuApp'); </script>
优势:数据驱动,代码结构清晰,支持轻松扩展表单验证(比如搭配VeeValidate),适合稍复杂的录入场景。
3. Alpine.js(超轻量声明式工具)
如果想要比Vue更轻量的方案,Alpine.js是绝佳选择——体积仅7KB,无需编译,语法接近原生JS,直接在Razor页面中使用。
示例代码:
<div x-data="{ menuItems: [{ MenuName: '', Price: 0, Description: '' }] }" class="container"> <template x-for="(item, idx) in menuItems" :key="idx"> <div class="row mb-2"> <input x-model="item.MenuName" type="text" class="form-control col" placeholder="菜单名称"> <input x-model.number="item.Price" type="number" class="form-control col" placeholder="价格"> <textarea x-model="item.Description" class="form-control col" placeholder="描述"></textarea> <button @click="menuItems.splice(idx, 1)" class="btn btn-danger col-auto">删除</button> </div> </template> <button @click="menuItems.push({ MenuName: '', Price: 0, Description: '' })" class="btn btn-primary mt-2">添加菜单</button> <form @submit.prevent="submit" class="mt-2"> <input type="hidden" x-ref="jsonData" name="MenuItemsJson"> <button type="submit" class="btn btn-success">提交</button> </form> </div> <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script> <script> document.addEventListener('alpine:init', () => { Alpine.data('menuForm', () => ({ submit() { this.$refs.jsonData.value = JSON.stringify(this.menuItems); this.$el.submit(); } })); }); </script>
后端可直接接收string MenuItemsJson参数,反序列化为List<MenuItem>即可。
优势:几乎无学习成本,体积极小,不影响页面加载速度,适合追求轻量的场景。
通用注意事项
- 后端模型需定义为
List<MenuItem>类型,Razor会自动识别索引式命名的表单字段完成绑定; - 可结合HTML5原生验证或后端数据注解验证,确保录入数据的合法性。
内容的提问来源于stack exchange,提问作者Pangomi IT
相关产品推荐
相关产品推荐

