AvueAvue
首页
  • 开发指南
  • Skill开发
  • 在线测试工具
  • Form组件
  • Crud组件
  • Default组件
  • Data组件
  • Component组件
产品
工作台
授权
联系
2.x文档
个人支付接口
首页
  • 开发指南
  • Skill开发
  • 在线测试工具
  • Form组件
  • Crud组件
  • Default组件
  • Data组件
  • Component组件
产品
工作台
授权
联系
2.x文档
个人支付接口
  • CRUD API
  • Object对象用法
  • 表格虚拟化
  • 分页
  • 搜索
  • 表头配置
  • 表格行配置项
  • 表格列配置项
  • 数据字典
  • 操作栏配置
  • 增删改查方法
  • 按钮文案和图标
  • 按钮自定义
  • 弹窗表单配置
  • 深层结构数据
  • 卡片模式
  • 统计合计
  • 导入导出
  • 表格树
  • 父子表
  • 行编辑
  • 权限控制
  • 动态行列合并
  • 空状态
  • 等待加载
  • 拖拽排序
  • 其它类型
  • 表格高级用法
  • 大表哥(宇宙最强表格)
  • CRUD模块封装
  • CRUD极简增删改查封装

增删改查方法

CRUD 提供表单、校验和操作事件,接口请求由业务处理。所有记录应包含稳定主键(默认 id),新增时使用服务端返回的真实主键。

新增数据

效果预览可直接操作下方示例

新增提交触发 row-save(row, done, loading)。保存成功用 done(savedRow) 关闭表单并加入本地列表;示例可切换为模拟失败,失败后调用 loading() 结束提交状态并保留输入。

正在加载示例…
<template>
  <div>
    <el-switch v-model="failNext" active-text="下次保存模拟失败" class="crud-save-switch" />
    <avue-crud v-model="form"
               :data="data"
               :option="option"
               @row-save="rowSave"
                />
    <p aria-live="polite">{{ message }} · 当前 {{ data.length }} 条</p>
  </div>
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
const form = ref({});
const failNext = ref(false);
const message = ref('本地示例,可新增或模拟保存失败。');
let nextId = 3;
const data = ref([
  { id: 1, name: '张三', department: '研发部' },
  { id: 2, name: '李四', department: '产品部' }
]);
const option = ref({
  rowKey: 'id',
  addBtn: true,
  editBtn: false,
  delBtn: false,
  gridBtn: false,
  refreshBtn: false,
  columnBtn: false,
  column: [
    { label: '姓名', prop: 'name', rules: [{ required: true, message: '请输入姓名', trigger: 'blur' }] },
    { label: '部门', prop: 'department' }
  ]
});
function shouldFail(loading) {
  if (!failNext.value) return false;
  failNext.value = false;
  loading();
  message.value = '本次模拟失败,已结束提交状态;保留输入,可直接重试。';
  ElMessage.error('模拟保存失败,请再次保存');
  return true;
}
function rowSave(row, done, loading) {
  if (shouldFail(loading)) return;
  const saved = { ...row, id: nextId++ };
  done(saved);
  message.value = '已新增 #' + saved.id + ':' + saved.name;
}
</script>
<style scoped>
.crud-save-switch { margin-bottom: 16px; }
</style>

修改数据

效果预览可直接操作下方示例

编辑提交触发 row-update(row, index, done, loading)。done(savedRow) 按主键更新本地记录;请求失败时调用 loading(),不会关闭编辑窗口。

正在加载示例…
<template>
  <div>
    <el-switch v-model="failNext" active-text="下次保存模拟失败" class="crud-save-switch" />
    <avue-crud v-model="form"
               :data="data"
               :option="option"
               @row-update="rowUpdate"
                />
    <p aria-live="polite">{{ message }} · 当前 {{ data.length }} 条</p>
  </div>
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
const form = ref({});
const failNext = ref(false);
const message = ref('本地示例,可编辑或模拟保存失败。');
const data = ref([
  { id: 1, name: '张三', department: '研发部' },
  { id: 2, name: '李四', department: '产品部' }
]);
const option = ref({
  rowKey: 'id',
  addBtn: false,
  editBtn: true,
  delBtn: false,
  gridBtn: false,
  refreshBtn: false,
  columnBtn: false,
  column: [
    { label: '姓名', prop: 'name', rules: [{ required: true, message: '请输入姓名', trigger: 'blur' }] },
    { label: '部门', prop: 'department' }
  ]
});
function shouldFail(loading) {
  if (!failNext.value) return false;
  failNext.value = false;
  loading();
  message.value = '本次模拟失败,已结束提交状态;保留输入,可直接重试。';
  ElMessage.error('模拟保存失败,请再次保存');
  return true;
}
function rowUpdate(row, index, done, loading) {
  if (shouldFail(loading)) return;
  done(row);
  message.value = '已更新 #' + row.id + ':' + row.name;
}
</script>
<style scoped>
.crud-save-switch { margin-bottom: 16px; }
</style>

删除数据

效果预览可直接操作下方示例

点击删除触发 row-del(row, index, done)。确认并完成业务删除后,再调用 done() 移除本地行;不调用它时列表不会自动删除。

正在加载示例…
<template>
  <avue-crud :data="data"
             :option="option"
             @row-del="rowDel"></avue-crud>
</template>

<script setup>
import { ref } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';

// 数据定义
const data = ref([
  { id: 1, name: '张三', sex: '男' },
  { id: 2, name: '李四', sex: '女' }
]);

const option = ref({
  editBtn: false,
  addBtn: false,
  delBtnText: '删除数据',
  delBtnIcon: 'el-icon-user',
  column: [
    { label: '姓名', prop: 'name' },
    { label: '性别', prop: 'sex' }
  ]
});

// 删除处理
const rowDel = (form, index) => {
  ElMessageBox.confirm('此操作将永久删除该文件, 是否继续?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    ElMessage.success('删除成功!');
  }).catch(() => { });
};
</script>

刷新数据

效果预览可直接操作下方示例

点击刷新触发 refresh-change,需要业务重新查询。它与 refreshTable() 不同:后者只重新挂载表格并清空选择,不请求列表。

正在加载示例…
<template>
  <avue-crud :data="data"
             :option="option"
             @refresh-change="refreshChange"></avue-crud>
</template>

<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';

// 数据定义
const data = ref([
  { id: 1, name: '张三', sex: '男' },
  { id: 2, name: '李四', sex: '女' }
]);

const option = ref({
  addBtn: false,
  menu: false,
  column: [
    { label: '姓名', prop: 'name' },
    { label: '性别', prop: 'sex' }
  ]
});

// 刷新回调处理
const refreshChange = () => {
  ElMessage.success('刷新回调');
};
</script>

综合用法

效果预览可直接操作下方示例

新增、修改和删除都使用组件回调同步本地数据。本例没有业务接口,操作后下方显示记录数量和最近结果;「模拟保存失败」可以验证提交结束后仍保留输入。

正在加载示例…
<template>
  <div>
    <el-switch v-model="failNext" active-text="下次保存模拟失败" class="crud-save-switch" />
    <avue-crud v-model="form"
               :data="data"
               :option="option"
               @row-save="rowSave"
               @row-update="rowUpdate"
               @row-del="rowDel" />
    <p aria-live="polite">{{ message }} · 当前 {{ data.length }} 条</p>
  </div>
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';
const form = ref({});
const failNext = ref(false);
const message = ref('本地示例,可新增、编辑或模拟保存失败。');
let nextId = 3;
const data = ref([
  { id: 1, name: '张三', department: '研发部' },
  { id: 2, name: '李四', department: '产品部' }
]);
const option = ref({
  rowKey: 'id',
  addBtn: true,
  editBtn: true,
  delBtn: true,
  gridBtn: false,
  refreshBtn: false,
  columnBtn: false,
  column: [
    { label: '姓名', prop: 'name', rules: [{ required: true, message: '请输入姓名', trigger: 'blur' }] },
    { label: '部门', prop: 'department' }
  ]
});
function shouldFail(loading) {
  if (!failNext.value) return false;
  failNext.value = false;
  loading();
  message.value = '本次模拟失败,已结束提交状态;保留输入,可直接重试。';
  ElMessage.error('模拟保存失败,请再次保存');
  return true;
}
function rowSave(row, done, loading) {
  if (shouldFail(loading)) return;
  const saved = { ...row, id: nextId++ };
  done(saved);
  message.value = '已新增 #' + saved.id + ':' + saved.name;
}
function rowUpdate(row, index, done, loading) {
  if (shouldFail(loading)) return;
  done(row);
  message.value = '已更新 #' + row.id + ':' + row.name;
}
function rowDel(row, index, done) {
  done();
  message.value = '已删除本地记录 #' + row.id;
}
</script>
<style scoped>
.crud-save-switch { margin-bottom: 16px; }
</style>

选择一种数据同步方式

场景保存后处理
完整记录已由接口返回,希望直接更新当前列表done(savedRow)
需要重新获取服务端分页、排序、计算字段done() 后重新请求当前页
保存失败,允许修改后重试显示错误,再调用 loading()
删除成功,直接更新当前本地列表done()

不要同时手动插入一条记录又调用 done(savedRow),否则会重复新增。删除当前页最后一条记录后,业务应根据新的总数校正页码再重新加载。done 和 loading 都是事件参数,不需要保存为全局变量。

async function rowSave(row, done, loading) {
  try {
    const savedRow = await createRecord(row);
    done(savedRow);
  } catch (error) {
    loading();
    // 使用项目的错误提示,保留当前输入。
  }
}

弹窗提交前已经执行字段校验;无须在 row-save 中再次调用 validate。按钮定制见 自定义按钮,分页查询见 分页。

最后更新:
贡献者: smallwei
Prev
操作栏配置
Next
按钮文案和图标