(1)安装vue-cli,在cmd中输入npm install -g @vue/cli
(2)在项目的目标位置上打开cmd,输入vue create 项目名
(这里以app为例)
注: 不要选择 Linter / Formatter,格式报错会让你怀疑人生
(3)按照需求选择所需的配置,下载完成后进入vscode打开项目
(4)安装ElementUI,在vscode中新建终端(Ctrl+Shift+~)输入:npm i [email protected]
,下载element-ui
直接使用npm i element-ui -S
下载会获取到最新版本2.15.9,但是最新版本有时间选择器的报错问题,所以需要指定下载2.15.8版本(使用npm uninstall element-ui
卸载后再安装2.15.8版本)
注:
参数 -S 的全称为 --save,表示将下载好的element-ui中的名字以及版本号记录到pakages.json的“dependency”节点下,“dependency”节点中的包在开发阶段、上线阶段中都需要用到
参数 -D 的全称为 --save-dev 表示将下载好的包的名字以及版本号记录到pakages.json的“devDependencies”节点下,“devDependencies”节点的包只会在开发阶段中用到
更多参考npmjs.com官网
(5)引入ElementUI在main.js中完整引入Element-ui所有组件
(1)在components下新建一个ApplyHome.vue的文件作为登录的主页面。
(2)根据我们表单各项的需求到elementui官网找到类似的设计,以下面这个为例。
将前端代码复制到VScode的对应位置中
同理script中的代码也复制到对应位置中,同时在style下定义一下两个div在页面的位置,如下:
#ApplyHeader {
text-align: center;
}
#ApplyComponent {
margin-left: 26%;
margin-right: 30%;
}
Ctrl+Shift+~!,调出命令行输入 npm run serve
测试是否成功
姓名使用input标签、性别使用radio标签
<el-form-item label="申请人姓名" prop="name">
<el-input v-model="ruleForm.name">el-input>
el-form-item>
<el-form-item label="性别" prop="gender">
<el-radio-group v-model="ruleForm.gender">
<el-radio :label="1">男el-radio>
<el-radio :label="0">女el-radio>
el-radio-group>
el-form-item>
使用 elementui 中的 el-date-picker 标签,其中 picker-options="pickerOption"
表示约束该时间选择器的方法名为 pickerOption
<el-form-item label="出生日期" prop="birth">
<div>
<el-date-picker v-model="ruleForm.birth" type="date" placeholder="选择日期"
:picker-options="pickerOption">
el-date-picker>
div>
el-form-item>
对应data部分如下:
其中pickerOption方法 根据其参数 disabledDate 填写禁用时间的集合
效果如下
使用 elementui 中的 el-input 标签,其中电话要进行验证是否为真实的手机号、邮箱同理也要进行验证
<el-form-item label="电话" prop="tel">
<el-input v-model="ruleForm.tel">el-input>
el-form-item>
<el-form-item label="邮箱" prop="mail">
<el-input v-model="ruleForm.mail">el-input>
el-form-item>
验证部分写在rules中,validator : 方法名,其中的方法在上面声明即可。需要注意的是邮箱不是必填项,所以只有当填写邮箱但是格式不对的时候才进行报错。这里的正则表达式验证的写法不唯一,我也是参考的别人的写法。
【当if后面存在callback函数时,必须跟着else { callback() }
,否则会报错】具体参考该博主的文章 Vue中this.$refs[formName].validate((valid) =>{}不执行的错误
,解决办法参考自https://blog.csdn.net/hhb442/article/details/124074728
效果:
所在地这里我希望显示成级联的格式,选择某一省后能够级联显示后面的区。使用的省市数据来自ElementUI的element-china-area-data
包。具体方法参考自https://www.jianshu.com/p/f4b5e3d5c3cc
npm install element-china-area-data -S
2. 引入对应的数据,这里只使用到了省和市的级联 即 provinceAndCityDataPlus
import { provinceAndCityData, regionData, provinceAndCityDataPlus, regionDataPlus, CodeToText, TextToCode } from 'element-china-area-data'
<el-form-item label="所在地" prop="location">
<el-cascader size="large" :options="options" v-model="ruleForm.location" @change="handleChange"
placeholder="请选择所在区域">
el-cascader>
el-form-item>
在return中声明数据源的具体值为引用的数据别称
提示:这里绑定的数据事件 @change=“handleChange” 是为了查看获取到的省市具体值,对应的代码如下:
handleChange(value) {
console.log(value) // value值为区域码
// 用CodeToText转换成中文
console.log(CodeToText[value[0]])
console.log(CodeToText[value[1]])
},
使用 elementui 中的 el-date-picker 标签(与出生年月一样),要对其开始时间、结束时间进行限制。
前端代码如下:
<el-form-item label="期望试用时间" prop="trail">
<div class="block">
<el-date-picker v-model="ruleForm.Strail" type="month" clearable style="margin-right:3%"
placeholder="开始月份" value-format="yyyy-MM" :picker-options="pickerBegin">
el-date-picker>
<el-date-picker v-model="ruleForm.Etrail" type="month" clearable placeholder="结束月份"
value-format="yyyy-MM" :picker-options="pickerEnd">
el-date-picker>
div>
el-form-item>
参数type="month"
可以限制只显示到月份,参数 clearable
表示显示清除按钮,参数style="margin-right:3%"
表示距离右侧的距离为3%,参数value-format="yyyy-MM"
表示最终选择的时间格式为 年-月
,参数:picker-options="pickerBegin"
表示限制的方法为pickerBegin。具体可参考下图
要求:结束月份-起始月份<=3个月
具体规则:
若存在结束月份,开始月份的禁选范围为 (-∞, 结束月份-2个月) ∪ (结束月份, +∞) (算上结束月份,有效时间是三个月)
否则,开始月份的禁选范围为 (-∞,当前月份)
若存在开始月份,结束月份的禁选范围为 (-∞, 小于开始月份] ∪ (开始月份+2个月, +∞) (算上开始月份,有效时间是三个月)
在elementui中找到对应的效果及其代码:
在之前的表单提交位置进行添加,并修改为自己所要的样式
Ctrl+Shift+~调出终端,下载axios
npm install axios
在main.js中注册为全局变量
返回到刚才的提交界面,具体的请求url以及data部分先不要细究,这部分是和后端相关的,下篇文章进行详解
<template>
<div>
<div id="ApplyHeader">
<h1>试用申请表h1>
div>
<div id="ApplyComponent">
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="申请人姓名" prop="name">
<el-input v-model="ruleForm.name">el-input>
el-form-item>
<el-form-item label="性别" prop="gender">
<el-radio-group v-model="ruleForm.gender">
<el-radio :label="1">男el-radio>
<el-radio :label="0">女el-radio>
el-radio-group>
el-form-item>
<el-form-item label="出生日期" prop="birth">
<div>
<el-date-picker v-model="ruleForm.birth" type="date" placeholder="请选择出生年月"
:picker-options="pickerOption">
el-date-picker>
div>
el-form-item>
<el-form-item label="电话" prop="tel">
<el-input v-model="ruleForm.tel">el-input>
el-form-item>
<el-form-item label="邮箱" prop="mail">
<el-input v-model="ruleForm.mail">el-input>
el-form-item>
<el-form-item label="所在地" prop="location">
<el-cascader size="large" :options="options" v-model="ruleForm.location" @change="handleChange"
placeholder="请选择所在区域">
el-cascader>
el-form-item>
<el-form-item label="期望试用时间" prop="trail">
<div class="block">
<el-date-picker v-model="ruleForm.Strail" type="month" clearable style="margin-right:3%"
placeholder="开始月份" value-format="yyyy-MM" :picker-options="pickerBegin">
el-date-picker>
<el-date-picker v-model="ruleForm.Etrail" type="month" clearable placeholder="结束月份"
value-format="yyyy-MM" :picker-options="pickerEnd">
el-date-picker>
div>
el-form-item>
el-form>
div>
div>
template>
<script>
import { provinceAndCityData, regionData, provinceAndCityDataPlus, regionDataPlus, CodeToText, TextToCode } from 'element-china-area-data'
export default {
data() {
let dayList = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
if (new Date(Date.now()).getFullYear % 4 == 0) dayList[1] = 29;
let validTel = (rule, value, callback) => {//验证手机号
if (!value) callback(new Error('请输入手机号'));
else if (!/^1[3456789]\d{9}$/.test(value)) callback(new Error('请输入正确的手机号'));
else callback();
};
let validMail = (rule, value, callback) => {//验证邮箱
const regEmail = /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/;
if (value && !regEmail.test(value)) {
callback(new Error('请输入有效的邮箱'));
}
else callback();
};
return {
ruleForm: {
name: "",
gender: 1,
birth: "",
tel: "",
mail: "",
location: "",
Strail: "2022-08",
Etrail: "2022-10",
},
options: provinceAndCityDataPlus,
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
gender: [
{ required: true, message: '请选择性别', trigger: 'change' }
],
birth: [
{ required: true, message: '请选择出生年月', trigger: 'change' }
],
tel: [
{ required: true, validator: validTel, trigger: 'blur' }
],
mail: [
{ required: false, validator: validMail, trigger: 'blur' }
],
Strail: [
{ required: true, message: '请选择开始试用时间', trigger: 'blur' }
],
Etrail: [
{ required: true, message: '请选择结束试用时间', trigger: 'blur' }
]
},
pickerOption: {
disabledDate: (time) => {
let totalDay = 0;
for (let day of dayList) totalDay += day;
console.log(totalDay);
let hundred = totalDay * 100 * 24 * 60 * 60 * 1000;
return time.getTime() >= Date.now() || time.getTime() < Date.now() - hundred;
}
},
/* 失效的开始时间 */
pickerBegin: {
disabledDate: (time) => {
/* 若存在结束时间,失效时间为 大于结束时间 ∪ 小于结束月份-3个月 */
if (this.ruleForm.Etrail) {
let endDate = new Date(this.ruleForm.Etrail);
let endMonth = new Date(this.ruleForm.Etrail).getMonth();
let totalDay = dayList[endMonth - 1] + dayList[endMonth - 2];
let twoMonth = totalDay * 24 * 60 * 60 * 1000;
return time.getTime() >= endDate.getTime()
|| time.getTime() < endDate.getTime() - twoMonth;
} else {
/* 否则失效时间为 小于当前时间的月份 */
return time.getTime() <= Date.now();
}
}
},
/* 结束时间的失效范围 */
pickerEnd: {
disabledDate: (time) => {
/* 若存在开始时间,失效范围为 小于开始时间 ∪ 大于开始时间+2个月(算上本月,有效时间是三个月) */
if (this.ruleForm.Strail) {
let startDate = new Date(this.ruleForm.Strail);
let startMonth = startDate.getMonth();
let totalDay = dayList[startMonth - 1] + dayList[startMonth - 2];
let twoMonth = totalDay * 24 * 60 * 60 * 1000;
return time.getTime() < startDate.getTime()
|| time.getTime() > startDate.getTime() + twoMonth;
} else {
/* 否则失效时间为 小于当前时间的月份 */
return time.getTime() <= Date.now();
}
}
}
};
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
// messageBox弹窗提示提交成功
this.$alert('我们会尽快给您回复', '申请成功', {
confirmButtonText: '确定',
callback: action => {
this.$message({
type: 'success',
message: `action: ${action}`,
center: true,
});
}
});
// console.log(this.ruleForm.gender);
axios.post(
"/api/ApplyContainer/Add",
{
"name": this.ruleForm.name,
"gender": this.ruleForm.gender,
"birth": this.ruleForm.birth,
"tel": this.ruleForm.tel,
"mail": this.ruleForm.mail,
"location": CodeToText[this.ruleForm.location[0]] + '/' + CodeToText[this.ruleForm.location[1]],
"strail": this.ruleForm.Strail + '-01',
"etrail": this.ruleForm.Strail + '-01'
});
console.log('submit');
} else {
console.log('error submit!!');
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
handleChange(value) {
console.log(value) // value值为区域码
// 用CodeToText转换成中文
console.log(CodeToText[value[0]])
console.log(CodeToText[value[1]])
},
}
}
script>
<style>
#ApplyHeader {
text-align: center;
}
#ApplyComponent {
margin-left: 26%;
margin-right: 30%;
}
#submitBar {
margin-top: 5%;
text-align: center;
}
style>