项目场景:
项目场景:当表格内容较少时,可简便为直接进行,行内编辑数据,进行增删改查操作(文章最后有全部代码,可自行尝试)
解决方法
首先单独讲解一下el-table-column嵌套el-autocomplete的写法以及代码逻辑,最后贴完整代码
循环列表项
<jr-table-column
:label="item.label"
v-for="item in columnList"
:key="item.prop"
>
<template slot-scope="scope">
<template v-if="state == 'edit'">
<el-autocomplete
v-if="item.prop == 'relatedPartyName'"
popper-class="el-autocomplete-suggestion"
style="width: 100%"
clearable
ref="modelRef"
v-model="scope.row[item.prop]"
:fetch-suggestions="querySearch"
placeholder="请输入名称"
@select="
(item) => {
handleSelect(item, scope.$index); 查询到可选项列表后选择对应那条数据(scope.$index确定它在列表的哪一行)
}
"
>
<el-button
slot="append"
style="width: 60px"
:loading="queryCarLoading"
@click="queryCarFun(scope.$index)" 点击放大镜按钮方法
>
<i class="el-icon-search" v-if="!queryCarLoading"></i>
</el-button>
</el-autocomplete>
<el-input
v-else
v-model="scope.row[item.prop]"
class="edit-input"
size="mini"
/>
</template>
</template>
</jr-table-column>
data() {
return {
columnList: [
{
prop: "statDate",
label: "测试数据",
},
{
prop: "relatedPartyType",
label: "测试数据111",
},
{
prop: "relatedPartyName",
label: "测试数据222",
},
{
prop: "corpUniscCode",
label: "测试数据333",
},
{
prop: "corpInvestFund",
label: "测试数据4444",
},
],
state: "",
querySearchName: "",
queryCarLoading: false,
queryFlag: false,
queryRes: [],
};
},
methods: {
querySearch(queryString, cb) {
this.querySearchName = queryString;
if (this.queryFlag) {
cb(this.queryRes);
this.queryFlag = false;
} else {
cb(this.queryRes || []);
}
},
//名称选择值后(这块的处理是因为我选择需要的那条后,还要把对应的某个字段放入列表的行内,所以有特殊处理)
handleSelect(val, index) {
this.d03List[index].relatedPartyCode = val.relatedPartyCode;
this.d03List[index].corpUniscCode = val.corpUniscCode;
},
//点击名称查询放大镜按钮
queryCarFun(val) {
let info = {
relatedname: this.querySearchName,
relatedPartyType: this.d03List[val].relatedPartyType || "",
};
this.queryCarLoading = true;
queryRelatedParty(info).then((res) => {
this.queryFlag = true;
this.queryCarLoading = false;
//这块是重点,查询后台获取到数据后,要放入el-autocomplete所需要的格式中,value代表弹出展示的名称
this.queryRes = res.data.map((item) => ({
// ...item,
relatedPartyCode: item.relatedcode,
corpUniscCode: item.identityNo,
value: item.relatedname,
}));
if (this.queryRes.length === 0) {
this.$message.warning("未查询到其名称,请修改后重新查询");
} else {
//.focus()是为了让查询到数据后自动弹出可选项的列表(如果el-autocomplete放在el-dialog组件,我们可以直接使用this.$refs.modelRef弹出,但是放在el-table-column,他会生成两条,所以只能去计算弹出,)
//可以打印一下this.$refs.modelRef就会明白我说的什么意思
// console.log(this.$refs.modelRef);
//每新增一行都有添加两条this.$refs.modelRef,只有新增那一行的第一条才可以显示打开查询的列表,所以要获取表格的第几行val然后X2
this.$refs.modelRef[val * 2].focus();
}
});
},
},
全部代码逻辑
以下是全部代码,自行替换所需的接口即可尝试
<template>
<div>
<div>
<el-button
type="primary"
size="mini"
@click="edit"
>编辑</el-button
>
<el-button type="success" size="mini" @click="save"
>保存</el-button
>
</div>
<jr-table :showPagination="false" :height="'300'" :tableData="d03List">
<jr-table-column label="序号" type="index" width="50"></jr-table-column>
<jr-table-column
:label="item.label"
v-for="item in columnList"
:key="item.prop"
>
<template slot-scope="scope">
<template v-if="state == 'edit'">
<el-autocomplete
v-if="item.prop == 'relatedPartyName'"
popper-class="el-autocomplete-suggestion"
style="width: 100%"
clearable
ref="modelRef"
v-model="scope.row[item.prop]"
:fetch-suggestions="querySearch"
placeholder="请输入名称"
@select="
(item) => {
handleSelect(item, scope.$index);
}
"
>
<el-button
slot="append"
style="width: 60px"
:loading="queryCarLoading"
@click="queryCarFun(scope.$index)"
>
<i class="el-icon-search" v-if="!queryCarLoading"></i>
</el-button>
</el-autocomplete>
<el-input
v-else
v-model="scope.row[item.prop]"
class="edit-input"
size="mini"
/>
</template>
<template v-else>
<span>{
{ scope.row[item.prop] }}</span>
</template>
</template>
</jr-table-column>
<el-table-column
fixed="right"
label="操作"
width="190"
align="center"
>
<template slot-scope="scope">
<el-button
icon="el-icon-plus"
size="mini"
type="primary"
@click="handleAdd(scope.$index, scope.row)"
>
新增
</el-button>
<el-button
size="mini"
type="danger"
icon="el-icon-delete"
@click.native.prevent="deleteRow(scope.$index, d03List)"
>
移除
</el-button>
</template>
</el-table-column>
</jr-table>
</div>
</template>
<script>
import {
saveMonthD03, queryRelatedParty } from "@/api/gljyData/gljyjcData";
import {
mapState } from "vuex";
export default {
computed: {
...mapState("common", [
]),
},
props: {
d03List: Array,
},
data() {
return {
columnList: [
{
prop: "statDate",
label: "测试数据",
},
{
prop: "relatedPartyType",
label: "测试数据111",
},
{
prop: "relatedPartyName",
label: "测试数据222",
},
{
prop: "corpUniscCode",
label: "测试数据333",
},
{
prop: "corpInvestFund",
label: "测试数据4444",
},
],
state: "",
querySearchName: "",
queryCarLoading: false,
queryFlag: false,
queryRes: [],
};
},
created() {
},
mounted() {
},
methods: {
querySearch(queryString, cb) {
this.querySearchName = queryString;
if (this.queryFlag) {
cb(this.queryRes);
this.queryFlag = false;
} else {
cb(this.queryRes || []);
}
},
//名称选择值后
handleSelect(val, index) {
this.d03List[index].relatedPartyCode = val.relatedPartyCode;
this.d03List[index].corpUniscCode = val.corpUniscCode;
},
//点击名称查询放大镜按钮
queryCarFun(val) {
let info = {
relatedname: this.querySearchName,
relatedPartyType: this.d03List[val].relatedPartyType || "",
};
this.queryCarLoading = true;
queryRelatedParty(info).then((res) => {
this.queryFlag = true;
this.queryCarLoading = false;
this.queryRes = res.data.map((item) => ({
// ...item,
relatedPartyCode: item.relatedcode,
corpUniscCode: item.identityNo,
value: item.relatedname,
}));
if (this.queryRes.length === 0) {
this.$message.warning("未查询到其名称,请修改后重新查询");
} else {
// console.log(this.$refs.modelRef.length);
//每新增一行都有添加两条this.$refs.modelRef,只有新增那一行的第一条才可以显示打开查询的列表,所以要获取表格的第几行val然后X2
this.$refs.modelRef[val * 2].focus();
}
});
},
//保存
save() {
console.log(this.d03List);
if (this.d03List && this.d03List.length > 0) {
saveMonthD03(this.d03List).then((res) => {
this.state = "";
this.$emit("saveD03");
this.$message.success("保存成功");
});
} else {
this.$message.warning("请先编辑数据");
}
},
//编辑
edit() {
if (this.d03List && this.d03List.length > 0) {
this.state = "edit";
} else {
this.state = "edit";
let tableVal = {
statDate: "",
relatedPartyType: "",
relatedPartyName: "",
relatedPartyCode: "",
corpUniscCode: "",
corpInvestFund: "",
};
this.d03List.push(tableVal);
}
},
//表格新增
handleAdd(row, val) {
this.state = "edit";
let tableVal = {
statDate: "",
relatedPartyType: "",
relatedPartyName: "",
relatedPartyCode: "",
corpUniscCode: "",
corpInvestFund: "",
};
this.queryRes = [];
this.d03List.push(tableVal);
},
//表格删除行
deleteRow(index, rows) {
this.$confirm("您现在的操作将删除此条数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
rows.splice(index, 1);
this.$message({
type: "success",
message: "删除成功!",
});
})
.catch(() => {
// this.$message({
// type: 'info',
// message: '已取消删除'
// });
});
},
},
};
</script>
小疑问:为啥在el-table里会生成this.$refs.modelRef两个节点呢,欢迎各位大佬指点讨论