手摸手用element实现列表增删改查

表单界面涉及到数据的操作,会有几个关键点

  1. 表单的双向绑定v-model
  2. 表格的分页处理
  3. 新增和编辑的dialog,弹窗删除的dialog

index.vue文件解析

<template>
  <div>
    <!-- 条件查询 -->
    <el-form/>
    <!-- 表格 -->
    <el-table/>
    <!-- 分页组件 -->
    <el-pagination/>
    <!-- 弹框 -->
    <Edit/>
  </div>
 </template>
<script>
import api from "@/api/category"; //接口
import Edit from "./edit";  //弹窗
export default {
// 注册后使用
  components: {
    Edit,
  },
  data() {
    return {}
  },
  // 钩子函数获取数据 
  created() {
   this.fetchData();
  },
  //方法
  methods: {
  }
}
</script>

1.首先实现类别列表功能,包含数据列表、分页、条件查询 。

在这里插入图片描述

列表接口
请求URL: /article/category/search
请求方式: post
描述:文章类别分页条件查询列表

Api 调用接口

  1. 在 src/api 下创建 category.js , 调用接口代码如下:
import request from '@/utils/request'
export default {
  //分类查询列表
  getList(query, current = 1, size = 20) {
    return request({
      url: `/article/category/search`,
      method: 'post',
      data: {
        ...query,
        current,
        size
      }
    })
  }
  }
  1. 在 src\views\category\index.vue 中, 添加 JS 代码如下:
 <template> 
 </template>
  <script>
   import api from '@/api/category'
export default { 
data() { return {
 list: [], page: { // 分页相关
  total: 0, // 总记录数 
  current: 1, // 当前页码 
  size: 20, // 每页显示20条数据, 
  },
  query: {} // 查询条件
   } 
   },
   // 钩子函数获取数据 
   created () {
    this.fetchData() 
    },
    methods: {
    async fetchData() {
      const { data } = await api.getList(
        this.query,
        this.page.current,
        this.page.size
      );
      this.list = data.records;
      this.page.total = data.total;
    },
  }
 </script>

列表模板

  1. 修改 src\views\category\index.vue ,编写模板代码:<el-table>列表参考:https://element.eleme.cn/#/zh-CN/component/table 链接: link.
<template>
  <div>
    <!-- 表格 -->
    <el-table stripe :data="list" border style="width: 100%">
      <el-table-column align="center" width="60px" type="index" label="序号">
      </el-table-column>
      <el-table-column align="center" prop="name" label="分类名称">
      </el-table-column>
      <el-table-column align="center" prop="sort" label="排序">
      </el-table-column>
      <el-table-column align="center" prop="remark" label="备注">
      </el-table-column>
      <el-table-column align="center" prop="status" label="状态">
        <template slot-scope="scope">
          <el-tag :type="scope.row.status | statusFilter">
            {{ scope.row.status ? "正常" : "禁用" }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column align="center" label="操作">
        <template slot-scope="scope">
          <el-button
            type="primary"
            @click="handleEdit(scope.row.id)"
            size="mini"
            >编辑</el-button
          >
          <el-button
            type="danger"
            @click="handleDelete(scope.row.id)"
            size="mini"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>
  1. methods 选项中添加 handleEdit 编辑和 handleDelete 删除方法,后面需要使用。
methods: { fetchData () {
api.getList(this.query, this.page.current, this.page.size).then(response => { 
// console.log(response)
 this.list = response.data.records 
 this.page.total = response.data.total })
  }
 ,handleEdit(id) { 
 console.log('编辑', id)
  },
 handleDelete(id) { 
 console.log('删除', id) 
 }, 
 }

状态码转名称
渲染后发现状态码,我们将状态列以转为名称,并且使用 <el-tag> 标签包裹,其中通过 filters 选项来定义过滤器来实现样式转换。
<el-tag> 参考: https://element.eleme.cn/#/zh-CN/component/tag 链接: link.

  1. 定义 statusFilter 过滤器转换样式
export default { 
filters: { statusFilter(status) { 
// 样式 在这里插入代码片
const statusMap = {0: 'danger', 1: 'success'} 
// status等于0返回danger, 1返回success 
return statusMap[status] } },
//.... 
}
  1. methods 选项中添加 handleEdit 编辑和 handleDelete 删除方法,后面需要使用。
methods: { 
fetchData () { 
api.getList(this.query, this.page.current, this.page.size).then(response => { 
// console.log(response)
 this.list = response.data.records 
 this.page.total = response.data.total }) },
 handleEdit(id) { console.log('编辑', id) },
 handleDelete(id) { console.log('删除', id) }, }

分页查询实现

  1. 修改 src\views\category\index.vue ,在 template 标签中添加分页组件:
    注意:添加在 div 里面。因为 template 里面只能有唯一根节点
<!-- 分页组件 -->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="page.current"
      :page-sizes="[10, 20, 50]"
      :page-size="page.size"
      layout="total, sizes, prev, pager, next, jumper"
      :total="page.total"
    >
    </el-pagination>
  1. methods 选项中定义 handleSizeChange 每页条目数改变后触发的方法,和 handleCurrentChange 页面改变后触发的方法。
methods: { 
// 当每页显示条数改变后,被触发 , val是最新的每页显示条数
   handleSizeChange(val) { 
     this.page.size = val this.fetchData() 
   },// 当页码改变后,被触发 , val 是最新的页面 
   handleCurrentChange(val) { 
     this.page.current = val this.fetchData()
  },
  // ... 
 }
  1. 测试,查看浏览器控制台 Network 处提交数据
    在这里插入图片描述

条件查询实现
在列表上方添加查询功能。
Form 表单参考 :https://element.eleme.cn/#/zh-CN/component/form#xing-nei-biao-dan链接: link.
Select选择器:https://element.eleme.cn/#/zh-CN/component/select 链接: link.

  1. 修改 src\views\category\index.vue ,增加条件查询模板代码:
 <el-form 
 :inline="true" 
 :model="query" 
 size="mini"> 
 <el-form-item label="分类名称:"> 
 <el-input v-model.trim="query.name"></el-input>
 </el-form-item>
   <el-form-item label="状态:" > 
   <!-- clearable 清空按钮,filterable 是否可搜索 -->
    <el-select v-model="query.status" clearable filterable style="width: 85px"> 
    <el-option v-for="item in statusOptions" :key="item.code" :label="item.name" :value="item.code">
</el-option>
 </el-select>
  </el-form-item> 
  <el-form-item> 
  <el-button icon='el-icon-search' type="primary" @click="queryData">查询</el-button> 
  <el-button icon='el-icon-refresh' class="filter-item" @click="reload">重置</el-button> <el-button type="primary" size="mini" icon="el-icon-circle-plus-outline" >新增</el- button> 
  </el-form-item> 
  </el-form>
  1. 声明一个全局变量 payTypeOptions 用于状态下拉框,并在 data 选项声明与赋值 payTypeOptions 属性。
<script> import api from '@/api/category' // 用于下拉框 
const statusOptions = [ 
{code: 0, name: '禁用'},
 {code: 1, name: '正常'} ]
 export default { data() {
  return {
   list: [],
   page: {// 分页相关 
     total: 0, // 总记录数
     current: 1, // 当前页码 
     size: 20, // 每页显示20条数据,
    },
    query: {}, // 查询条件 
    statusOptions, //状态下拉框
  }
 },
  1. methods 声明 queryData 查询方法 , 主要是把 this.page.current 当前页面变为 1
methods: {
// 查询 
queryData() { 
// 将页码变为第1页 
this.page.current = 1 this.fetchData()
 },
  1. 重置功能:在 methods 选项中添加 reload 方法,模板中触发调用此方法
methods: { 
// 重置 or 刷新当前页面
 reload() { 
 this.query = {} 
 this.fetchData() 
 },
 // ... 
 }

2.新增功能

  1. 点击 新增 按钮后,对话框形式弹出新增窗口
  2. 输入分类信息后,点击 确定 提交表单数据;
    在这里插入图片描述

新增窗口实现
新增和修改功能共用一个组件,我们将它作为子组件引入到列表查询父组件中,下面先将组件定义出来。
弹出功能参考:https://element.eleme.cn/#/zh-CN/component/dialog#zi-ding-yi-nei-rong 链接: link.
el-dialog 标答属性 title 窗口标题, visible.sync 是否弹出窗口
注意其中包含多行文本编辑框。

  1. 创建新增和修改的组件文件: src\views\category\edit.vue
  2. 定义模板代码
<template>
  <el-dialog
    :title="title"
    :visible.sync="visible"
    width="500px"
    :before-close="handleClose"
  >
    <el-form
      ref="formData"
      :model="formData"
      label-width="100px"
      label-position="right"
      style="width: 400px"
    >
      <el-form-item label="分类名称:" prop="name">
        <el-input v-model="formData.name"></el-input>
      </el-form-item>
      <el-form-item label="状态:" prop="status">
        <el-radio-group v-model="formData.status">
          <el-radio :label="1" value="1">正常</el-radio>
          <el-radio :label="0" value="0">禁用</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="排序:" prop="sort">
        <el-input-number
          v-model="formData.sort"
          :min="1"
          :max="10000"
          style="width: 295px"
        ></el-input-number>
      </el-form-item>
      <el-form-item label="备注:" prop="remark">
        <el-input type="textarea" v-model="formData.remark"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('formData')"
          >确定</el-button
        >
        <el-button @click="handleClose">取消</el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>
 注意:每个 el-form-item 不要少了 prop ,不然清空不了数据。
  1. 新增功能中引用的属性都通过父组件传递过来,下面我们将它们通过 props 声明出来,并且在
    methods 中声明 handleClose 关闭弹窗和 submitForm 确定提交表单方法
<script> export default { 
// 接收父组件传递的属性 
props: {
 visible: { 
 //弹出隐藏 
 type: Boolean, 
 default: false 
 },
 title: { 
 // 标题 
 type: String,
 default: '' 
 },
formData: { 
// 表单数据
 type: Object, 
 default: {} 
 },
 remoteClose: Function // 用于关闭窗口
},
  methods: { 
  // 关闭弹窗 
  handleClose(done) { },//提交表单 
  submitForm(formName) { },
   }
} 
</script>

列表引用新增组件
在父组件 category/index.vue 引用 category/edit.vue 子组件实现弹窗

  1. 导入 edit.vue 组件,并使用 components 选项引用为子组件
<script>
 import api from '@/api/category'
 import Edit from './edit'
   export default {
    components: {
     Edit
     }, 
    //...
     }
     </script>
  1. 模板中使用 <Edit> 子组件
 <template> <div > 
 <!-- 条件查询 -->
  <!-- 数据列表 -->
   <!-- 分页组件 --> 
   <!-- 新增与编辑组件 --> 
    <Edit
      :title="edit.title"
      :visible="edit.visible"
      :formData="edit.formData"
      :remoteClose="remoteClose"
    />
     </div> 
     </template>
  1. data 选项中声明传递给子组件的属性、方法
<script>
 import api from '@/api/category'
  import Edit from './edit' 
  export default {
   components: { Edit },
    data() { 
    return { //... 
    edit: { // 子组件中引用 
    title: '', 
    visible: false,
     formData: {}
      } 
      } 
      },
      methods: { // 触发关闭弹出的新增修改子组件窗口 
      remoteClose() {
       }, } }
       </script>
  1. 为 新增 按钮绑定点击事件 @click="openAdd" 弹出窗口
<el-button
       icon="el-icon-circle-plus-outline"
       type="primary"
       @click="openAdd"
       >新增
</el-button>
methods: { 
//打开新增窗口 
openAdd() {
      this.edit.visible = true;
      this.edit.title = "新增";
    },
    //... 
    }
  1. 测试是否正常打开
    注意: 要在 el-form-item 标签的 prop 属性中指定字段名, 不然有时间会输入框输入不了,如果还是输入不了,在 index.vue 组件中的 edit.formData 中将字段名指定出来
data() {
 return { 
 edit: { // 子组件中引用 
 title: '', 
 visible: false,
  formData: { 
  id: null,
   name: '', 
   sort: null, 
   remark: '' }
    }} 
  }

关闭弹出窗口
当点击 取消 按钮或者右上角 X 将关闭窗口

  1. 错误的关闭窗口方式:
    注意:不能在子组件 edit.vue 中直接将 this.visible = false 关闭窗口,因为它是父组件传递过来的,子组件不能直接改。
// 关闭弹窗 
handleClose(done) { 
//this.visible = false错误的,因为它是父组件传递过来的,子组件不能直接改 
},
  1. 正确的关闭窗口方式:
    在edit.vue 子组件中触发 list.vue 父组件的 remoteClose 方法来关闭窗口。
    edit.vue 中触发父组件的 remoteClose,并重置清空表单数据
methods: { 
// 关闭弹窗
 handleClose(done) { 
 // 表单清空 
 this.$refs['formData'].resetFields() 
 // this.visible
  // 错误的,因为它是父组件传递过来的,子组件不能直接改 // 因为 visible 是父组件的属性,所以要让父组件去改变值 
 this.remoteClose() },
 //提交表单 
 submitForm(formName) { 
 }, }
  1. 在 index.vue 中将 this.edit.visiable=false 关闭窗口,刷新数据。
methods: { 
//打开新增窗口
 openAdd() { 
 this.edit.visible = true this.edit.title = '新增' },// 触发关闭弹出的新增修改子组件窗口 
 remoteClose() { // 一定要加上这个,不然有时候表单输入不了值
  this.edit.formData = {} t
  his.edit.visible = false 
  this.fetchData() 
  }

校验表单数据

  1. 在 edit.vue 新增窗口的 el-form 上绑定属性 :rules="rules"
<template>
 <!--弹窗--> 
 <el-dialog 
 :title="title" 
 :visible.sync="visible"
 :before-close="handleClose"
  width="500px">
  <!-- status-icon 当表单校验不通过时, 输入框右侧有个 x 小图标 -->
  <el-form :rules="rules"
  1. 在 data 选项中添加 rules 属性进行校验
  data() {
    return {
      rules: {
        // porp值
        name: [{ required: true, message: "请输入分类名称", trigger: "blur" }],
        status: [
          { required: true, message: "请输入分类名称", trigger: "change" },
        ],
        sort: [{ required: true, message: "请输入分类名称", trigger: "blur" }],
      },
    };
  },

提交表单数据
当点击新增窗口中的确认按钮时, 提交表单数据,后台API服务接口响应新增成功或失败。
请求URL: /article/category
请求方式: post

Api 调用接口

  1. 在 src\api\category.js 添加调用新增接口的方法
 add(data) {
    return request({
      url: `/article/category`,
      method: 'post',
      data
    })
  },

  1. 在 src\views\category\edit.vue 中的 submitForm 方法中判断校验是否通过,通过了则调用 submitData异步方法提交数据,代码如下:

注意: async submitData(){} 不要少了前面的 async

<script> import api from '@/api/category' 
export default { 
//..., 
methods: {
 // ... 
//2. 提交表单
   // 2.提交表单数据
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          // 校验通过,提交表单数据
          this.submitData();
        } else {
          // 校验不通过
          return false;
        }
      });
    },
//3. 异步方法提交数据
    async submitData() {
      let response = null;
      if (this.formData.id) {
        //编辑
        response = await api.update(this.formData);
      } else {
        //新增
        response = await api.add(this.formData);
      }
      // 等上面返回数据response后再进行处理
      if (response.code === 20000) {
        // 提交成功, 关闭窗口, 刷新列表
        this.$message({
          showClose: true,
          message: "保存成功",
          type: "success",
        });
        // 关闭窗口
        this.handleClose();
      } else {
        this.$message({
          showClose: true,
          message: "保存失败",
          type: "error",
        });
      }
    },
   </script>

3.修改功能

当点击 编辑 按钮后,弹出编辑窗口,并查询出分类相关信息进行渲染。修改后点击 确定 提交修改后的数据。
在这里插入图片描述

添加查询数据
请求URL: /article/category/{id}
请求方式: get
描述:通过类别 ID 查询数据接口

添加提交修改数据
请求URL: /article/category
请求方式: put
描述:类别数据更新

Api 调用接口回显数据

  1. src\api\category.js 添加通过ID查询方法 getById 和 更新方法 update
// 查询类别详情
  getById(id) {
    return request({
      url: `/article/category/${id}`,
      method: 'get'
    })
  },

  //更新
  update(data) {
    return request({
      url: `/article/category`,
      method: 'put',
      data
    })
  },
  1. 在 src\views\category\index.vue 中的 handleEdit 方法做如下修改:再特别强调下是 index.vue,不是 edit.vue
 handleEdit(id) {
      //通过id查询详情
      api.getById(id).then((response) => {
        if (response.code === 20000) {
          // 将查询的详情传递
          this.edit.formData = response.data;
          this.edit.title = "编辑";
          this.edit.visible = true;
        }
      });
    },

提交修改后的数据
在 src/views/category/edit.vue 组件中的 submitData 方法加上一个判断 this.formData.id 存在则为更新,否则是新增操作。

 // 提交表单数据
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          // 校验通过,提交表单数据
          this.submitData();
        } else {
          // 校验不通过
          return false;
        }
      });
    },
    
    // 异步方法提交数据
    async submitData() {
      let response = null;
      if (this.formData.id) {
        //编辑
        response = await api.update(this.formData);
      } else {
        //新增
        response = await api.add(this.formData);
      }
      // 等上面返回数据response后再进行处理
      if (response.code === 20000) {
        // 提交成功, 关闭窗口, 刷新列表
        this.$message({
          showClose: true,
          message: "保存成功",
          type: "success",
        });
        // 关闭窗口
        this.handleClose();
      } else {
        this.$message({
          showClose: true,
          message: "保存失败",
          type: "error",
        });
      }
    },
  },
};

3.删除功能

当点击删除按钮后, 弹出提示框,点击确定后,执行删除并刷新列表数据
确认消息弹框参考:https://element.eleme.cn/#/zh-CN/component/message-box#que-ren-xiao-xi 链接: link.
在这里插入图片描述
删除接口
请求URL: /article/category/{id}
请求方式: delete
描述:根据ID删除类别

Api 调用接口

  1. src\api\category.js 添加 deleteById 方法
  //删除
  deleteById(id) {
    return request({
      url: `/article/category/${id}`,//单反引号
      method: 'delete',// delete 方式提交
    })
  },
  1. 在 src\views\category\index.vue 中的 handleDelete 方法做如下修改:
// 删除 
handleDelete(id) {
 this.$confirm('确认删除这条记录吗?', '提示', { confirmButtonText: '确定', 
 cancelButtonText: '取消', 
 type: 'warning'}).then(() => { 
 // 确认
  api.deleteById(id).then(response => { 
  //提示信息 
  this.$message({ type: response.code===20000 ? 'success':'error',
   message: response.message 
   })
  // 刷新列表 
  this.fetchData() }) }).catch(() => { 
  // 取消删除,不理会 
  }) 
  }
  1. 检查 删除 按钮是否和下面代码一致
   <el-table-column align="center" label="操作">
        <template slot-scope="scope">
          <el-button
            type="primary"
            @click="handleEdit(scope.row.id)"
            size="mini"
            >编辑</el-button
          >
          <el-button
            type="danger"
            @click="handleDelete(scope.row.id)"
            size="mini"
            >删除</el-button
          >
        </template>
      </el-table-column>
      

完整代码

category/index.vue

<template>
  <div>
    <!-- 条件查询 -->
    <el-form :inline="true" :model="query" size="small ">
      <el-form-item label="分类名称">
        <el-input v-model="query.name" placeholder="审批人"></el-input>
      </el-form-item>
      <el-form-item label="状态">
        <el-select
          v-model="query.status"
          clearable
          filterable
          style="width: 85px"
        >
          <el-option label="正常" value="1"></el-option>
          <el-option label="禁用" value="0"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button icon="el-icon-search" type="primary" @click="queryData"
          >查询</el-button
        >
        <el-button icon="el-icon-refresh" @click="reload">重置</el-button>
        <el-button
          icon="el-icon-circle-plus-outline"
          type="primary"
          @click="openAdd"
          >新增</el-button
        >
      </el-form-item>
    </el-form>
    <!-- 表格 -->
    <el-table stripe :data="list" border style="width: 100%">
      <el-table-column align="center" width="60px" type="index" label="序号">
      </el-table-column>
      <el-table-column align="center" prop="name" label="分类名称">
      </el-table-column>
      <el-table-column align="center" prop="sort" label="排序">
      </el-table-column>
      <el-table-column align="center" prop="remark" label="备注">
      </el-table-column>
      <el-table-column align="center" prop="status" label="状态">
        <template slot-scope="scope">
          <el-tag :type="scope.row.status | statusFilter">
            {{ scope.row.status ? "正常" : "禁用" }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column align="center" label="操作">
        <template slot-scope="scope">
          <el-button
            type="primary"
            @click="handleEdit(scope.row.id)"
            size="mini"
            >编辑</el-button
          >
          <el-button
            type="danger"
            @click="handleDelete(scope.row.id)"
            size="mini"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件 -->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="page.current"
      :page-sizes="[10, 20, 50]"
      :page-size="page.size"
      layout="total, sizes, prev, pager, next, jumper"
      :total="page.total"
    >
    </el-pagination>
    <!-- 弹框 -->
    <Edit
      :title="edit.title"
      :visible="edit.visible"
      :formData="edit.formData"
      :remoteClose="remoteClose"
    />
  </div>
</template>
<script>
import api from "@/api/category";
import Edit from "./edit";
export default {
  name: "Category", //和对应路由表中配置的name值一致
  components: {
    Edit,
  },
  data() {
    return {
      query: {}, //查询条件
      list: [],
      page: {
        current: 1, //当前页码
        size: 20, //每页显示多少条
        total: 0, //总计录数
      },
      // statusOptions, // 状态下拉框数组
      edit: {
        title: "",
        visible: false,
        formData: {},
      },
    };
  },

  filters: {
    statusFilter(status) {
      // 0 禁用,1 正常
      const statusMap = { 0: "danger", 1: "success" };
      return statusMap[status];
    },
  },

  created() {
    this.fetchData();
  },
  methods: {
    fetchData() {
      api
        .getList(this.query, this.page.current, this.page.size)
        .then((response) => {
          this.list = response.data.records;
          this.page.total = response.data.total;
        });
    },

    handleEdit(id) {
      //通过id查询详情
      api.getById(id).then((response) => {
        if (response.code === 20000) {
          // 将查询的详情传递
          this.edit.formData = response.data;
          this.edit.title = "编辑";
          this.edit.visible = true;
        }
      });
    },

    //删除
    handleDelete(id) {
      this.$confirm("确认删除这条记录吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          // 发送删除请求
          api.deleteById(id).then((response) => {
            this.$message({
              type: response.code === 20000 ? "success" : "error",
              message: response.message,
            });
          });
          //刷新列表数据
          this.fetchData();
        })
        .catch(() => {
          //取消删除,不用理会
        });
    },

    //val 是切换之后的每页显示多少条
    handleSizeChange(val) {
      this.page.size = val;
      this.fetchData();
    },
    handleCurrentChange(val) {
      this.page.current = val;
      this.fetchData();
    },
    // 条件查询
    queryData() {
      //将页码变为1,第1页
      this.page.current;
      this.fetchData();
    },
    //重置
    reload() {
      this.query = {};
      this.fetchData();
    },
    // 关闭窗口
    remoteClose() {
      this.edit.formData = {};
      this.edit.visible = false;
      this.fetchData();
    },
    // 点击新增
    openAdd() {
      this.edit.visible = true;
      this.edit.title = "新增";
    },
  },
};
</script>

category/edit.vue

<template>
  <el-dialog
    :title="title"
    :visible.sync="visible"
    width="500px"
    :before-close="handleClose"
  >
    <el-form
      :rules="rules"
      ref="formData"
      :model="formData"
      label-width="100px"
      label-position="right"
      style="width: 400px"
    >
      <el-form-item label="分类名称:" prop="name">
        <el-input v-model="formData.name"></el-input>
      </el-form-item>
      <el-form-item label="状态:" prop="status">
        <el-radio-group v-model="formData.status">
          <el-radio :label="1" value="1">正常</el-radio>
          <el-radio :label="0" value="0">禁用</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="排序:" prop="sort">
        <el-input-number
          v-model="formData.sort"
          :min="1"
          :max="10000"
          style="width: 295px"
        ></el-input-number>
      </el-form-item>
      <el-form-item label="备注:" prop="remark">
        <el-input type="textarea" v-model="formData.remark"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm('formData')"
          >确定</el-button
        >
        <el-button @click="handleClose">取消</el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>

<script>
import api from "@/api/category";
export default {
  props: {
    //弹窗标题
    title: {
      type: String,
      default: "",
    },
    // 弹出窗口,true弹出
    visible: {
      type: Boolean,
      default: false,
    },
    // 提交表单数据
    formData: {
      type: Object,
      default: {},
    },
    remoteClose: Function, // 用于关闭窗口
  },
  data() {
    return {
      rules: {
        // porp值
        name: [{ required: true, message: "请输入分类名称", trigger: "blur" }],
        status: [
          { required: true, message: "请输入分类名称", trigger: "change" },
        ],
        sort: [{ required: true, message: "请输入分类名称", trigger: "blur" }],
      },
    };
  },

  methods: {
    // 关闭窗口
    handleClose() {
      this.$refs["formData"].resetFields();
      // 注意不可以通过 this.visble = false 来关闭,因为它是父组件的属性
      this.remoteClose();
    },
    // 提交表单数据
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          // 校验通过,提交表单数据
          this.submitData();
        } else {
          // 校验不通过
          return false;
        }
      });
    },
    
    // 异步方法提交数据
    async submitData() {
      let response = null;
      if (this.formData.id) {
        //编辑
        response = await api.update(this.formData);
      } else {
        //新增
        response = await api.add(this.formData);
      }
      // 等上面返回数据response后再进行处理
      if (response.code === 20000) {
        // 提交成功, 关闭窗口, 刷新列表
        this.$message({
          showClose: true,
          message: "保存成功",
          type: "success",
        });
        // 关闭窗口
        this.handleClose();
      } else {
        this.$message({
          showClose: true,
          message: "保存失败",
          type: "error",
        });
      }
    },
  },
};
</script>
<style>
</style>

api/category.js

import request from '@/utils/request'

export default {
  //分类查询列表
  getList(query, current = 1, size = 20) {
    return request({
      url: `/article/category/search`,
      method: 'post',
      data: {
        ...query,
        current,
        size
      }
    })
  },
  add(data) {
    return request({
      url: `/article/category`,
      method: 'post',
      data
    })
  },

  // 查询类别详情
  getById(id) {
    return request({
      url: `/article/category/${id}`,
      method: 'get'
    })
  },

  //更新
  update(data) {
    return request({
      url: `/article/category`,
      method: 'put',
      data
    })
  },

  //删除
  deleteById(id) {
    return request({
      url: `/article/category/${id}`,
      method: 'delete',
    })
  },

  // 查询类别详情
  getNormalList() {
    return request({
      url: `/article/category/list`,
      method: 'get'
    })
  },

  // 获取所有正常状态的分类和标签
  getCategoryAndLabel() {
    return request({
      url: `/article/category/label/list`,
      method: 'get'
    })
  },
}
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值