ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【Vue项目 + 自写java后端】尚品汇(七)后台项目 ElementUI 表单验证 + 三级联动

2022-09-11 20:35:09  阅读:281  来源: 互联网

标签:insert Vue java 自写 into pid values result categoryName


ElementUI 表单验证

1 标准验证规则

Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。

      <el-form :rules="rules" :model="tmForm">
        <el-form-item prop="tmname" label="品牌名称" label-width="100px">
          <el-input autocomplete="off" v-model="tmForm.tmname" style="width: 400px"></el-input>
        </el-form-item>

        <el-form-item prop="logourl" label="品牌LOGO" label-width="100px">
          <el-upload
            class="upload-demo"
            action="/api/admin/product/fileUpload"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload">
            <img v-if="tmForm.logourl" :src="tmForm.logourl" class="avatar">
            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
            <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过10MB</div>
          </el-upload>

        </el-form-item>
      </el-form>

这里出现输入正确也一直有提示的情况,原因是因为el-form表单中的model表单绑定对象使用的是v-model而不是:model

v-model:表示value属性

:model:表示子组件有个prop叫model

      // 表单验证规则
      rules: {
        tmname: [
          {required: true, message: '请输入品牌名', trigger: 'blur'},
          {min: 3, max: 5, message: '长度在3到5个字符', trigger: 'blur'}
        ],
        logourl: [
          {required: true, message: '请上传品牌LoGo'}
        ]
      }
  • required:是否为必填项,true则会在form-item前出现红色*

  • message:验证失败时出现的提示信息

  • trigger: 验证的时机

    • blur:失去聚焦时验证

    • change:改动时验证

在函数回调中进行表单验证
    addOrUpdateTradeMark() {
      this.$refs.ruleForm.validate(async (valid) => {
        if (valid) {
          await this.$API.tradeMark.reqAddOrUpdateTradeMark(this.tmForm)
          this.$message({
            message: this.tmForm.id ? `品牌 ${this.tmForm.tmname} 修改成功` : `品牌 ${this.tmForm.tmname} 添加成功`,
            type: 'success'
          })
          this.hiddenDialogForm()
          await this.getPageList(this.page)
        } else {
          return false;
        }
      });
    }

注意async 和 await的位置,应该放在最近的箭头函数处

自定义验证规则

  data() {
    var checkTmname = (rule, value, callback) => {
      if(value.length >= 2 && value.length <= 5) {
        callback()
      } else {
        callback(new Error('品牌名称应在2-5位字符'))
      }
    }
    return {
      ...
      // 表单验证规则
      rules: {
        tmname: [
          {required: true, message: '请输入品牌名称', trigger: 'blur'},
          // {min: 2, max: 5, message: '长度在 2 到 5 个字符', trigger: 'blur'}
          {validator: checkTmname, trigger: 'blur'}
        ],
        logourl: [
          {required: true, message: '请上传品牌LOGO'}
        ]
      }
    }
  },

前端

1 静态组件

1.1 注册三级联动全局组件

/src/main.js

import CategorySelect from "@/components/CategorySelect";
Vue.component(CategorySelect.name, CategorySelect)

三级联动组件 /src/components/CategorySelect/index.vue

<template>
  <div>
    <el-form :inline="true" class="demo-form-inline">
      <el-form-item label="一级分类">
        <el-select  placeholder="请选择">
          <el-option label="区域一" value=""></el-option>
          <el-option label="区域二" value=""></el-option>
        </el-select>
      </el-form-item>

      <el-form-item label="二级分类">
        <el-select  placeholder="请选择">
          <el-option label="区域一" value=""></el-option>
          <el-option label="区域二" value=""></el-option>
        </el-select>
      </el-form-item>

      <el-form-item label="三级分类">
        <el-select  placeholder="请选择">
          <el-option label="区域一" value=""></el-option>
          <el-option label="区域二" value=""></el-option>
        </el-select>
      </el-form-item>

      <el-form-item>
        <el-button type="primary" @click="">查询</el-button>
      </el-form-item>
    </el-form>

  </div>
</template>

<script>
export default {
  name: "CategorySelect"
}
</script>

<style scoped>

</style>

在/src/views/product/attr中引入全局组件

<template>
  <div>
    <el-card style="margin-bottom: 20px"> <category-select/> </el-card>
    <el-card style="margin-top: 20px"> </el-card>
  </div>
</template>

<script>
export default {
  name: "index"
}
</script>

<style scoped>

</style>

2 编写请求接口

/src/api/product/attr.js

import request from "@/utils/request";

export const reqCategoryInfo = (id) => {
  return request({
    url: `/admin/product/attrInfoList/${id}`,
    method: 'get'
  })
}

CategorySelect组件加载完成时获取一级分类的属性信息

/src/components/CategorySelect/index.vue

  mounted() {
    this.getCategoryInfo()
  },
  methods: {
    async getCategoryInfo() {
      let result = await this.$API.attr.reqCategoryInfo(-1)
      if (result.code === 200) {
        this.list1 = result.data
      }
    },

-1代表没有父组件,即一级分类

使用el-select生成三级分类选项

    <el-form :inline="true" class="demo-form-inline" :model="categoryForm">
      <el-form-item label="一级分类">
      <el-select placeholder="请选择"
                 @change="list1Handle()"
                 v-model="categoryForm.category1Id">
        <el-option :label="c1.categoryName"
                   :value="c1.id"
                   v-for="(c1, index) in list1"
                   :key="c1.id"
        ></el-option>
      </el-select>
    </el-form-item>

      <el-form-item label="二级分类">
        <el-select placeholder="请选择"
                   @change="list2Handle()"
                   v-model="categoryForm.category2Id">
          <el-option :label="c2.categoryName"
                     :value="c2.id"
                     v-for="(c2, index) in list2"
                     :key="c2.id"
          ></el-option>
        </el-select>
      </el-form-item>

      <el-form-item label="三级分类">
        <el-select placeholder="请选择" v-model="categoryForm.category3Id">
          <el-option :label="list3 ? c3.categoryName : ''"
                     :value="c3.id"
                     v-for="(c3, index) in list3"
                     :key="c3.id"
          ></el-option>
        </el-select>
      </el-form-item>

      <el-form-item>
        <el-button type="primary" @click="">查询</el-button>
      </el-form-item>
    </el-form>

-model:表单双向绑定的数据对象

:model:双向绑定的数据对象的

@change: 选项发生改变时触发函数

:value='':该项会与上面:model的值进行双向绑定

:key:循环的区别值,不能够省略,否则会出现意想不到的错误,估计是ElementUI提供的组件内部使用了

绑定的函数:

<script>
export default {
  name: "CategorySelect",
  data() {
    return {
      list1: [],
      list2: [],
      list3: [],
      categoryForm: {
        category1Id: "",
        category2Id: "",
        category3Id: "",
      }
    }
  },
  mounted() {
    this.getCategoryInfo()
  },
  methods: {
    async getCategoryInfo() {
      let result = await this.$API.attr.reqCategoryInfo(-1)
      if (result.code === 200) {
        this.list1 = result.data
      }
    },
    async list1Handle() {
      this.categoryForm.category2Id = ''
      this.categoryForm.category3Id = ''
      const {category1Id} = this.categoryForm
      let result = await this.$API.attr.reqCategoryInfo(category1Id)
      if (result.code === 200) {
        this.list2 = result.data
      }
    },
    async list2Handle() {
      this.categoryForm.category3Id = ''
      const {category2Id} = this.categoryForm
      let result = await this.$API.attr.reqCategoryInfo(category2Id)
      if (result.code === 200) {
        this.list3 = result.data
      }
    }
  }
}
</script>

需要注意的一个点是在一级分类的value改变的时候应该将二三级分类的categoryform.categoryxid置空,否则会出现一个很严重的bug

比如二级分类选定电子书刊,三级分类选择一个电子书,如果这时候没有置空而将二级分类变为其他的选项的话,三级分类的label默认仍为电子书刊的电子书,这是由于二级分类双向绑定的对象的值是上一次残留的结果

后端

这部分后端相对来说简单一些,首先用xpath爬取了一点点数据,放入数据库后利用mybatis逆向工程生成entity、xml以及mapper接口。

insert into t_categoryName(pid, categoryName) values(-1, '图书、音像、电子书刊');
insert into t_categoryName(pid, categoryName) values(-1, '手机')
insert into t_categoryName(pid, categoryName) values(-1, '家用电器');
insert into t_categoryName(pid, categoryName) values(-1, '数码');
insert into t_categoryName(pid, categoryName) values(-1, '家居家装');
insert into t_categoryName(pid, categoryName) values(-1, '电脑办公');
insert into t_categoryName(pid, categoryName) values(-1, '厨具');
insert into t_categoryName(pid, categoryName) values(-1, '个护化妆');
insert into t_categoryName(pid, categoryName) values(-1, '服饰内衣');
insert into t_categoryName(pid, categoryName) values(-1, '钟表');
insert into t_categoryName(pid, categoryName) values(-1, '鞋靴');
insert into t_categoryName(pid, categoryName) values(-1, '母婴');
insert into t_categoryName(pid, categoryName) values(-1, '礼品箱包');
insert into t_categoryName(pid, categoryName) values(-1, '礼品箱包');
insert into t_categoryName(pid, categoryName) values(-1, '食品饮料、保健食品');
insert into t_categoryName(pid, categoryName) values(-1, '珠宝');
insert into t_categoryName(pid, categoryName) values(-1, '运动健康') 

insert into t_categoryName(pid, categoryName) values(1, '5');
insert into t_categoryName(pid, categoryName) values(1, '电子书刊');
insert into t_categoryName(pid, categoryName) values(1, '音像');
insert into t_categoryName(pid, categoryName) values(1, '英文原版');
insert into t_categoryName(pid, categoryName) values(1, '文艺');
insert into t_categoryName(pid, categoryName) values(1, '少儿');
insert into t_categoryName(pid, categoryName) values(1, '人文社科');
insert into t_categoryName(pid, categoryName) values(1, '经管励志');
insert into t_categoryName(pid, categoryName) values(1, '生活');
insert into t_categoryName(pid, categoryName) values(1, '科技');
insert into t_categoryName(pid, categoryName) values(1, '教育');
insert into t_categoryName(pid, categoryName) values(1, '港台图书');
insert into t_categoryName(pid, categoryName) values(1, '其他');


insert into t_categoryName(pid, categoryName) values(19, '电子书');
insert into t_categoryName(pid, categoryName) values(19, '网络原创')
insert into t_categoryName(pid, categoryName) values(19, '数字杂志');
insert into t_categoryName(pid, categoryName) values(19, '多媒体图书');
insert into t_categoryName(pid, categoryName) values(19, '小说');
insert into t_categoryName(pid, categoryName) values(19, '杂志');


insert into t_categoryName(pid, categoryName) values(20, '音乐');
insert into t_categoryName(pid, categoryName) values(20, '影视教育');
insert into t_categoryName(pid, categoryName) values(20, '音像');

记录逆向工程的一个坑点,如果数据库字段默认不使用下划线方式的话,转换成的实体类的字段全是小写的,而使用之后会将下划线变为驼峰。但是这个记得好像是能在配置文件设置的,懒得查了。。

如:category_name -> categoryName

CategoryHandler.java

@RequestMapping("/admin/product/attrInfoList")
@RestController
public class CategoryHandler {
    @Autowired
    CategoryService categoryService;

    @RequestMapping(value = "/{categoryId}", method = RequestMethod.GET)
    public ResultEntity<Object> getAttrInfoList(@PathVariable("categoryId") Integer pid) {
        List<Category> cateGoryList = categoryService.getCateGoryByPid(pid);

        return ResultEntity.successWithData(cateGoryList);
    }
}

CategoryServiceImpl.java

@Service
public class CategoryServiceImpl implements CategoryService {
    @Autowired
    private CategoryMapper categoryMapper;
    @Override
    public List<Category> getCateGoryByPid(int pid) {
        CategoryExample categoryExample = new CategoryExample();
        categoryExample.createCriteria().andPidEqualTo(pid);
        List<Category> categories = categoryMapper.selectByExample(categoryExample);

        return categories;
    }
}

标签:insert,Vue,java,自写,into,pid,values,result,categoryName
来源: https://www.cnblogs.com/tod4/p/16684746.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有