1.请求数据
调用getData通过异步方法在控制台获取数据(数据:data.data.record)
const getData = async () =>{
const res = await getProducts();
console.log(res)
}
2.定义列表(columns)
<a-table :columns="columns">
</a-table>
调用columns创建列表
const columns = [
{
title:'商品',
dataIndex:'name'
},
{
title:'价格',
dataIndex:'price'
},
{
title:'操作',
dataIndex:'methods'
}
]
2.1获取接口数据,通过dataSource来实现
const dataSource = ref([]);//双向绑定,初始值为空
再再getData调用函数中把res.data.data.record的值赋值给dataSource.value获取信息到列表当中
2.2定义页码pagination
//页码展示
const pagination = ref({
current: 1,//当前页
pageSize: 10,//每页展示多少条
total: 0,//总共多少条
showSizeChanger: true,//展示change
pageSizeOptions: ["2", "3", "5", "10"],
});
再在getData调用函数中获取总共的数据pagination.value.total = res.data.data.totalItems;
2.3定义每页数据条数@change="handleTableChange"
调用handleTableChange
const handleTableChange = (pageObj) => {
pagination.value = pageObj;//pageObj赋值给pagination
};
2.4再在getData调用函数中将分页数据传给getData
const res = await getProducts({
//传入对应的数据
pageNumber:pagination.value.current,
pageSize:pagination.value.pageSize,
});
2.5添加删除、修改操作按钮
删除操作
<template #bodyCell="{column,record}">
<a-space v-if="column.dataIndex === 'methods'">
<a-button>编辑</a-button>
//删除提示框
<a-popconfirm
title="你确认要删除这条数据吗?"
ok-text="确定"
cancel-text="取消"
@confirm="() => deleteItem(record.id)"
>
<a-button>删除</a-button>
</a-popconfirm>
</a-space>
</template>
{column,record}解构,根据record.id传入的id来删除用户信息
调用deleteItem
const deleteItem = async (id) => {//通过异步方法,接收id删除数据
await deleteProducts(id);
//提示信息
message.success("删除成功!");
getData();//请求列表
};
2.6添加a-form表单属性
查询操作
//定义v-model="passData",passData传入后端数据的函数
<a-form v-model="passData" layout="inline">
<a-form-item name="name" label="商品">
<a-input v-model:value="passData.name" />
</a-form-item>
<a-form-item name="price" label="价格">
<a-input v-model:value="passData.price" />
</a-form-item>
<a-form-item>
<a-space>
<a-button @click="search">查询</a-button>
<a-button @click="reset">重置</a-button>
</a-space>
</a-form-item>
</a-form>
//调用点击事件search
const search = () =>{
pagination.value.current = 1;//页码回到第一页
getData();//请求列表数据
}
将...passData.value添加到getData中,解构来获取搜索的值
//调用reset点击事件重置
const reset = () => {
pagination.value.current = 1;//页码回到第一页
pagination.value.pageSize = 10;//分页回到十页
passData.value = {};//passData将表单数据回到空
getData();//请求列表数据
};
2.7添加模态框
<a-modal :open="isOpen" :title="formData.id ? '修改商品' : '新增商品'">
<a-form :model="formData">
<a-form-item name="name" label="商品">
<a-input v-model:value="formData.name"/>
</a-form-item>
<a-form-item name="price" label="价格">
<a-input v-model:value="formData.price"/>
</a-form-item>
</a-form>
</a-modal>
调用isOpen,最初设置为关闭
const isOpen = ref(false);
调用formData来实现表单数据
const formData = ref({});
判断根据商品id来实现修改和新增,如果存在则是修改,反则新增
title="formData.id ? '修改商品' : '新增商品'"
2.8新增
添加按钮点击事件handleOpen
调用handleOpen
const handleOpen = () =>{
formData.value = {};//置为一个空的对象
isOpen.value = true;//打开模态框
}
2.9修改
添加修改箭头函数
@click="() => handleEdit(record)"获取record中的数据来实现handleEdit修改操作
调用handleEdit
const handleEdit = (record) => {
console.log(record);//拿出record中的数据
formData.value = {...record};//将获取到的数据赋值给formData
isOpen.value = true;//打开模态框
};
2.10模态框中的点击确认和取消按钮逻辑
a-modal中添加@ok="handleEditOrCreate @cancel="handleCancel"点击事件
调用handleEditOrCreate
// 点击模态框的确定
const handleEditOrCreate = async () => {
const isCreate = !formData.value.id;//判断如果id没有
if (isCreate) {
await addProducts(formData.value);
message.success("新增成功");
reset();//重置回到第一页
} else {
await updateProducts(formData.value);
message.success("修改成功");
getData();//请求列表数据
}
isOpen.value = false;
};
// 点击模态框的取消
const handleCancel = () => {
isOpen.value = false;
};
3.封装模态框
通过封装v-modal来实现修改、添加
// 包含新增、编辑功能的模态框
// 需要传入的props有(父传子):
// 1. 是否打开模态框
// 2. 传入当前form需要编辑的数据
// 3. 到底是新增,还是修改
const props = defineProps({//defineProps接收一个对象
isOpen: {
type: Boolean,
required: true,
},
editData: {
type: Object,//Object编辑是一个对象
required: true
}
});
添加封装的a-modal
<a-modal
@ok="handleOk"
@cancel="handleCancel"
:open="props.isOpen"//通过props实现模态框的操作
:title="props.editData.id ? '修改商品-独立' : '新增商品-独立'"
>
<a-form :model="passData" :rules="rules">
<a-form-item name="name" label="商品">
<a-input v-model:value="passData.name" />
</a-form-item>
<a-form-item name="price" label="价格">
<a-input v-model:value="passData.price" />
</a-form-item>
</a-form>
</a-modal>
const passData = ref({ ...props.editData });//操作内部数据
调用点击事件ok和cancel
//emit事件,onSuccess通知父组件新增或修改成功、changeIsOpen关闭模态框
const emit = defineEmits(["onSuccess", "changeIsOpen"]);
const handleOk = async () => {
if (props.editData.id) {
// 修改
await updateProducts(passData.value);
message.success("修改成功");
emit("onSuccess", "edit");
} else {
// 新增
await addProducts(passData.value);
message.success("新增成功");
emit("onSuccess", "add");
}
};
const handleCancel = () => {
emit("changeIsOpen");//通过emit事件来取消模态框
};
父组件中引入
<AddEditModal
v-if="isOpen"
:is-open="isOpen"
:editData="formData"//将formData的逻辑传给editData
@changeIsOpen="() => (isOpen = !isOpen)"//接收子组件中的changeIsOpen
@onSuccess="handleSuccess"//接收子组件中的onSuccess
/>
//调用handleSuccess
const handleSuccess = (type) => {//传入type形参
if (type === "add") {
reset();
} else {
getData();
}
isOpen.value = false;
};
整体代码:
父组件
<template>
<a-form layout="inline" v-model="passData">
<a-form-item name="name" label="商品">
<a-input v-model:value="passData.name"/>
</a-form-item>
<a-form-item name="price" label="价格">
<a-input v-model:value="passData.price"/>
</a-form-item>
<a-form-item>
<a-space>
<a-button @click="search">搜索</a-button>
<a-button @click="reset">重置</a-button>
</a-space>
</a-form-item>
</a-form>
<div>
<a-button @click="handelOpen">新增</a-button>
</div>
<a-table :columns="columns" :dataSource="dataSource" :pagination="pagination"
@change="handleTableChange">
<template #bodyCell="{record,column}">
<a-space v-if="column.dataIndex === 'methods'">
<a-button @click="() => handleEdit(record)">编辑</a-button>
<a-popconfirm title="确认删除这条数据吗" ok-text="确定" cancel-text="取消"
@confirm="() => deleteItem(record.id)">
<a-button>删除</a-button>
</a-popconfirm>
</a-space>
</template>
</a-table>
<a-modal :open="isOpen" :title="formData.id?'修改商品':'新增商品'"
@ok="handleEditOrCreate" @cancel="handleCancel">
<a-form v-model="formData">
<a-form-item name="name" label="商品">
<a-input v-model:value="formData.name"/>
</a-form-item>
<a-form-item name="price" label="价格">
<a-input v-model:value="formData.price"/>
</a-form-item>
</a-form>
</a-modal>
<!-- <AddEditModal
:is-open="isOpen"
:editData="formData"
@onSuccess="handeladdoredit"
@changeIsOpen="() =>(isOpen =! isOpen)"
/> -->
</template>
<script setup>
// import AddEditModal from '../component/AddEditModal.vue'
import { addProducts, deleteProducts, getProducts, updateProducts } from '../../../../services/products';
import {ref} from 'vue'
import {message} from 'ant-design-vue'
const dataSource = ref([])//双向绑定,初始值为空
const passData = ref([])//将传给后端的数据passData的值置为空对象
const isOpen = ref(false);//模态框最初设为关闭状态
const formData = ref({});//调用formData来实现模态框的数据获取
// const handeladdoredit = (type) =>{
// if(type === "add"){
// reset();
// }else{
// getData();
// }
// }
//新增
const handelOpen = () =>{
formData.value = {};//将新增模态框中的数据置为空的对象
isOpen.value = true;//打开模态框
}
//修改
const handleEdit = (record) =>{
console.log(record);//拿出record中的数据展示到表单中
formData.value = {...record};//将record中的数据传给一个新的对象formData来接收
isOpen.value = true//打开模态框
}
//调用handleEditOrCreate判断是否新增还是修改
const handleEditOrCreate = async() =>{
const add = !formData.value.id;//判断有没有id
//如果不存在则是新增
if(add){
await addProducts(formData.value);
message.success("新增成功");
reset();//新增之后回到第一页查看新增数据
}else{
await updateProducts(formData.value);
message.success("修改成功");
getData();//修改之后访问当前页数据
}
isOpen.value = false;//执行完后关闭模态框
}
//模态框取消按钮逻辑
const handleCancel = () =>{
isOpen.value = false;//关闭模态框
}
//定义数据列表
const columns = [
{
title:'商品',
dataIndex:'name'
},
{
title:'价格',
dataIndex:'price'
},
{
title:'操作',
dataIndex:'methods'
},
]
//调用点击事件实现搜索
const search = () =>{
pagination.value.current = 1;//页码回到第一页
getData();//搜索完成后再次请求数据
}
//重置
const reset =() =>{
pagination.value.current = 1;//页码回到第一页
pagination.value.pageSize = 10;//回到每页十条数据
passData.value = {};//将表单中的数据置为一个空的对象
getData();//再次请求列表中的数据
}
//删除
const deleteItem = async(id) =>{
await deleteProducts(id);
// 提示信息
message.success("删除成功");
getData();//请求列表数据
}
//调用页码
const pagination =ref({
current:1,//当前页
pageSize:10,//每页展示10条
total:0,//总共条数
showSizeChanger:true,//true即修改页码执行
pageSizeOptions:["2","3","5","10"]//选择页码展示条数
})
//调用handleTableChange实现页面的条数显示
const handleTableChange = (pageobj) =>{
pagination.value = pageobj;//将pageonbj的值赋给pagination
}
//获取数据
const getData = async() =>{
const res = await getProducts({
//传入相应的数据
pageNumber:pagination.value.current,
pageSize:pagination.value.pageSize,
...passData.value,//解构来实现搜索获取数据
});
dataSource.value = res.data.data.record;//将获取到的数据重新赋值给dataSource
pagination.value.total = res.data.data.totalItems;//获取所有的数据
}
getData();
</script>
<style>
</style>
子组件
<template>
<a-modal
@ok="handleOk"
@cancel="handleCancel"
:open="props.isOpen"
:title="props.editData.id ? '修改商品-独立' : '新增商品-独立'"
>
<a-form :model="passData" :rules="rules">
<a-form-item name="name" label="商品">
<a-input v-model:value="passData.name" />
</a-form-item>
<a-form-item name="price" label="价格">
<a-input v-model:value="passData.price" />
</a-form-item>
</a-form>
</a-modal>
</template>
<script setup>
import {
defineProps,
defineEmits,
ref,
watch,
watchEffect,
computed,
} from "vue";
import { message } from "ant-design-vue";
import { updateProducts, addProducts } from "../../../../services/products";
// 包含新增、编辑功能的模态框
// 需要传入的props有(父传子):
// 1. 是否打开模态框
// 2. 传入当前form需要编辑的数据
// 3. 到底是新增,还是修改
const props = defineProps({//defineProps接收一个对象
isOpen: {
type: Boolean,
required: true,
},
editData: {
type: Object,//Object编辑是一个对象
required: true,
// default: {},
},
// isCreate: {
// type: Boolean,
// required: true,
// },
});
const rules = {
name: [{ required: true, message: "请填写商品名" }],
price: [{ required: true, message: "请填写价格" }],
};
const passData = ref({ ...props.editData });//操作内部数据
// 需要emit出去的事件有(子传父):
// 1. 新增或者修改成功后,通知父组件:
// 2. 模态框是否关闭
//emit事件,onSuccess通知父组件新增或修改成功、changeIsOpen关闭模态框
const emit = defineEmits(["onSuccess", "changeIsOpen"]);
const handleOk = async () => {
if (props.editData.id) {
// 修改
await updateProducts(passData.value);
message.success("修改成功");
emit("onSuccess", "edit");
} else {
// 新增
await addProducts(passData.value);
message.success("新增成功");
emit("onSuccess", "add");
}
};
const handleCancel = () => {
emit("changeIsOpen");//通过emit事件来取消模态框
};
// watch(
// () => props.editData,
// (value, oldValue) => {
// passData.value = { ...value };
// console.log(value, oldValue);
// }
// );
// watchEffect(() => {
// passData.value = { ...props.editData };
// // console.log(props.editData);
// });
// const isCreate = computed(() => !props.editData.id)
// const nowTitle = computed(() => {
// return isCreate ? "新增用户-独立" : "修改用户-独立";
// });
</script>
<style></style>
<!-- <template>
<a-modal :title="props.addData.id ? '修改商品-独立':'编辑商品-独立'" :open="props.isOpen"
@ok="handelOK" @cancel="handelCancel">
<a-form v-modal="passData" :rules="rules">
<a-form-item name="name" label="商品">
<a-input v-modal:value="passData.name"/>
</a-form-item>
<a-form-item name="price" label="价格">
<a-input v-modal:value="passData.price"/>
</a-form-item>
</a-form>
</a-modal>
</template>
<script setup>
import { addProducts, updateProducts } from '../../../../services/products';
import { defineEmits,defineProps,ref} from 'vue';
import {message} from 'ant-design-vue'
// 传入props,(父传子)
// 1.打开模态框
// 2.传入需要的数据
// 3.是否新增或者修改
const props = defineProps({
isOpen:{
type:Boolean,
required:true
},
addData:{
type:Object,//编辑修改的是一个对象
required:true
}
})
//操作内部数据、
const passData = ref({...props.addData});
const rules = {
name:[{required:true,message:'请填写商品'}],
price:[{required:true,message:'请填写价格'}]
}
// 向父组件emit出去,1.成功修改或者添加 2.模态框是否关闭
const emit = defineEmits(["Success","IsOpen"])
const handelOK = async() =>{
if(props.addData.id){
//修改
await updateProducts(passData.value)
message.success("修改成功!")
emit("Success","update")
}else{
await addProducts(passData.value)
message.success("新增成功!")
emit("Success","add")
}
}
const handelCancel = () =>{
emit("IsOpen")//通过emit事件来取消模态框
}
</script>
<style></style> -->
注意:具体的路由配置、service的接口调用(根据相应的项目)、参数名、别名需根据实际需要具体修改!
效果图
这是没有启动后端项目因此没有数据
类似这种效果,可自行添加其它操作(代码中无状态)
模态框
新增、修改类似(红色字体为表单验证)