vue、elementUI 的弹窗表单最佳实践
弹窗表单基于 vue + element-ui 的弹窗表单最佳实践数据回显数据回显主要分为两种情况,一种是通过在弹窗组件里面去调用详情接口回显数据,一种是从父组件中传值回显。调用接口获取详情回显数据—在组件调用的地方给一个判断,避免在父组件初始化时就调用弹窗里的详情接口。props 父组件向子组件传值<!-- 父组件调用 dialogTest 组件 --><dialog-test
·
弹窗表单
基于 vue + element-ui 的弹窗表单最佳实践
数据回显
数据回显主要分为两种情况,一种是通过在弹窗组件里面去调用详情接口回显数据,一种是从父组件中传值回显。
- 调用接口获取详情回显数据—在组件调用的地方给一个判断,避免在父组件初始化时就调用弹窗里的详情接口。
- props 父组件向子组件传值
<!-- 父组件调用 dialogTest 组件 -->
<dialog-test
v-if="dialogStatus"
:dialog-status="dialogStatus"
:dialog-title="dialogTitle"
:handle-type="handleType"
@close-dialog="dialogStatus=false">
</dialog-test>
- 用 ref 从父组件操作子组件方法
- 注:通过ref 传值,由于传的值是在方法里拿到的,而不是在子组件初始化时拿到的数据,所以在用 resetFields 重置表单时,通过ref传过来的值会被重置清空调
<!-- 父组件 -->
<dialog-test
ref="dialog"
v-if="dialogStatus"
:dialog-status="dialogStatus"
:dialog-title="dialogTitle"
:handle-type="handleType"
@close-dialog="dialogStatus=false">
</dialog-test>
<script>
export default {
data() {},
methods: {
edit(row) {
this.dialogStatus = true
this.dialogTitle = '修改'
this.handleType = 'edit'
// ref 和 v-if 渲染问题,用this.$nextTick来进行判断当前是否数据和dom已经加载完成了,加载完成了,再执行打开弹窗操作
this.$nextTick(() => {
// 子组价直接在 open() 方法里获取 row里的数据
this.$refs.dialog.open(row)
})
}
}
}
</script>
<!-- 子组件 -->
<script>
export default {
data() {
return {
form: {
…
}
}
},
methods: {
open(row) {
Object.keys(this.form).forEach(key => {
this.form[key] = row[key]
})
}
}
}
</script>
表单重置
- resetFields:对该表单项进行重置,将其值重置为初始值并移除校验结果
- 注意点: resetFields 只能重置用prop绑定的字段,没有prop绑定的字段需要手动重置
<script>
export default {
methods: {
reset() {
this.$refs.form.resetFields()
// resetFields 只能重置绑定有 prop 的字段,未被绑定的需手动重置
this.form.start = ''
this.form.end = ''
},
}
}
</script>
表单校验
实现表单校验的主要属性:
属性 | 类型 | 备注 |
---|---|---|
ref | - | 给元素或子组件注册引用信息,引用信息将会注册在父组件的 $refs 对象上 |
rules | Object | 表单检验规则 |
model | Object | 表单数据对象 |
prop | String | 表单域model字段,在使用 validate、resetFields 方法的情况下,该属性必填 |
表单方法:
方法名 | 说明 | 参数 |
---|---|---|
validate | 对整个表单进行校验的方法,参数为一个回调函数。该回调函数会在校验结束后被调用,并传入两个参数:是否校验成功和未通过校验的字段。若不传入回调函数,则会返回一个 promise | Function(callback: Function(boolean, object)) |
validateField | 对部分表单字段进行校验的方法 | Function(props: array |
resetFields | 对整个表单进行重置,将所有字段值重置为初始值并移除校验结果 | – |
clearValidate | 移除表单项的校验结果。传入待移除的表单项的 prop 属性或者 prop 组成的数组,如不传则移除整个表单的校验结果 | Function(props: array |
表单校验:
<el-form :model="form" ref="formRef" :rules="rules" label-width="100px" size="small">
<el-form-item label="活动名称" prop="name">
<el-input class="dialog-input" v-model="form.name" :maxlength="55" placeholder="请输入活动名称"></el-input>
</el-form-item>
</el-form>
<el-button type="primary" size="small" @click="submit">确 定</el-button>
<script>
export default {
data() {
let nameCheck = (rule, value, callback) => {
const reg = /^[a-z]+([-]?[a-z0-9])*$/
if(!value) {
callback(new Error('活动名称不能为空'))
} else if(!reg.test(value)) {
callback(new Error('只能包含小写字母、数字及分隔符('-'),且必须以小写字母开头,数字或小写字母结尾'))
} else {
callback()
}
}
return {
form: {
name: ''
},
rules: [
name: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
{ validator: nameCheck, trigger: 'blur' }
]
]
}
},
methods: {
submit() {
this.$refs.formRef.validate((valid) => {
if(valid) {
// 校验通过,执行提交操作
// dosomething……
}
})
}
}
}
</script>
在表单校验过程中,可能存在一个文本标签对应着多个填选框,以以下两种场景为例:
- 针对每一个输入框做校验提示(各输入框的错误提示显示在相应输入框的下方)
<el-form :model="form" ref="formRef" :rules="rules" label-width="100px" size="small">
<el-form-item label="环境变量" required>
<el-row>
<el-col :span="8">
<el-form-item prop="envName">
<el-input class="dialog-input" v-model="form.envName" :maxlength="50"></el-input>
</el-form-item>
</el-col>
<el-col :span="1">
<span> = </span>
</el-col>
<el-col :span="8">
<el-form-item prop="envNum">
<el-input class="dialog-input" v-model="form.envNum" :maxlength="50"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form-item>
</el-form>
<script>
export default {
data() {
return {
form: {
envName: '',
envNum: ''
},
rules: {
envName: [
{ required: true, message: '请输入变量名', trigger: 'blur' }
],
envNum: [
{ required: true, message: '请输入变量值', trigger: 'blur' }
]
}
}
}
}
</script>
- 用一个 prop 对多个输入框做校验(多个输入框的校验提示显示在同一个位置)
<el-form :model="form" ref="formRef" :rules="rules" label-width="100px" size="small">
<!-- 两个或多个输入框用一个提示 -->
<el-form-item label="阈值范围" prop="ratio">
<el-input class="ratio-input" v-model="form.start" :maxlength="2"></el-input>
<span> - </span>
<el-input class="ratio-input" v-model="form.end" :maxlength="2"></el-input>
</el-form-item>
</el-form>
<script>
export default {
data() {
let ratioCheck =(rule, val, callback) => {
// 给 ratio 一个初始值,才能跳到该方法里对 start end 输入框的值做校验
if(!this.form.start && !this.form.end) {
callback(new Error('请输入阈值范围'))
} else if(this.form.start && !this.form.end) {
callback(new Error('请输入最大值'))
} else if(!this.form.start && this.form.end) {
callback(new Error('请输入最小值'))
} else {
callback()
}
}
return {
form: {
ratio: '121',
satrt: '',
end: ''
},
rules: {
ratio: [
{ required: true, message: '请输入阈值范围', trigger: 'blur' },
{ validator: ratioCheck, trigger: 'blur' }
],
}
}
}
}
<script>
防重复点击
- 给定一个变量,每次点击过后给按钮loading置为true,等所有的操作结束后再将按钮 loading状态置为 false。
<el-button type="primary" size="small" @click="submit" :loading="btnLoading">确 定</el-button>
<script>
export default {
data() {
return {
btnLoading: false
}
},
methods: {
submit() {
this.btnLoading = true
setTimeout(() => {
this.btnLoading = false
this.cancel()
},1000)
}
}
}
</script>
更多推荐
已为社区贡献1条内容
所有评论(0)