前端路线--Vue(day26)

笔记

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

知识点

get:获取数据
post:提交数据
put:修改数据
delete:删除数据

分类列表表格的编辑操作

//分类列表
<!--  -->
<template>
  <div class="category_list">
    <el-card>
      <!-- 面包屑 -->
      <el-breadcrumb
        separator-class="el-icon-arrow-right"
        style="margin: 0px 0px 20px"
      >
        <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
        <el-breadcrumb-item><a href="/">用户信息</a></el-breadcrumb-item>
        <el-breadcrumb-item>分类列表</el-breadcrumb-item>
      </el-breadcrumb>
      <!--树形懒加载的表格  -->
      <el-table
        :data="categoryListDatas.data"
        style="width: 100%"
        row-key="id"
        border
        lazy
        :load="load"
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
      >
        <el-table-column prop="id" label="ID" width="180"> </el-table-column>
        <el-table-column prop="pic" label="用户头像" width="180">
          <template slot-scope="scope">
            <img
              :src="'http://localhost:3000/' + scope.row.pic"
              alt=""
              style="width: 60px; height: 50px"
            />
          </template>
        </el-table-column>
        <el-table-column prop="title" label="分类名称"> </el-table-column>

        <el-table-column fixed="right" label="操作" width="100">
          <template slot-scope="scope">
            <el-button @click="handleClick(scope.row)" type="text" size="small"
              >修改</el-button
            >
            <el-button type="text" size="small" @click="delClick(scope.row)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页 -->
      <div class="block" style="margin: 20px auto">
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="currentPage1"
          :page-sizes="[5, 10, 15, 20]"
          :page-size="size"
          layout="total, sizes, prev, pager, next, jumper"
          :total="categoryListDatas.count"
          background
        >
        </el-pagination>
        <!-- 点击修改出现的弹窗 
      在data中定义dialogUsereditFormVisible默认为false,默认隐藏,
      点击修改变为true
    -->
        <el-dialog title="修改用户" :visible.sync="dialogCateeditFormVisible">
          <el-form :model="editForm" label-width="80px">
            <el-form-item label="类别">
              <!-- 级联菜单 -->
              <el-cascader
                :options="chooseCateDatas"
                :props="{ checkStrictly: true }"
                clearable
                @change="handleChange"
              ></el-cascader>
            </el-form-item>
            <el-form-item label="分类名">
              <el-input v-model="editForm.title"></el-input>
            </el-form-item>
            <el-form-item label="用户头像">
              <el-upload
                class="avatar-uploader"
                action="http://localhost:3000/api/upload"
                :show-file-list="false"
                :on-success="handleAvatarSuccess"
                :before-upload="beforeAvatarUpload"
              >
                <img
                  v-if="imageUrl"
                  :src="'http://localhost:3000/' + imageUrl"
                  class="avatar"
                />
                <i v-else class="el-icon-plus avatar-uploader-icon"></i>
              </el-upload>
            </el-form-item>
            <el-form-item label="是否可用">
              <el-switch
                v-model="editForm.is_show"
                active-color="#13ce66"
                inactive-color="#ff4949"
                active-text="开"
                inactive-text="关"
                active-value="1"
                inactive-value="0"
              >
              </el-switch>
            </el-form-item>
          </el-form>

          <div slot="footer" class="dialog-footer">
            <el-button @click="dialogCateeditFormVisible = false"
              >取 消</el-button
            >
            <el-button type="primary" @click="editCateOk">确 定</el-button>
          </div>
        </el-dialog>
      </div>
    </el-card>
  </div>
</template>

<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
import { CategoryListTwoApi, EditCateApi, DelCateApi } from "@/api/product.js";
export default {
  //import引入的组件需要注入到对象中才能使用
  components: {},
  data() {
    //这里存放数据
    return {
      // 分页的数据
      page: 1,
      size: 5,
      currentPage1: 1,
      // dialog对话框的数据
      dialogCateeditFormVisible: false,
      // 上传头像的数据
      imageUrl: "",
      // 添加按钮表单里的数据
      editForm: {
        title: "",
        is_show: "1",
      },
      // 树形懒加载表格的数据
      // tableData1: [
      //   {
      //     id: 1,
      //     date: "2016-05-02",
      //     name: "王小虎",
      //     address: "上海市普陀区金沙江路 1518 弄",
      //   },
      //   {
      //     id: 2,
      //     date: "2016-05-04",
      //     name: "王小虎",
      //     address: "上海市普陀区金沙江路 1517 弄",
      //   },
      //   {
      //     id: 3,
      //     date: "2016-05-01",
      //     name: "王小虎",
      //     address: "上海市普陀区金沙江路 1519 弄",
      //     hasChildren: true,
      //   },
      //   {
      //     id: 4,
      //     date: "2016-05-03",
      //     name: "王小虎",
      //     address: "上海市普陀区金沙江路 1516 弄",
      //   },
      // ],
      // 级联菜单的数据
      // options: [
      //   {
      //     id: 1,
      //     value: "1",
      //     label: "大家电",
      //     children: [
      //       {
      //         id: 1001,
      //         value: "1001",
      //         label: "厨房电器",
      //         children: [
      //           {
      //             id: 10001,
      //             value: "10001",
      //             label: "电饭锅",
      //           },
      //         ],
      //       },
      //     ],
      //   },
      // ],
    };
  },
  //计算属性 类似于data概念
  computed: {
    // 树形懒加载表格的数据
    categoryListDatas() {
      return this.$store.state.products.categoryListDatas;
    },
    // 级联菜单的数据
    chooseCateDatas() {
      return this.$store.state.products.chooseCategoryDatas;
    },
  },
  //监控data中的数据变化
  watch: {},
  //方法集合
  methods: {
    // 树形懒加载表格的方法
    async load(tree, treeNode, resolve) {
      // tree.id对应数据库中的产品分类id
      console.log(tree.id, treeNode);
      // 在此可以进行二级分类的axios异步请求
      let subProducts = [];
      let result = await CategoryListTwoApi(tree.id);
      console.log(result.data.data);
      subProducts = result.data.data;
      setTimeout(() => {
        resolve(subProducts);
      }, 200);
    },
    //表格的操作的方法
    handleClick(row) {
      console.log(row);
      this.dialogCateeditFormVisible = true;
      // 点击修改按钮让当前行的数据显示在对话框里
      this.editForm = row;
    },
    // 分页的事件
    handleSizeChange(val) {
      console.log(`每页 ${val}`);
      // 将页数等于第一页
      this.page = 1;
      this.size = val;
      // 提交派遣分页数据给store的user.js
      this.$store.dispatch("actChangeCategoryListDatas", {
        page: this.page,
        size: this.size,
      });
    },
    handleCurrentChange(val) {
      console.log(`当前页: ${val}`);
      //将页数等于当前页
      this.page = val;
      // 提交派遣分页数据给store的user.js
      this.$store.dispatch("actChangeCategoryListDatas", {
        page: this.page,
        size: this.size,
      });
    },

    // 点击对话框的确定按钮发出axios请求来修改数据库的内容
    async editCateOk() {
      //将图片给addForm
      this.$set(this.editForm, "pic", this.imageUrl);
      // 发起修改分类的异步请求
      EditCateApi(this.editForm).then((result) => {
        if (result.data.status == 200) {
          // 刷新数据
          this.$store.dispatch("actChangeCategoryListDatas", {
            page: this.page,
            size: this.size,
          });
          this.dialogCateeditFormVisible = false;
        } else {
          alert("修改失败");
        }
      });
    },
    // 上传头像的方法
    handleAvatarSuccess(res, file) {
      console.log(res); //返回的是接口返回的数据
      console.log(file);
      // 让imageUrl上传图像的数据等于后台响应回来的值
      this.imageUrl = res.imgPath;
    },
    beforeAvatarUpload(file) {
      const isJPG =
        file.type === "image/jpeg" ||
        file.type === "image/gif" ||
        file.type === "image/png";
      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isJPG) {
        this.$message.error("上传头像图片只能是 JPG 格式!");
      }
      if (!isLt2M) {
        this.$message.error("上传头像图片大小不能超过 2MB!");
      }
      return isJPG && isLt2M;
    },
    // 级联菜单的方法
    handleChange(value) {
      console.log(value);
      //pid就是value这个数组的最后一项
      let pid = value[value.length - 1];
      // 把pid给addForm数据
      this.$set(this.editForm, "pid", pid);
    },
    // 点击删除按钮出现的messageBox
    delClick(row) {
      this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          DelCateApi(row).then((result) => {
            if (result.data.status == 200) {
              // 刷新数据
              this.$store.dispatch("actChangeCategoryListDatas", {
                page: this.page,
                size: this.size,
              });
              location.reload();
            } else {
              alert(result.data.msg);
            }
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },
  },
  //生命周期 - 挂载完成(可以访问DOM元素)
  mounted() {
    // 获取到分类列表的数据
    this.$store.dispatch("actChangeCategoryListDatas", {
      page: this.page,
      size: this.size,
    });
    //获取到级联菜单的数据
    this.$store.dispatch("actChangeChooseCategoryDatas");
  },
  beforeUpdate() {}, //生命周期 - 更新之前
  updated() {}, //生命周期 - 更新之后
  beforeDestroy() {}, //生命周期 - 销毁之前
  destroyed() {}, //生命周期 - 销毁完成
  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
};
</script>
<style lang="scss">
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 78px;
  height: 78px;
  line-height: 78px;
  text-align: center;
}
.avatar {
  width: 78px;
  height: 78px;
  display: block;
}
</style>

后台:
级联菜单的接口业务:

// 级联菜单的业务
let ChooseCategory=async (req,res)=>{
	// 别名查询出一级菜单
	let sql=`select id, id as value,title as label from hg_category WHERE pid=0`;
	let result=await request(sql);
	// 给一级菜单的数据添加上二级菜单
	for(let i=0;i<result.length;i++){
		let sql2=`select id, id as value,title as label from hg_category WHERE pid=${result[i].id}`;
		let result2=await request(sql2);
		result[i].children=result2;
	}
	result.unshift({
		value:0,
		label:"顶级分类"
	})
	res.json({
		status:200,
		data:result
	})
}
// 修改分类的业务
let EditCategory=async (req,res)=>{
	let {title,is_show,pid,pic,id}=req.body;
	let create_time=moment().format("YYYY-MM-DD hh:mm:ss");
		//修改的sql语句
		let sql=`UPDATE hg_category SET title="${title}",is_show=${is_show},pic="${pic}",create_time="${create_time}" WHERE id=${id}`;
		let result=await request(sql);
		res.json({
			status:200,
			msg:"修改成功",
			data:result
		})
}

添加分类页面

<!--  -->
<template>
  <div class="category_add">
    <el-card>
      <!-- 面包屑 -->
      <el-breadcrumb
        separator-class="el-icon-arrow-right"
        style="margin: 0px 0px 20px"
      >
        <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
        <el-breadcrumb-item><a href="/">用户信息</a></el-breadcrumb-item>
        <el-breadcrumb-item>分类列表</el-breadcrumb-item>
      </el-breadcrumb>
      <!-- 添加的表单 -->
      <el-form :model="addForm" label-width="80px" ref="ruleForm">
        <el-form-item label="类别">
          <!-- 级联菜单 -->
          <el-cascader
            :options="chooseCateDatas"
            :props="{ checkStrictly: true }"
            clearable
            @change="handleChange"
          ></el-cascader>
        </el-form-item>
        <el-form-item label="分类名">
          <el-input v-model="addForm.title"></el-input>
        </el-form-item>
        <el-form-item label="用户头像">
          <el-upload
            class="avatar-uploader"
            action="http://localhost:3000/api/upload"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
          >
            <img
              v-if="imageUrl"
              :src="'http://localhost:3000/' + imageUrl"
              class="avatar"
            />
            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
          </el-upload>
        </el-form-item>
        <el-form-item label="是否可用">
          <el-switch
            v-model="addForm.is_show"
            active-color="#13ce66"
            inactive-color="#ff4949"
            active-text="开"
            inactive-text="关"
            active-value="1"
            inactive-value="0"
          >
          </el-switch>
        </el-form-item>
        <!-- 添加按钮 -->
        <el-form-item>
          <el-button type="primary" @click="submitForm('ruleForm')"
            >添加</el-button
          >
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
import { addCateApi } from "@/api/product.js";
export default {
  //import引入的组件需要注入到对象中才能使用
  components: {},
  data() {
    //这里存放数据
    return {
      // 上传头像的数据
      imageUrl: "",
      // 表单里的数据
      addForm: {
        title: "",
        is_show: "1",
      },
      // 级联菜单的数据
      // options: [
      //   {
      //     id: 1,
      //     value: "1",
      //     label: "大家电",
      //     children: [
      //       {
      //         id: 1001,
      //         value: "1001",
      //         label: "厨房电器",
      //         children: [
      //           {
      //             id: 10001,
      //             value: "10001",
      //             label: "电饭锅",
      //           },
      //         ],
      //       },
      //     ],
      //   },
      // ],
    };
  },
  //计算属性 类似于data概念
  computed: {
    // 级联菜单的数据
    chooseCateDatas() {
      return this.$store.state.products.chooseCategoryDatas;
    },
  },
  //监控data中的数据变化
  watch: {},
  //方法集合
  methods: {
    // 上传头像的方法
    handleAvatarSuccess(res, file) {
      console.log(res); //返回的是接口返回的数据
      console.log(file);
      // 让imageUrl上传图像的数据等于后台响应回来的值
      this.imageUrl = res.imgPath;
    },
    beforeAvatarUpload(file) {
      const isJPG =
        file.type === "image/jpeg" ||
        file.type === "image/gif" ||
        file.type === "image/png";
      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isJPG) {
        this.$message.error("上传头像图片只能是 JPG 格式!");
      }
      if (!isLt2M) {
        this.$message.error("上传头像图片大小不能超过 2MB!");
      }
      return isJPG && isLt2M;
    },
    // 点击添加的表单验证的方法
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          // alert("submit");
          //将图片给addForm
          this.$set(this.addForm, "pic", this.imageUrl);
          // 添加分类的异步请求
          addCateApi(this.addForm).then((result) => {
            // console.log(result);
            if (result.data.status == 200) {
              this.$router.push("/layout/category/list");
            } else {
              alert("添加失败");
            }
          });
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    // 级联菜单的方法
    handleChange(value) {
      console.log(value);
      //pid就是value这个数组的最后一项
      let pid = value[value.length - 1];
      // 把pid给addForm数据
      this.$set(this.addForm, "pid", pid);
    },
  },
  beforeCreate() {}, //生命周期 - 创建之前
  //生命周期 - 创建完成(可以访问当前this实例)
  created() {},
  beforeMount() {}, //生命周期 - 挂载之前
  //生命周期 - 挂载完成(可以访问DOM元素)
  mounted() {
    //获取到级联菜单的数据
    this.$store.dispatch("actChangeChooseCategoryDatas");
  },
  beforeUpdate() {}, //生命周期 - 更新之前
  updated() {}, //生命周期 - 更新之后
  beforeDestroy() {}, //生命周期 - 销毁之前
  destroyed() {}, //生命周期 - 销毁完成
  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
};
</script>
<style lang="scss" >
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 78px;
  height: 78px;
  line-height: 78px;
  text-align: center;
}
.avatar {
  width: 78px;
  height: 78px;
  display: block;
}
</style>

后台:

//添加分类的业务
let AddCategory=async (req,res)=>{
	let {title,is_show,pid,pic}=req.body;
	let create_time=moment().format("YYYY-MM-DD hh:mm:ss");
	
	// 在添加之前需要判断数据库中是否有该名
	let isHasCateNameSql=`select * from hg_category where title="${title}"`;
	let isResult=await request(isHasCateNameSql);
	if(isResult.length>0){
		res.json({
			status:1004,
			msg:"数据库已存在该类名"
		})
	}else{
		// insert into hg_category set title="鞋靴箱包",pid=0,is_show=1,create_time="2022-06-17 21:37:00"
		//添加的sql语句
		let sql=`insert into hg_category set title="${title}",pid=${pid},pic="${pic}",is_show=${is_show},create_time="${create_time}"`;
		let result=await request(sql);
		
		
		res.json({
			status:200,
			msg:"添加成功",
			data:result
		})
	}
}

分类列表的删除操作

删除分类的接口

// 删除分类的业务
let DelCategory=async (req,res)=>{
	let {id}=req.body;
	// 在删除之前需要判断数据库中是否有子分类
	let isHasChidrenSql=`select * from hg_category where pid=${id}`;
	let isResult=await request(isHasChidrenSql);
	console.log(isResult);
	if(isResult.length>0){
		res.json({
			status:1004,
			msg:"禁止删除,可能该分类存在子分类"
		})
	}else{
		//删除的sql语句
		let sql=`DELETE FROM hg_category WHERE id=${id}`;
		let result=await request(sql);
		
		
		res.json({
			status:200,
			msg:"删除成功",
			data:result
		})
	}
}

调用接口

看笔记和代码即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值