使用Vue3开发学生管理系统模板6 老师信息的实现

2023-12-28 18:40:44

字段设计

  • ID
  • name:姓名,字符串,最大长度36
  • age:年龄,数字
  • gender:性别,字符串,最大长度6
  • phone:电话,字符串,最大长度20
  • height:身高,数字
  • weight:体重,数字
  • course_id:科目ID,字符串,最大长度36
  • course:教学科目,字符串,最大长度36
  • job:职位,字符串,最大长度255
  • job_age:工龄,数字
  • job_time:入职时间,日期类型
  • salary:工资,浮点数
  • detail:详细信息,文本类型

老师JSON数据构造

[
  {
    "id": "1",
    "name": "张三的老师",
    "phone": "18811118888",
    "age": 33,
    "gender": "男",
    "height": 177,
    "weight": 128,
    "course_id": "1",
    "course_name": "数学",
    "job": "教导处主任",
    "job_age": 5,
    "job_time": "2018-06-09",
    "salary": 12000,
    "detail": "{}"
  },
  {
    "id": "2",
    "name": "李四的老师",
    "phone": "18811118888",
    "age": 33,
    "gender": "男",
    "height": 177,
    "weight": 128,
    "course_id": "1",
    "course_name": "数学",
    "job": "教导处主任",
    "job_age": 5,
    "job_time": "2018-06-09",
    "salary": 12000,
    "detail": "{}"
  },
  {
    "id": "3",
    "name": "王五的老师",
    "phone": "18811118888",
    "age": 33,
    "gender": "男",
    "height": 177,
    "weight": 128,
    "course_id": "1",
    "course_name": "数学",
    "job": "教导处主任",
    "job_age": 5,
    "job_time": "2018-06-09",
    "salary": 12000,
    "detail": "{}"
  }
]

渲染老师表格信息

完整代码:

<script setup>
import {FilterMatchMode} from 'primevue/api';
import {ref, onBeforeMount} from 'vue';
import {useToast} from 'primevue/usetoast';
import sClasss from "@/assets/data/sclasss.json"
import students from "@/assets/data/students.json"
import studentHomes from "@/assets/data/student_home.json";
import sClasses from "@/assets/data/sclasss.json"
import teachers from "@/assets/data/teachers.json"

// 学生家长
const studentHome = ref({
  id: 1,
  name: "张三的家长",
  gender: "男",
  age: "41",
  phone: "18888887777",
  student_id: "1",
  student_sclass_id: "1",
  student_sclass: "初一(3)班",
  student_name: "张三",
  relation: "父子"
})

const sClass = ref(null) // 选取的学生家长信息
const student = ref(null) // 班长信息

const toast = useToast();

const isEdit = ref(false) // 是否为编辑
const sClassDialog = ref(false); // 学生家长弹窗是否显示
const deleteSClassLevelDialog = ref(false); // 确认删除学生家长弹窗是否显示
const deleteSClassesDialog = ref(false); // 批量删除学生家长弹窗是否显示
const selectedSClasses = ref(null);
const dt = ref(null);
const filters = ref({});
const submitted = ref(false);


onBeforeMount(() => {
  initFilters();
});

/**
 * 打开新增学生家长的弹窗
 */
function openNew() {
  studentHome.value = {
    id: 1,
    name: "张三的家长",
    gender: "男",
    age: "41",
    phone: "18888887777",
    student_id: "1",
    student_sclass_id: "1",
    student_sclass: "初一(3)班",
    student_name: "张三",
    relation: "父子"
  };
  isEdit.value = false
  submitted.value = false;
  sClassDialog.value = true;
}

/**
 * 新增学生家长
 */
function addStudentHome() {
  console.log("新增学生家长:", sClass.value)
  sClassDialog.value = false
}

const hideDialog = () => {
  sClassDialog.value = false;
  submitted.value = false;
};


/**
 * 编辑学生家长信息
 * @param data 要编辑的学生家长信息
 */
const editStudentHome = (data) => {
  sClass.value = {...data};
  console.log(sClass);
  isEdit.value = true
  sClassDialog.value = true;
};

/**
 * 确认删除学生家长
 * @param editStudentHome 要删除的学生家长信息
 */
const confirmDeleteStudentHome = (editStudentHome) => {
  sClass.value = editStudentHome;
  deleteSClassLevelDialog.value = true;
};

/**
 * 删除学生家长
 */
const deleteStudentHome = () => {
  sClasss = sClasss.filter((val) => val.id !== sClass.value.id);
  deleteSClassLevelDialog.value = false;
  sClass.value = {
    id: "1",
    name: "初一(1)班",
    level: 7,
    total: 20,
    student_id: "1",
    student_name: "张三",
    student_phone: "188811118888",
    teacher_id: "1",
    teacher_name: "张三的老师",
    teacher_phone: "188811118888",
    detail: "{}"
  };
  toast.add({severity: 'success', summary: '成功', detail: '删除学生家长', life: 3000});
};

const exportCSV = () => {
  dt.value.exportCSV();
};

const confirmDeleteSelected = () => {
  deleteSClassesDialog.value = true;
};

/**
 * 删除选中的学生家长
 */
const deleteSelectedStudentHome = () => {
  users = users.filter((val) => !selectedSClasses.value.includes(val));
  deleteSClassesDialog.value = false;
  selectedSClasses.value = null;
  toast.add({severity: 'success', summary: '成功', detail: '删除学生家长', life: 3000});
};

/**
 * 初始化过滤器
 */
const initFilters = () => {
  filters.value = {
    global: {value: null, matchMode: FilterMatchMode.CONTAINS}
  };
};
</script>

<template>
  <div class="grid">
    <div class="col-12">
      <div class="card">
        <!--消息提示-->
        <Toast/>
        <!--顶部工具栏-->
        <Toolbar class="mb-4">
          <!--左侧-->
          <template v-slot:start>
            <div class="my-2">
              <Button label="新增" icon="pi pi-plus" class="p-button-success mr-2" @click="openNew"/>
              <Button label="删除" icon="pi pi-trash" class="p-button-danger" @click="confirmDeleteSelected"
                      :disabled="!selectedSClasses || !selectedSClasses.length"/>
            </div>
          </template>
          <!--右侧-->
          <template v-slot:end>
            <FileUpload mode="basic" accept="image/*" :maxFileSize="1000000" label="Import" chooseLabel="导入"
                        class="mr-2 inline-block"/>
            <Button label="导出" icon="pi pi-upload" class="p-button-help" @click="exportCSV($event)"/>
          </template>
        </Toolbar>

        <!--数据表格-->
        <DataTable
            ref="dt"
            :value="teachers"
            v-model:selection="selectedSClasses"
            dataKey="id"
            :paginator="true"
            :rows="10"
            :filters="filters"
            paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
            :rowsPerPageOptions="[5, 10, 25]"
            currentPageReportTemplate="显示第 {first}-{last} 条数据,共 {totalRecords} 条"
            responsiveLayout="scroll"
        >
          <!--表头-->
          <template #header>
            <div class="flex flex-column md:flex-row md:justify-content-between md:align-items-center">
              <h5 class="m-0">老师管理</h5>
              <span class="block mt-2 md:mt-0 p-input-icon-left">
                  <i class="pi pi-search"/>
                  <InputText v-model="filters['global'].value" placeholder="搜索..."/>
              </span>
            </div>
          </template>

          <!--内容-->
          <Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
          <Column field="name" header="姓名" :sortable="true"></Column>
          <Column field="age" header="年龄" :sortable="true"></Column>
          <Column field="gender" header="性别" :sortable="true"></Column>
          <Column field="phone" header="电话" :sortable="true"></Column>
          <Column field="height" header="身高" :sortable="true"></Column>
          <Column field="weight" header="体重" :sortable="true"></Column>
          <Column field="course_name" header="教学科目" :sortable="true"></Column>
          <Column field="job" header="职位" :sortable="true"></Column>
          <Column field="job_age" header="工龄" :sortable="true"></Column>
          <Column field="job_time" header="入职时间" :sortable="true"></Column>
          <Column field="salary" header="工资" :sortable="true"></Column>
          <Column>
            <template #body="slotProps">
              <Button icon="pi pi-pencil" class="p-button-rounded p-button-success mr-2"
                      @click="editStudentHome(slotProps.data)"/>
              <Button icon="pi pi-trash" class="p-button-rounded p-button-warning mt-2"
                      @click="confirmDeleteStudentHome(slotProps.data)"/>
            </template>
          </Column>
        </DataTable>

        <!--新增弹窗-->
        <Dialog v-model:visible="sClassDialog"
                :style="{ width: '450px' }"
                header="新增学生家长"
                :modal="true"
                class="p-fluid">
          <div class="field">
            <label for="name">姓名</label>
            <InputText id="name" v-model.trim="studentHome.name"/>
          </div>
          <div class="field">
            <label for="age">年龄</label>
            <InputText id="age" v-model.trim="studentHome.age"/>
          </div>
          <div class="field">
            <label for="gender">性别</label>
            <InputText id="gender" v-model.trim="studentHome.gender"/>
          </div>
          <div class="field">
            <label for="phone">电话</label>
            <InputText id="phone" v-model.trim="studentHome.phone"/>
          </div>
          <!--只有在编辑状态,下面的内容才会显示-->
          <template v-if="isEdit">
            <div class="field">
              <label for="student">学生</label>
              <Dropdown id="student" v-model="student" :options="students" optionLabel="name" placeholder="请选择"/>
            </div>
            <div class="field">
              <label for="relation">关系</label>
              <InputText id="relation" v-model.trim="studentHome.relation"/>
            </div>
            <div class="field">
              <label for="student">学生家长</label>
              <Dropdown id="student" v-model="sClass" :options="sClasses" optionLabel="name" placeholder="请选择"/>
            </div>
          </template>
          <template #footer>
            <Button label="取消" icon="pi pi-times" class="p-button-text" @click="hideDialog"/>
            <Button label="保存" icon="pi pi-check" class="p-button-text" @click="addStudentHome"/>
          </template>
        </Dialog>

        <!--确认删除弹窗-->
        <Dialog v-model:visible="deleteSClassLevelDialog" :style="{ width: '450px' }" header="Confirm" :modal="true">
          <div class="flex align-items-center justify-content-center">
            <i class="pi pi-exclamation-triangle mr-3" style="font-size: 2rem"/>
            <span v-if="user">您确认要删除 <b>{{ user.name }}</b>吗?</span>
          </div>
          <template #footer>
            <Button label="取消" icon="pi pi-times" class="p-button-text" @click="deleteSClassLevelDialog = false"/>
            <Button label="确认" icon="pi pi-check" class="p-button-text" @click="deleteStudentHome"/>
          </template>
        </Dialog>

        <!--批量删除确认弹窗-->
        <Dialog v-model:visible="deleteSClassesDialog" :style="{ width: '450px' }" header="请确认" :modal="true">
          <div class="flex align-items-center justify-content-center">
            <i class="pi pi-exclamation-triangle mr-3" style="font-size: 2rem"/>
            <span v-if="user">删除后无法撤销,您确定要删除吗?</span>
          </div>
          <template #footer>
            <Button label="取消" icon="pi pi-times" class="p-button-text" @click="deleteSClassesDialog = false"/>
            <Button label="确认" icon="pi pi-check" class="p-button-text" @click="deleteSelectedStudentHome"/>
          </template>
        </Dialog>
      </div>
    </div>
  </div>
</template>


渲染效果:
在这里插入图片描述

实现级别增删改查

完整代码:

<script setup>
import {FilterMatchMode} from 'primevue/api';
import {ref, onBeforeMount} from 'vue';
import {useToast} from 'primevue/usetoast';
import teachers from "@/assets/data/teachers.json"

// 老师
const teacher = ref({
  id: "1",
  name: "张三的老师",
  phone: "18811118888",
  age: 33,
  gender: "男",
  height: 177,
  weight: 128,
  course_id: "1",
  course_name: "数学",
  job: "教导处主任",
  job_age: 5,
  job_time: "2018-06-09",
  salary: 12000,
  detail: "{}"
})

const sClass = ref(null) // 选取的老师信息

const toast = useToast();

const isEdit = ref(false) // 是否为编辑
const teacherDialog = ref(false); // 老师弹窗是否显示
const deleteTeacherDialog = ref(false); // 确认删除老师弹窗是否显示
const deleteTeachersDialog = ref(false); // 批量删除老师弹窗是否显示
const selectedTeachers = ref(null);
const dt = ref(null);
const filters = ref({});
const submitted = ref(false);


onBeforeMount(() => {
  initFilters();
});

/**
 * 打开新增老师的弹窗
 */
function openNew() {
  teacher.value = {
    id: "1",
    name: "张三的老师",
    phone: "18811118888",
    age: 33,
    gender: "男",
    height: 177,
    weight: 128,
    course_id: "1",
    course_name: "数学",
    job: "教导处主任",
    job_age: 5,
    job_time: "2018-06-09",
    salary: 12000,
    detail: "{}"
  };
  isEdit.value = false
  submitted.value = false;
  teacherDialog.value = true;
}

/**
 * 新增老师
 */
function addStudentHome() {
  console.log("新增老师:", sClass.value)
  teacherDialog.value = false
}

const hideDialog = () => {
  teacherDialog.value = false;
  submitted.value = false;
};


/**
 * 编辑老师信息
 * @param data 要编辑的老师信息
 */
const editTeacher = (data) => {
  teacher.value = {...data};
  console.log(teacher);
  isEdit.value = true
  teacherDialog.value = true;
};

/**
 * 确认删除老师
 * @param data 要删除的老师信息
 */
const confirmDeleteTeacher = (data) => {
  teacher.value = data;
  deleteTeacherDialog.value = true;
};

/**
 * 删除老师
 */
const deleteTeacher = () => {
  sClasss = sClasss.filter((val) => val.id !== sClass.value.id);
  deleteTeacherDialog.value = false;
  sClass.value = {
    id: 1,
    name: "张三的家长",
    gender: "男",
    age: "41",
    phone: "18888887777",
    student_id: "1",
    student_sclass_id: "1",
    student_sclass: "初一(3)班",
    student_name: "张三",
    relation: "父子"
  };
  toast.add({severity: 'success', summary: '成功', detail: '删除老师', life: 3000});
};

const exportCSV = () => {
  dt.value.exportCSV();
};

const confirmDeleteSelected = () => {
  deleteTeachersDialog.value = true;
};

/**
 * 删除选中的老师
 */
const deleteSelectedTeachers = () => {
  users = users.filter((val) => !selectedTeachers.value.includes(val));
  deleteTeachersDialog.value = false;
  selectedTeachers.value = null;
  toast.add({severity: 'success', summary: '成功', detail: '删除老师', life: 3000});
};

/**
 * 初始化过滤器
 */
const initFilters = () => {
  filters.value = {
    global: {value: null, matchMode: FilterMatchMode.CONTAINS}
  };
};
</script>

<template>
  <div class="grid">
    <div class="col-12">
      <div class="card">
        <!--消息提示-->
        <Toast/>
        <!--顶部工具栏-->
        <Toolbar class="mb-4">
          <!--左侧-->
          <template v-slot:start>
            <div class="my-2">
              <Button label="新增" icon="pi pi-plus" class="p-button-success mr-2" @click="openNew"/>
              <Button label="删除" icon="pi pi-trash" class="p-button-danger" @click="confirmDeleteSelected"
                      :disabled="!selectedTeachers || !selectedTeachers.length"/>
            </div>
          </template>
          <!--右侧-->
          <template v-slot:end>
            <FileUpload mode="basic" accept="image/*" :maxFileSize="1000000" label="Import" chooseLabel="导入"
                        class="mr-2 inline-block"/>
            <Button label="导出" icon="pi pi-upload" class="p-button-help" @click="exportCSV($event)"/>
          </template>
        </Toolbar>

        <!--数据表格-->
        <DataTable
            ref="dt"
            :value="teachers"
            v-model:selection="selectedTeachers"
            dataKey="id"
            :paginator="true"
            :rows="10"
            :filters="filters"
            paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
            :rowsPerPageOptions="[5, 10, 25]"
            currentPageReportTemplate="显示第 {first}-{last} 条数据,共 {totalRecords} 条"
            responsiveLayout="scroll"
        >
          <!--表头-->
          <template #header>
            <div class="flex flex-column md:flex-row md:justify-content-between md:align-items-center">
              <h5 class="m-0">老师管理</h5>
              <span class="block mt-2 md:mt-0 p-input-icon-left">
                  <i class="pi pi-search"/>
                  <InputText v-model="filters['global'].value" placeholder="搜索..."/>
              </span>
            </div>
          </template>

          <!--内容-->
          <Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
          <Column field="name" header="姓名" :sortable="true"></Column>
          <Column field="age" header="年龄" :sortable="true"></Column>
          <Column field="gender" header="性别" :sortable="true"></Column>
          <Column field="phone" header="电话" :sortable="true"></Column>
          <Column field="height" header="身高" :sortable="true"></Column>
          <Column field="weight" header="体重" :sortable="true"></Column>
          <Column field="course_name" header="教学科目" :sortable="true"></Column>
          <Column field="job" header="职位" :sortable="true"></Column>
          <Column field="job_age" header="工龄" :sortable="true"></Column>
          <Column field="job_time" header="入职时间" :sortable="true"></Column>
          <Column field="salary" header="工资" :sortable="true"></Column>
          <Column>
            <template #body="slotProps">
              <Button icon="pi pi-pencil" class="p-button-rounded p-button-success mr-2"
                      @click="editTeacher(slotProps.data)"/>
              <Button icon="pi pi-trash" class="p-button-rounded p-button-warning mt-2"
                      @click="confirmDeleteTeacher(slotProps.data)"/>
            </template>
          </Column>
        </DataTable>

        <!--新增弹窗-->
        <Dialog v-model:visible="teacherDialog"
                :style="{ width: '450px' }"
                header="新增老师"
                :modal="true"
                class="p-fluid">
          <div class="field">
            <label for="name">姓名</label>
            <InputText id="name" v-model.trim="teacher.name"/>
          </div>
          <div class="field">
            <label for="age">年龄</label>
            <InputText id="age" v-model.trim="teacher.age"/>
          </div>
          <div class="field">
            <label for="gender">性别</label>
            <InputText id="gender" v-model.trim="teacher.gender"/>
          </div>
          <div class="field">
            <label for="phone">电话</label>
            <InputText id="phone" v-model.trim="teacher.phone"/>
          </div>
          <div class="field">
            <label for="height">身高</label>
            <InputText id="height" v-model.trim="teacher.height"/>
          </div>
          <div class="field">
            <label for="weight">体重</label>
            <InputText id="weight" v-model.trim="teacher.weight"/>
          </div>
          <div class="field">
            <label for="course">科目</label>
            <InputText id="course" v-model.trim="teacher.course_name"/>
          </div>
          <div class="field">
            <label for="job">职位</label>
            <InputText id="job" v-model.trim="teacher.job"/>
          </div>
          <div class="field">
            <label for="job_time">入职时间</label>
            <InputText id="job_time" v-model.trim="teacher.job_time"/>
          </div>
          <div class="field">
            <label for="salary">工资</label>
            <InputText id="salary" v-model.trim="teacher.salary"/>
          </div>
          <template #footer>
            <Button label="取消" icon="pi pi-times" class="p-button-text" @click="hideDialog"/>
            <Button label="保存" icon="pi pi-check" class="p-button-text" @click="addStudentHome"/>
          </template>
        </Dialog>

        <!--确认删除弹窗-->
        <Dialog v-model:visible="deleteTeacherDialog" :style="{ width: '450px' }" header="Confirm" :modal="true">
          <div class="flex align-items-center justify-content-center">
            <i class="pi pi-exclamation-triangle mr-3" style="font-size: 2rem"/>
            <span v-if="teacher">您确认要删除 <b>{{ teacher.name }}</b>吗?</span>
          </div>
          <template #footer>
            <Button label="取消" icon="pi pi-times" class="p-button-text" @click="deleteTeacherDialog = false"/>
            <Button label="确认" icon="pi pi-check" class="p-button-text" @click="deleteTeacher"/>
          </template>
        </Dialog>

        <!--批量删除确认弹窗-->
        <Dialog v-model:visible="deleteTeachersDialog" :style="{ width: '450px' }" header="请确认" :modal="true">
          <div class="flex align-items-center justify-content-center">
            <i class="pi pi-exclamation-triangle mr-3" style="font-size: 2rem"/>
            <span v-if="teacher">删除后无法撤销,您确定要删除吗?</span>
          </div>
          <template #footer>
            <Button label="取消" icon="pi pi-times" class="p-button-text" @click="deleteTeachersDialog = false"/>
            <Button label="确认" icon="pi pi-check" class="p-button-text" @click="deleteSelectedTeachers"/>
          </template>
        </Dialog>
      </div>
    </div>
  </div>
</template>


渲染效果:
在这里插入图片描述

文章来源:https://blog.csdn.net/qq_37703224/article/details/135274002
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。