使用jsx 方式开发elementUI可编辑表格组建开发
- v-mode 改为 vModel 事件属性参考babel-plugin-transform-vue-jsx
- 指令改为实体对象方式 directives={{ name: "number", value: row, arg: prop}} vue-jsx API
- 插槽注入 scopedSlots 返回实体VNode或文本 {default:(scope)=>scope} 参考 vue-jsx API
针对scope 对象传入对象是引用类型,可以直接编辑对象并this.$forceUpdate(); 处罚VNode更新。
/**
* @name 可编辑表格
* @template <ConditionTable :data="demoData" :column="demoColumn" />
* @param {json} data 数据 例子: let demoData = [{ title1: "1", title2: "2", title3: "3", title4: "4", title5: "5",edit:"0" }];
* @param {json} column 表头 例子
* let demoColumn = [
{ prop: "title1", label: "表头1", align: "center", width: "auto",slot:"input" },
{ prop: "title5", label: "表头5", align: "center", width: "auto",slot:"select",select:[{label:"Sliding Scale",value:"1"},{label:"Fix Comm",value:"2"}] },
{ prop: "action", label: "操作" , align: "center", width: "300",slot:"button+" }
];
* @param {slot} slot 可处理类型 input 输入框 select 下拉菜单需要设置 select属性对应数据 button:无增加按钮 button+:有增加按钮
*/
export default {
name: "ConditionTable",
props: {
data: {
type: Array,
default: () => [] // 数据
},
column: {
type: Array,
default: () => []
}
},
data() {
return {};
},
mounted() {
console.log(this.column);
},
methods: {
// TODO: 创建表头
createColumn(data) {
// console.log(this.column)
let button = (row, $index, { prop }) => {
return (
<div class="inlineBlock">
{row["edit"] === "0" || !row["edit"] ? (
<el-button type="primary" class="ml10" size="mini" onClick={() => this.eventEdit($index, row, data)}>
修改
</el-button>
) : (
<el-button type="warning" class="ml10" size="mini" onClick={() => this.eventConfirm($index, row, data)}>
确认
</el-button>
)}
<el-button type="danger" class="ml10" size="mini" onClick={() => this.eventDelete($index, row, data, "service")}>
删除
</el-button>
</div>
);
};
// TODO: 按钮类
let buttonPluse = (row, $index, { prop }) => {
return (
<div>
<el-button type="primary" size="mini" onClick={() => this.eventAdd($index, row, data)}>
增加
</el-button>
{button(row, $index, { prop })}
</div>
);
};
// TODO: input 类
let input = (row, $index, { prop }) => {
let directives = { name: "number", value: row, arg: prop };
if (row["edit"] === "1") {
return <el-input vModel={row[prop]} directives={directives} class="edit-input" size="small" />;
} else {
return <span>{row[prop]}</span>;
}
};
// TODO: select 类
let select = (row, $index, { prop,select }) => {
let text = ()=>{
let da = select.filter(item=>{ return item.value==row[prop]});
if(da.length){ return da[0].label}else{ return row[prop]
}
}
if (row["edit"] === "1") {
return (
<el-select vModel={row[prop]} class="edit-input" size="small">
{select.map((item, ind) => {
return <el-option key={ind} label={item.label} value={item.value} />;
})}
</el-select>
);
} else {
return <span>{text()}</span>;
}
};
// TODO: 列
let col = this.column.map((item = { prop: "", label: "--", align: "center", slot: "" }, ind) => {
let scopedSlots = {
default: ({ row, $index }) => {
switch (item["slot"]) {
case "button+":
return buttonPluse(row, $index, item); // note: 有新增
case "button":
return button(row, $index, item); // note: 无新增
case "input":
return input(row, $index, item);
case "select":
return select(row, $index, item);
default:
return row[item.prop];
}
}
};
if (item["slot"]) {
return (
<el-table-column
prop={item.prop}
label={item.label}
align="center"
key={ind}
width={item["width"] || "auto"}
scopedSlots={scopedSlots}
/>
);
} else {
return <el-table-column prop={item.prop} label={item.label} align="center" key={ind} width={item["width"] || "auto"} />;
}
});
return col;
},
// TODO:增加
eventAdd(index, row, data) {
let cloneData = { ...row };
for (let item in cloneData) {
cloneData[item] = item=="edit"? "1":"";
}
data.splice(index + 1, 0, cloneData);
this.$forceUpdate();
this.$emit("add",data);
},
// TODO: 修改
eventEdit(index,row, data) {
row.edit="1";
this.$forceUpdate();
},
// TODO: 确认
eventConfirm(index,row, data) {
row.edit="0";
this.$forceUpdate();
this.$emit("confirm",data);
},
// TODO: 删除
eventDelete(index,row, data, name) {
if (data.length <= 1) {
this.$message({
type: "warning",
message: "最后一条数据,请点击编辑!"
});
return;
}
this.$confirm("确认删除此条记录吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
data.splice(index, 1);
this.$forceUpdate();
this.$emit("delete", data);
});
}
},
render() {
let { data } = this;
return (
<article class="condition-table">
<el-table data={data} fit border empty-text="暂无数据" style="width: 100%">
{this.createColumn(data)}
</el-table>
</article>
);
}
};