页面展示index.vue:
<template>
<div class="wrapper">
<TabList class="tablist" @tabEvent="tabEvent($event)" />
<div class="main-wrapper">
<button class="createbtn" color="primary" @click="toCreate">
添加
</button>
<TableList
:attributes="attributes"
:tabId="tabId"
:drawer.sync="drawer"
@editEvent="editEvent($event)"
@refreshListEvent="refreshListEvent($event)"
/>
</div>
<Create
v-if="drawer"
:tabId="tabId"
:editId="editId"
:displayType="displayType"
:drawer.sync="drawer"
@refreshListEvent="refreshListEvent($event)"
/>
</div>
</template>
<script>
import { api_request } from "@/util/network";
import TabList from "@/components/attributeCps/TabList";
import TableList from "@/components/attributeCps/TableList";
import Create from "@/components/attributeCps/Create";
export default {
name: "personList",
data() {
return {
tabId: "a",
attributes: [],
drawer: false,
displayType: "CREATE",
editId: null
};
},
created() {
this.switchFetchList(this.tabId);
},
methods: {
tabEvent(id) {
this.tabId = id;
this.switchFetchList(this.tabId);
},
refreshListEvent(id) {
this.switchFetchList(id);
},
editEvent({ id, displayType }) {
this.editId = id;
this.displayType = displayType;
},
fetchAList() {
this.$http
.get(`/api/a/list`)
.delegateTo(api_request)
.then(data => {
this.attributes = data.attributes;
})
.catch(({ code, message }) => {
throw `查询列表失败:${this.$t("api." + code)}, 额外信息: ${this.$t(
"api." + typeof message === "string"
? message
: JSON.stringify(message)
)}`;
})
.delegateTo(this.$snackbar.delegate);
},
fetchBList() {
this.$http
.get(`/api/b/list`)
.delegateTo(api_request)
.then(data => {
this.attributes = data.attributes;
})
.catch(({ code, message }) => {
throw `查询列表失败:${this.$t("api." + code)}, 额外信息: ${this.$t(
"api." + typeof message === "string"
? message
: JSON.stringify(message)
)}`;
})
.delegateTo(this.$snackbar.delegate);
},
fetchCList() {
this.$http
.get(`/api/c/list`)
.delegateTo(api_request)
.then(data => {
this.attributes = data.attributes;
})
.catch(({ code, message }) => {
throw `查询列表失败:${this.$t("api." + code)}, 额外信息: ${this.$t(
"api." + typeof message === "string"
? message
: JSON.stringify(message)
)}`;
})
.delegateTo(this.$snackbar.delegate);
},
toCreate() {
this.drawer = true;
this.displayType = "CREATE";
},
switchFetchList(tabId) {
switch (tabId) {
case "a":
this.fetchBList();
break;
case "b":
this.fetchCList();
break;
default:
this.fetchAList();
break;
}
}
},
components: {
TabList,
TableList,
Create
}
};
</script>
<style lang="less" scoped>
.wrapper {
.tablist {
margin-bottom: 20px;
}
.main-wrapper {
width: 100%;
.createbtn {
width: 120px;
height: 40px;
line-height: 40px;
background-color: #0078d7;
color: #fff;
margin-left: 20px;
margin-bottom: 20px;
border-radius: 4px;
}
}
}
</style>
封装tab组件TabList.vue:
<template>
<div class="tablist-container">
<ul class="tablist">
<li
:class="[tabId === item.id ? 'tabitem active' : 'tabitem']"
v-for="item in tabList"
:key="item.id"
@click="curItem(item.id)"
>
{{ item.name }}
</li>
</ul>
</div>
</template>
<script>
export default {
name: "tabList",
data() {
return {
tabList: [
{
id: "a",
name: "TAB1"
},
{
id: "b",
name: "TAB2"
},
{
id: "c",
name: "TAB3"
}
],
tabId: "a"
};
},
methods: {
curItem(id) {
this.tabId = id;
this.$emit("tabEvent", this.tabId);
}
}
};
</script>
<style lang="less" scoped>
.tablist-container {
width: 100%;
.tablist {
list-style: none;
display: flex;
padding-left: 0px;
.tabitem {
box-sizing: border-box;
padding: 12px 46px;
text-align: center;
&.active {
border-bottom: 2px solid #0078d7;
color: #0078d7;
}
}
}
}
</style>
封装table列表组件TableList.vue:
<template>
<div class="accountlist">
<v-simple-table class="table-wrapper">
<thead>
<tr>
<th class="text-left">
序号
</th>
<th class="text-left">
姓名
</th>
<th class="text-left">
身高
</th>
<th class="text-left">
是否单身
</th>
</tr>
</thead>
<tbody>
<tr v-for="item in attributes" :key="item.id">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.height }}</td>
<td>{{ item.simple ? "是" : "否" }}</td>
<td>
<v-btn icon elevation="0" @click.stop="toEdit(item.id)">
<v-icon>
mdi-square-edit-outline
</v-icon>
</v-btn>
<v-btn
icon
elevation="0"
color="red"
@click.stop="toDelete(item.id)"
>
<v-icon>
mdi-trash-can-outline
</v-icon>
</v-btn>
</td>
</tr>
</tbody>
</v-simple-table>
</div>
</template>
<script>
import { api_request } from "@/util/network";
export default {
name: "TableList",
props: {
personData: {
type: Array
},
tabId: {
type: String
}
},
created() {},
methods: {
toEdit(id) {
this.$emit("update:drawer", true);
this.$emit("editEvent", { id, displayType: "EDIT" });
},
toDelete(id) {
this.$http
.delete(`/api/${id}`)
.delegateTo(api_request)
.then(() => {
this.$emit("refreshListEvent", this.tabId);
return "删除成功";
})
.catch(({ code, message }) => {
throw `删除失败:${this.$t("api." + code)}, 额外信息: ${this.$t(
"api." + typeof message === "string"
? message
: JSON.stringify(message)
)}`;
})
.delegateTo(this.$snackbar.delegate);
}
}
};
</script>
<style lang="less" scoped>
.accountlist {
.table-wrapper {
/deep/.v-data-table__wrapper {
max-height: 626px;
overflow-x: auto;
overflow-y: auto;
}
}
}
</style>
封装Create组件 Create.vue:
<template>
<div class="create-wrapper">
<v-navigation-drawer width="450px" absolute permanent right>
<h4 class="theme-title">
{{ displayType === "CREATE" ? "新建属性" : "修改属性" }}
</h4>
<hr />
<div class="theme-content">
<button v-if="verifyResult" class="verify_notice">
请填写完整表单数据
</button>
<div class="every-item">
<span style="color:red">*</span>
<label>姓名</label>
<input type="text" v-model="name" />
</div>
<div class="every-item">
<span style="color:red">*</span>
<label>身高</label>
<input type="text" v-model="height" />
</div>
<div class="every-item">
<span style="color:red">*</span>
<label>爱好</label>
<select
v-model="love"
@change="getvalue_typeSelected(love)"
style="appearance: auto;"
>
<option :value="item" v-for="item in types" :key="item">{{
item
}}</option>
</select>
</div>
</div>
<div class="submit-con">
<button @click="submit">
{{ displayType === "CREATE" ? "新建" : "修改" }}
</button>
<button @click="cancel">取消</button>
</div>
</v-navigation-drawer>
</div>
</template>
<script>
import { api_request } from "@/util/network";
export default {
name: "CreateDrawer",
props: {
drawer: {
type: Boolean
},
displayType: {
type: String
},
tabId: {
type: String
},
editId: {
type: Number
}
},
data() {
return {
verifyResult: false,
name: "",
height: "",
love: "",
types: ["吃", "喝", "玩", "乐"]
};
},
created() {
if (this.displayType === "EDIT") {
this.getCurIdData();
}
this.love= this.types[0];
},
methods: {
getCurIdData() {
this.$http
.get(`/api/attribute/${this.editId}`)
.delegateTo(api_request)
.then(data => {
this.name = data.name;
this.height= data.height;
this.love= data.love;
});
},
getvalue_typeSelected(val) {
this.value_type = val;
},
submit() {
if (
this.name.trim() !== "" &&
this.height.trim() !== ""
) {
this.displayType === "CREATE" ? this.toCreate() : this.toEdit();
} else {
this.verifyResult = true;
setTimeout(() => {
this.verifyResult = false;
}, 2000);
}
},
cancel() {
this.$emit("update:drawer", false);
},
toCreate() {
let params = {
entity_type: this.tabId,
name: this.name,
height: this.height,
love: this.love
};
this.$http
.post("/api/create", params)
.delegateTo(api_request)
.then(() => {
this.$emit("update:drawer", false);
this.$emit("refreshListEvent", this.tabId);
})
.catch(({ code, message }) => {
this.$emit("update:drawer", false);
throw `新建失败:${this.$t("api." + code)}, 额外信息: ${this.$t(
"api." + typeof message === "string"
? message
: JSON.stringify(message)
)}`;
})
.delegateTo(this.$snackbar.delegate);
},
toEdit() {
let params = {
name: this.name,
height: this.height,
love: this.love
};
this.$http
.patch(`/api/${this.editId}`, params)
.delegateTo(api_request)
.then(() => {
this.$emit("update:drawer", false);
this.$emit("refreshListEvent", this.tabId);
})
.catch(({ code, message }) => {
this.$emit("update:drawer", false);
throw `修改失败:${this.$t("api." + code)}, 额外信息: ${this.$t(
"api." + typeof message === "string"
? message
: JSON.stringify(message)
)}`;
})
.delegateTo(this.$snackbar.delegate);
}
}
};
</script>
<style lang="less" scoped>
.create-wrapper {
.theme-title {
height: 50px;
line-height: 50px;
box-sizing: border-box;
padding-left: 20px;
}
.theme-content {
box-sizing: border-box;
padding: 50px 30px 40px;
.verify_notice {
width: 340px;
text-align: center;
background-color: red;
color: #fff;
height: 40px;
line-height: 40px;
border-radius: 10px;
}
.every-item {
display: flex;
height: 14px;
align-items: center;
margin-top: 50px;
label {
flex: 0 0 130px;
text-align: left;
color: #666;
}
input {
width: 200px;
height: 40px;
box-sizing: border-box;
padding-left: 20px;
outline: none;
border: 1px solid #666;
border-radius: 4px;
font-size: 14px;
}
select {
width: 200px;
height: 40px;
box-sizing: border-box;
padding-left: 20px;
outline: none;
border: 1px solid #666;
border-radius: 4px;
font-size: 14px;
}
}
}
.submit-con {
text-align: center;
margin-top: 100px;
button {
width: 120px;
box-sizing: border-box;
padding: 6px 10px;
background-color: #0078d7;
color: #fff;
border-radius: 4px;
}
button:not(:first-child) {
background-color: #666;
color: #000;
margin-left: 20px;
}
}
}
</style>