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;
}
}

最新文章

  1. 使用TortoiseGit对android studio工程进行代码版本控制
  2. 如何让用户只能访问特定的数据库(MSSQL)
  3. Telnet弱口令猜解【Python脚本】
  4. PHP面向对象07_PDO
  5. FFmpeg编译出错_img_convert 找不到
  6. 2016 Multi-University Training Contest 9
  7. SQL查询(一)
  8. 20145210 《Java程序设计》第十周学习总结
  9. DB2缓冲池、表空间
  10. 6月24日AppCan移动开发者大会礼品清单遭泄露
  11. mybatis知识总结
  12. NIO基础篇(一)
  13. django 利用pillow 进行简单的设置验证码(python)
  14. Spring Boot重定向的使用方法
  15. Python参数笔记
  16. 大数据架构工具hadoop
  17. Go 学习
  18. Java 使用 Jxl 实现 Excel 导入导出
  19. @property详解,@property修饰符以及各个修饰符区别(上)
  20. python-校验密码小练习

热门文章

  1. openfire开源IM服务器知识分享+社交app实战
  2. 十大经典排序之快速排序(C++实现)
  3. MMDetection中模型的Checkpoints下载
  4. APIView使用
  5. EurekaServer高可用搭建
  6. 2019之VLC3.071版本Ubuntu 18-win32-64为编译经验记录
  7. 2020/03/23--Diary
  8. CentOS7 使用Mariadb 安装 hive
  9. 4.javaweb-thymeleaf
  10. SSRF Server-Side Request Forgery(服务器端请求伪造)