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

【Vue项目 + 自写java后端】尚品汇(七)后台项目 ElementUI 表单验证 + 三级联动的更多相关文章

  1. vue大型电商项目尚品汇(后台篇)day01

    开始我们后台篇的内容,前面处理了一些事情,去学校完成授位仪式,由校长授位合影,青春不留遗憾,然后还换了一个电脑,征战了四年的神船终于退役了,各种各样的小毛病是真的烦人. 现在正式开始后台篇的内容,做了 ...

  2. vue大型电商项目尚品汇(后台篇)day02

    这几天更新有点小慢,逐渐开始回归状态了.尽快把这个后台做完,要开始vue3了 3.添加修改品牌 用到组件 Dialog 对话框,其中visible.sync这个配置是修改他的显示隐藏的,label-w ...

  3. vue大型电商项目尚品汇(后台篇)day03

    今天把平台属性的管理基本完成了,后台管理做到现在基本也开始熟悉,确实就是对ElementUI的一个熟练程度. 一.平台属性管理 1.动态展示数据 先把接口弄好,应该在第三级标题选择后进行发请求 静态页 ...

  4. vue大型电商项目尚品汇(后台篇)day05

    今天继续是对后台管理部分的一个操作,但是快要结束了,今天结束,明天会进入一个从Vue以来,另外一个名声显著的东西了,一只耳闻从未见识,而且十分的炫酷 他就是------数据可视化Echarts,迫不及 ...

  5. vue大型电商项目尚品汇(后台篇)day04

    昨天太晚就没来得及更新,今天是spu管理界面,这个界面一共有三个界面需要切换,完成了两个界面,而且今天的难度在于最后两个章节,富有一定的逻辑性,当然中间也有很多需要注意的,比如ElementUI的照片 ...

  6. vue大型电商项目尚品汇(后台终结篇)day06 重磅!!!

    自此整个项目前后台,全部搭建完毕. 今天是最后一天,内容很多,而且也比较常用,一个图标类数据可视化,一个后台的权限管理,都是很经典的类型. 一.数据可视化 1.简介 专门的一门学科,有专门研究这个的岗 ...

  7. vue大型电商项目尚品汇(前台篇)day05

    紧急更新第二弹,然后就剩下最后一弹,也就是整个前台的项目 一.购物车 1.加入购物车(新知识点) 加入到购物车是需要接口操作的,因为我们需要将用户的加入到购物车的保存到服务器数据库,你的账号后面才会在 ...

  8. vue大型电商项目尚品汇(前台篇)day05终结篇

    前台部分到此结束,一路走来还挺怀念,今天主要是对整个项目的完成做一个最后的收尾工作,对于功能上的需求没有什么了,主要就是项目上线的一些注意事项. 一.个人中心二级路由 当我们点击查看订单应该跳转到个人 ...

  9. Vue项目之实现登录功能的表单验证!

    Vue项目之实现登录功能的表单验证! 步骤: 配置 Form表单验证; 1.必须给el-from组件绑定model 为表单数据对象 2 给需要验证的表单项 el-form-item 绑定 prop 属 ...

  10. 写一个简单易用可扩展vue表单验证插件(vue-validate-easy)

    写一个vue表单验证插件(vue-validate-easy) 需求 目标:简单易用可扩展 如何简单 开发者要做的 写了一个表单,指定一个name,指定其验证规则. 调用提交表单方法,可以获取验证成功 ...

随机推荐

  1. linux 文件系统和包管理工具rpm,yum

    文件系统 1.什么是文件系统? 文件系统是一种存储和组织计算机中数据文件的机制或方法,他使得对计算机内的数据的存储.访问和查找变得更容易,简单. 文件系统落到计算机里其实就是一个应用软件 ext2 e ...

  2. 关于 'vue-cli-service' 不是内部或外部命令,也不是可运行的程序 或批处理文件 的处理

    关于 npm run serve 之后 'vue-cli-service' 不是内部或外部命令,也不是可运行的程序 或批处理文件 一.安装node.js 去官网安装Node.js(地址:https:/ ...

  3. LoadRunner性能测试-app压力测试

    步骤分为三步: 一,录制脚本 录制脚本原理:启动LR代理服务器监听设置好的端口号是否有请求发送给服务器,有请求时,代理服务器接收请求,并转发给对应的系统服务器,LR从而获取到请求的信息与数据,生成脚本 ...

  4. 二、Basic HTML5 知识整理

    一.需要记下的html5知识 1.html5网页文本框架 <!DOCTYPE html> <html> <head></head> <body&g ...

  5. 微信小程序 图片预览 wx.previewImage

    官网地址: go官网 效果展示: list: [ 'http://img5.imgtn.bdimg.com/it/u=3300305952,1328708913&fm=26&gp=0. ...

  6. weblogic session timed out

    How to Configure Session Timeout in Weblogic Server (WLS) ?

  7. linux 安装 jupyter notebook

    虚拟机使用的是ubuntu系统 直接遇见一个问题 E: 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) E: 无法锁定管理目录(/var/lib/dpkg/ ...

  8. lc.977 有序数组的平方

    题目描述 给你一个按非递减顺序排序的整数数组nums,返回每个数字的平方组成的新数组,要求也按非递减顺序 排序. 输入:nums = [-4,-1,0,3,10] 输出:[0,1,9,16,100] ...

  9. C知识点

    1.变量在内存中所占存储空间的首地址,称为该变量的地址:而变量在存储空间中存放的数据,即变量的值. C语言中,指针就是变量的地址.一个变量的值是另一个变量的地址,且变量类型相同,则称该变量为指针变量. ...

  10. python之tk学习,闲鱼搜索-小记

    (如想转载,请联系博主或贴上本博地址) 编程,逻辑,总是让人如痴如醉. 下面进入正题. 火热的天气配上火热的python,python的入门友好性让门外汉们都看到了希望.当然自己写的程序如果没有GUI ...