Merge branch 'develop' of gitee.com:layui-vue/layui-vue into develop
This commit is contained in:
commit
f0cc890411
@ -4,37 +4,62 @@
|
|||||||
::: demo
|
::: demo
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<lay-form @submit="submit" :model="model">
|
<lay-form :model="model">
|
||||||
<lay-form-item label="账户">
|
<lay-form-item label="账户" prop="username">
|
||||||
<lay-input v-model="model.username"></lay-input>
|
<lay-input v-model="model.username"></lay-input>
|
||||||
</lay-form-item>
|
</lay-form-item>
|
||||||
<lay-form-item label="密码">
|
<lay-form-item label="密码" prop="password">
|
||||||
<lay-input v-model="model.password"></lay-input>
|
<lay-input v-model="model.password" type="password"></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="爱好" prop="hobby">
|
||||||
|
<lay-select v-model="model.hobby">
|
||||||
|
<lay-select-option value="1" label="学习"></lay-select-option>
|
||||||
|
<lay-select-option value="2" label="编码"></lay-select-option>
|
||||||
|
<lay-select-option value="3" label="运动"></lay-select-option>
|
||||||
|
</lay-select>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="特长" prop="specialty">
|
||||||
|
<lay-radio v-model="model.specialty" name="specialty" label="1">写作</lay-radio>
|
||||||
|
<lay-radio v-model="model.specialty" name="specialty" label="2">画画</lay-radio>
|
||||||
|
<lay-radio v-model="model.specialty" name="specialty" label="3">编码</lay-radio>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="描述" prop="desc">
|
||||||
|
<lay-textarea placeholder="请输入描述" v-model="model.desc"></lay-textarea>
|
||||||
</lay-form-item>
|
</lay-form-item>
|
||||||
<lay-form-item>
|
<lay-form-item>
|
||||||
<lay-button naive-type="submit">提交</lay-button>
|
<lay-button @click="submitClick">提交</lay-button>
|
||||||
</lay-form-item>
|
</lay-form-item>
|
||||||
</lay-form>
|
</lay-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue'
|
||||||
|
import {layer} from '@layui/layer-vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
|
|
||||||
const model = reactive({
|
const model = reactive({
|
||||||
username: "admin",
|
username: "admin",
|
||||||
password: "admin"
|
password: "123456",
|
||||||
|
specialty: "1"
|
||||||
})
|
})
|
||||||
|
|
||||||
const submit = function(val) {
|
const submitClick = function(){
|
||||||
alert(JSON.stringify(val))
|
layer.open({
|
||||||
}
|
type: 1,
|
||||||
|
title:"表单结果",
|
||||||
|
content: `<div style="padding: 10px">${JSON.stringify(model)}</div>`,
|
||||||
|
shade: false,
|
||||||
|
isHtmlFragment: true,
|
||||||
|
btn : [{ text: '确认', callback(index) { layer.close(index) }}],
|
||||||
|
area : '500px'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
model,
|
model,
|
||||||
submit
|
submitClick
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,38 +67,515 @@ export default {
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: title 表单事件
|
::: title 表单基本校验功能
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-form :model="validateModel" ref="layFormRef" required>
|
||||||
|
<lay-form-item label="账户" prop="username">
|
||||||
|
<lay-input v-model="validateModel.username"></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="密码" prop="password">
|
||||||
|
<lay-input v-model="validateModel.password" type="password">></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="爱好" prop="hobby">
|
||||||
|
<lay-select v-model="validateModel.hobby">
|
||||||
|
<lay-select-option value="1" label="学习"></lay-select-option>
|
||||||
|
<lay-select-option value="2" label="编码"></lay-select-option>
|
||||||
|
<lay-select-option value="3" label="运动"></lay-select-option>
|
||||||
|
</lay-select>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="特长" prop="specialty">
|
||||||
|
<lay-radio v-model="validateModel.specialty" name="specialty" label="1">写作</lay-radio>
|
||||||
|
<lay-radio v-model="validateModel.specialty" name="specialty" label="2">画画</lay-radio>
|
||||||
|
<lay-radio v-model="validateModel.specialty" name="specialty" label="3">编码</lay-radio>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="描述" prop="desc">
|
||||||
|
<lay-textarea placeholder="请输入描述" v-model="validateModel.desc"></lay-textarea>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item>
|
||||||
|
<lay-button @click="validate">提交</lay-button>
|
||||||
|
<lay-button @click="clearValidate">清除校验</lay-button>
|
||||||
|
<lay-button @click="reset">重置表单</lay-button>
|
||||||
|
</lay-form-item>
|
||||||
|
</lay-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref, reactive } from 'vue'
|
||||||
|
import {layer} from '@layui/layer-vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
|
||||||
|
const validateModel = reactive({
|
||||||
|
username: "",
|
||||||
|
password: "",
|
||||||
|
specialty: "1"
|
||||||
|
})
|
||||||
|
|
||||||
|
const layFormRef = ref(null);
|
||||||
|
// 校验
|
||||||
|
const validate = function() {
|
||||||
|
layFormRef.value.validate((isValidate, model, errors) => {
|
||||||
|
layer.open({
|
||||||
|
type: 1,
|
||||||
|
title:"表单提交结果",
|
||||||
|
content: `<div style="padding: 10px"><p>是否通过 : ${isValidate}</p> <p>表单数据 : ${JSON.stringify(model)} </p> <p>错误信息 : ${JSON.stringify(errors)}</p></div>`,
|
||||||
|
shade: false,
|
||||||
|
isHtmlFragment: true,
|
||||||
|
btn : [{ text: '确认', callback(index) { layer.close(index) }}],
|
||||||
|
area : '500px'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除校验
|
||||||
|
const clearValidate = function() {
|
||||||
|
layFormRef.value.clearValidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单
|
||||||
|
const reset = function() {
|
||||||
|
layFormRef.value.reset();
|
||||||
|
validateModel.specialty = "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
validateModel,
|
||||||
|
layFormRef,
|
||||||
|
validate,
|
||||||
|
clearValidate,
|
||||||
|
reset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: title 校验规则 - 通过表单配置
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-form :model="ruleDemo1" ref="layFormRef1" :rules="rules" required initValidate>
|
||||||
|
<lay-form-item label="邮箱" prop="email">
|
||||||
|
<lay-input v-model="ruleDemo1.email"></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="url路径" prop="url">
|
||||||
|
<lay-input v-model="ruleDemo1.url"></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="日期" prop="date">
|
||||||
|
<lay-input v-model="ruleDemo1.date"></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="用户名" prop="username">
|
||||||
|
<lay-input v-model="ruleDemo1.username"></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="年龄" prop="age">
|
||||||
|
<lay-input v-model="ruleDemo1.age"></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item>
|
||||||
|
<lay-button @click="validate1">提交</lay-button>
|
||||||
|
</lay-form-item>
|
||||||
|
</lay-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref, reactive } from 'vue'
|
||||||
|
import {layer} from '@layui/layer-vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
|
||||||
|
const ruleDemo1 = reactive({
|
||||||
|
email: "",
|
||||||
|
url: "",
|
||||||
|
date: "",
|
||||||
|
username: "",
|
||||||
|
age: null,
|
||||||
|
})
|
||||||
|
|
||||||
|
const rules = ref({
|
||||||
|
email : {
|
||||||
|
type : 'email'
|
||||||
|
},
|
||||||
|
url : {
|
||||||
|
type : 'url'
|
||||||
|
},
|
||||||
|
date : {
|
||||||
|
type : 'date'
|
||||||
|
},
|
||||||
|
username : {
|
||||||
|
type : 'string',
|
||||||
|
min : 8,
|
||||||
|
max : 16
|
||||||
|
},
|
||||||
|
age : {
|
||||||
|
validator(rule, value, callback, source, options){
|
||||||
|
if (value < 18) {
|
||||||
|
callback(new Error(`${rule.field}太过于年轻`));
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const layFormRef1 = ref(null);
|
||||||
|
// 校验
|
||||||
|
const validate1 = function() {
|
||||||
|
layFormRef1.value.validate((isValidate, model, errors) => {
|
||||||
|
layer.open({
|
||||||
|
type: 1,
|
||||||
|
title:"表单提交结果",
|
||||||
|
content: `<div style="padding: 10px"><p>是否通过 : ${isValidate}</p> <p>表单数据 : ${JSON.stringify(model)} </p> <p>错误信息 : ${JSON.stringify(errors)}</p></div>`,
|
||||||
|
shade: false,
|
||||||
|
isHtmlFragment: true,
|
||||||
|
btn : [{ text: '确认', callback(index) { layer.close(index) }}],
|
||||||
|
area : '500px'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
ruleDemo1,
|
||||||
|
layFormRef1,
|
||||||
|
validate1,
|
||||||
|
rules
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: title 校验规则 - 通过表单子项配置
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-form :model="ruleDemo2" ref="layFormRef2" required initValidate>
|
||||||
|
<lay-form-item label="邮箱" prop="email" :rules="{type : 'email'}">
|
||||||
|
<lay-input v-model="ruleDemo2.email"></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="url路径" prop="url" :rules="{type : 'url'}">
|
||||||
|
<lay-input v-model="ruleDemo2.url"></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="日期" prop="date" :rules="{type : 'date'}">
|
||||||
|
<lay-input v-model="ruleDemo2.date"></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="用户名" prop="username"
|
||||||
|
:rules="{
|
||||||
|
type : 'string',
|
||||||
|
min : 8,
|
||||||
|
max : 16
|
||||||
|
}">
|
||||||
|
<lay-input v-model="ruleDemo2.username"></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="年龄" prop="age" :rules="ageRules">
|
||||||
|
<lay-input v-model="ruleDemo2.age"></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="自定义提示" prop="myEmail"
|
||||||
|
:rules="{
|
||||||
|
type : 'email',
|
||||||
|
message : '必须为邮箱'
|
||||||
|
}">
|
||||||
|
<lay-input v-model="ruleDemo2.myEmail"></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item>
|
||||||
|
<lay-button @click="validate2">提交</lay-button>
|
||||||
|
</lay-form-item>
|
||||||
|
</lay-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref, reactive } from 'vue'
|
||||||
|
import {layer} from '@layui/layer-vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
|
||||||
|
const ruleDemo2 = reactive({
|
||||||
|
email: "",
|
||||||
|
url: "",
|
||||||
|
date: "",
|
||||||
|
username: "",
|
||||||
|
age: null,
|
||||||
|
myEmail: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
const ageRules = {
|
||||||
|
validator(rule, value, callback, source, options){
|
||||||
|
if (value < 18) {
|
||||||
|
callback(new Error(`${rule.field}太过于年轻`));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const layFormRef2 = ref(null);
|
||||||
|
// 校验
|
||||||
|
const validate2 = function() {
|
||||||
|
layFormRef2.value.validate((isValidate, model, errors) => {
|
||||||
|
layer.open({
|
||||||
|
type: 1,
|
||||||
|
title:"表单提交结果",
|
||||||
|
content: `<div style="padding: 10px"><p>是否通过 : ${isValidate}</p> <p>表单数据 : ${JSON.stringify(model)} </p> <p>错误信息 : ${JSON.stringify(errors)}</p></div>`,
|
||||||
|
shade: false,
|
||||||
|
isHtmlFragment: true,
|
||||||
|
btn : [{ text: '确认', callback(index) { layer.close(index) }}],
|
||||||
|
area : '500px'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
ruleDemo2,
|
||||||
|
layFormRef2,
|
||||||
|
validate2,
|
||||||
|
ageRules
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: title 原生submit方式校验 -- 校验通过将提交表单 -- 不推荐使用
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-form @submit="submit" :model="submitModel" requiredIcons="layui-icon-heart-fill" :use-CN="false" required>
|
||||||
|
<lay-form-item label="账户" prop="username">
|
||||||
|
<template #label>
|
||||||
|
<i class="layui-icon layui-icon-username"></i>
|
||||||
|
账户
|
||||||
|
</template>
|
||||||
|
<lay-input v-model="submitModel.username"></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item label="密码" prop="password">
|
||||||
|
<lay-input v-model="submitModel.password"></lay-input>
|
||||||
|
</lay-form-item>
|
||||||
|
<lay-form-item>
|
||||||
|
<lay-button native-type="submit">提交</lay-button>
|
||||||
|
</lay-form-item>
|
||||||
|
</lay-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref, reactive } from 'vue'
|
||||||
|
import {layer} from '@layui/layer-vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
|
||||||
|
const submitModel = reactive({
|
||||||
|
username: "",
|
||||||
|
password: ""
|
||||||
|
})
|
||||||
|
|
||||||
|
const submit = function(isValidate, model, errors) {
|
||||||
|
layer.open({
|
||||||
|
type: 1,
|
||||||
|
title:"表单提交结果",
|
||||||
|
content: `<div style="padding: 10px"><p>是否通过 : ${isValidate}</p> <p>表单数据 : ${JSON.stringify(model)} </p> <p>错误信息 : </br>${JSON.stringify(errors)}</p></div>`,
|
||||||
|
shade: false,
|
||||||
|
isHtmlFragment: true,
|
||||||
|
btn : [{ text: '确认', callback(index) { layer.close(index) }}],
|
||||||
|
area : '500px'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
submitModel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: title 表单(form)属性
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: table
|
::: table
|
||||||
|
|
||||||
| Name | Description | Accepted Values |
|
| 属性 | 描述 | 类型 | 可选值 | 默认值 |
|
||||||
| ----- | ----------- | --------------- |
|
| ------------- | -------------------------------------------------------------- | --------- | -------------- | ------- |
|
||||||
| model | 表单绑定值 | -- |
|
| model | 表单绑定值 | `object` | - | {} |
|
||||||
|
| required | 是否必填 | `boolean` | `true` `false` | `false` |
|
||||||
|
| rules | 表单校验规则; <br>可查看[async-validator](https://github.com/yiminghe/async-validator) | `object` | - | - |
|
||||||
|
| initValidate | 是否一开始就校验表单 | `boolean` | `true` `false` | `false` |
|
||||||
|
| useCN | 是否使用中文错误提示 | `boolean` | `true` `false` | `false` |
|
||||||
|
| requiredIcons | 必填前缀图标`class` | `string` | - | `*` |
|
||||||
|
| required-erroer-message | 必填错误提示信息 | `string` | - | `%s不能为空`|
|
||||||
|
| validate-message | 自定义校验错误提示信息; <br>由于内置了中文错误提示,可按需求增量增加<br>可参考 [layui-vue 内置中文错误提示](https://gitee.com/layui-vue/layui-vue/tree/master/src/module/formItem/cnValidateMessage.ts) | `string` | - | `%s不能为空`|
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: title 表单事件
|
::: title 表单(form)事件
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: table
|
::: table
|
||||||
|
|
||||||
| Name | Description | Accepted Values |
|
| 属性 | 描述 | 回调参数 |
|
||||||
| ------ | ----------- | --------------- |
|
| ------------- | ------------------------------- | -------------- |
|
||||||
| submit | 提交事件 | -- |
|
| submit | 提交事件`(不推荐使用)` | (`isValidate`, `model`, `errors`)<br><br> `isValidate`: (`boolean`)是否校验通过<br><br> `model`: (`object`)表单绑定的值<br><br> `errors`: (`Array`)校验结果的错误信息 |
|
||||||
|
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: title 表单项属性
|
::: title 表单(form)方法
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: table
|
::: table
|
||||||
|
|
||||||
| Name | Description | Accepted Values |
|
| 属性 | 描述 | 入参 |
|
||||||
| ----- | ----------- | --------------- |
|
| ------------- | -------------- | -------------- |
|
||||||
| label | 标题名称 | -- |
|
| validate | 表单校验; <br>如果没有`callback`回调,会返回`Promise`, <br> `Promise`参数为{`isValidate`, `model`, `errors`}<br> 参数具体描述请看上面表单`submit`提交事件 | (`fields` `[可选]`, `callback` `[可选]`)<br><br> `fields`: (`string` / `string[]` / `function`)<br>单独校验的字段,<br>该字段如果为`function`, <br>则认为`callback`入参,校验全部字段;<br><br> `callback`: (`function`)校验之后的回调,<br>回调参数为(`isValidate`, `model`, `errors`);<br>参数具体描述请看上面表单`submit`提交事件|
|
||||||
|
| clearValidate | 清除表单校验 | (`fields`[可选])<br><br> `fields`: (`string` / `string[]`)<br>需要进行清除校验的表单字段, 如果该字段为空则清除全部校验|
|
||||||
|
| reset | 重置表单所有值 | - |
|
||||||
|
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
::: title 表单项(form-item)属性
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: table
|
||||||
|
|
||||||
|
| 属性 | 描述 | 类型 | 可选值 | 默认值 |
|
||||||
|
| ------------- | -------------------------------------------------------------- | --------- | -------------- | ------- |
|
||||||
|
| prop | 在表单绑定值(`model`)中字段`key` | `string` | - | - |
|
||||||
|
| label | 子项前边描述值,**尽量填写**,中文校验错误需要用到 | `string` | - | - |
|
||||||
|
| required | 是否必填 | `boolean` | `true` `false` | `false` |
|
||||||
|
| rules | 表单校验规则; <br>可查看[async-validator](https://github.com/yiminghe/async-validator) | `object` | - | - |
|
||||||
|
| error-message | 表单校验失败固定提示语 | `string` |`block` `inline`| `block` |
|
||||||
|
| mode | 表单项显示的模式,`块元素` / `行元素` | `string` |`block` `inline`| `block` |
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: title 表单项(form-item)方法
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: table
|
||||||
|
|
||||||
|
| 属性 | 描述 | 入参 |
|
||||||
|
| ------------- | -------------- | -------------- |
|
||||||
|
| validate | 表单校验; | (`callback` `[可选]`)<br><br> `callback`: (`function`)校验之后的回调,<br>回调参数为(`errors`, `fields`);<br><br> `errors`: (`Array`)校验结果的错误信息;<br><br> `fields`: (`Array`)当前校验的字段信息|
|
||||||
|
| clearValidate | 清除表单校验 | - |
|
||||||
|
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: title 表单项(form-item)插槽
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: table
|
||||||
|
|
||||||
|
| 属性 | 描述 | 可使用参数 |
|
||||||
|
| ------------- | ---------------------------------------------------------------- | --------------------------------------- |
|
||||||
|
| - | 默认插槽 | 传递进来的`props`和表单绑定的值(`model`) |
|
||||||
|
| label | 子项前边描述插槽<br>如果使用此插槽,`props`**尽量**也传递`label`参数 | 传递进来的`props`和表单绑定的值(`model`) |
|
||||||
|
| required | 必填前缀插槽 | `*` / `表单props` 中的 `requiredIcons` |
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: title 关于 async-validator 的使用
|
||||||
|
:::
|
||||||
|
|
||||||
|
查看: https://github.com/yiminghe/async-validator
|
||||||
|
中文翻译: https://www.cnblogs.com/wozho/p/10955525.html
|
||||||
|
|
||||||
|
::: title async-validator 基本校验类型
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: table
|
||||||
|
| 属性 | 描述 | 使用方式 |
|
||||||
|
| -------------| ----------------- | ------------------- |
|
||||||
|
| number | 数字 | `{type : 'number'}` |
|
||||||
|
| boolean | 布尔类型 | `{type : 'boolean'}` |
|
||||||
|
| method | 方法 | `{type : 'method'}` |
|
||||||
|
| regexp | 正则表达式 | `{type : 'regexp'}` |
|
||||||
|
| integer | 整型数字 | `{type : 'integer'}` |
|
||||||
|
| float | 浮点小数 | `{type : 'float'}` |
|
||||||
|
| array | 数组 | `{type : 'array'}` |
|
||||||
|
| object | 对象 | `{type : 'object'}` |
|
||||||
|
| enum | 枚举 | `{type : 'enum'}` |
|
||||||
|
| date | 日期 | `{type : 'date'}` |
|
||||||
|
| url | url | `{type : 'url'}` |
|
||||||
|
| hex | 十六进制 | `{type : 'hex'}` |
|
||||||
|
| email | 邮箱 | `{type : 'email'}` |
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: title async-validator 中 validator参数使用
|
||||||
|
:::
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
validator: (rule, value) => value === 'root'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
::: title async-validator 中 asyncValidator参数使用
|
||||||
|
:::
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
asyncValidator: (rule, value) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (value < 18) {
|
||||||
|
reject('too young'); // reject with error message
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
::: title form 配置 async-validator 的使用
|
||||||
|
:::
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
key : rule // key为表单子项需要校验的对应key名称, rule为校验规则,格式为{}
|
||||||
|
}
|
||||||
|
// 例如 表单绑定值为 {email : 'xxx', username: 'xxxxx'}
|
||||||
|
// 需要校验邮箱,而邮箱输入框在表单绑定的值中key为email,
|
||||||
|
// 需要校验用户名长度为8到16之间,而用户名输入框在表单绑定的值中key为username,
|
||||||
|
{
|
||||||
|
email : {
|
||||||
|
type : 'email'
|
||||||
|
},
|
||||||
|
username : {
|
||||||
|
type : 'string',
|
||||||
|
min : 8,
|
||||||
|
max : 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
::: title form-item 配置 async-validator 的使用
|
||||||
|
:::
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// 例如 表单绑定值为 {email : 'xxx', phone: 'xxxxx'}
|
||||||
|
// 需要校验邮箱,而邮箱输入框在表单绑定的值中key为email
|
||||||
|
{
|
||||||
|
type : 'email'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
::: comment
|
::: comment
|
||||||
:::
|
:::
|
@ -38,6 +38,7 @@
|
|||||||
"@layui/hooks-vue": "^0.1.6",
|
"@layui/hooks-vue": "^0.1.6",
|
||||||
"@layui/icons-vue": "^1.0.1",
|
"@layui/icons-vue": "^1.0.1",
|
||||||
"@layui/layer-vue": "^1.2.0",
|
"@layui/layer-vue": "^1.2.0",
|
||||||
|
"async-validator": "^4.0.7",
|
||||||
"evtd": "^0.2.3",
|
"evtd": "^0.2.3",
|
||||||
"vue": "^3.2.26",
|
"vue": "^3.2.26",
|
||||||
"vue-router": "^4.0.12"
|
"vue-router": "^4.0.12"
|
||||||
|
@ -1,25 +1,140 @@
|
|||||||
<template>
|
<template>
|
||||||
<form class="layui-form" @submit="submit">
|
<form class="layui-form" :onsubmit="submit">
|
||||||
<slot />
|
<slot />
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="LayForm" lang="ts">
|
<script lang="ts">
|
||||||
|
export default{
|
||||||
|
name: 'LayForm'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { toRefs, provide,reactive, onMounted } from "vue"
|
||||||
|
import { Rule, ValidateError, ValidateMessages } from "async-validator"
|
||||||
|
import {layFormKey, LayFormItemContext, FormCallback, modelType} from "../type/form"
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
model?: object
|
model?: modelType
|
||||||
|
required?: boolean,
|
||||||
|
rules?: Rule,
|
||||||
|
initValidate?: boolean,
|
||||||
|
requiredIcons?: string,
|
||||||
|
requiredErrorMessage?: string,
|
||||||
|
validateMessage?: ValidateMessages,
|
||||||
|
useCN?: boolean
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
model: function(){
|
model: function(){
|
||||||
return {}
|
return {}
|
||||||
}
|
},
|
||||||
|
useCN : true,
|
||||||
|
requiredIcons : '',
|
||||||
|
initValidate : false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const formItems : LayFormItemContext[] = [];
|
||||||
|
const formItemMap : {[key:string]:LayFormItemContext} = {};
|
||||||
|
|
||||||
const emit = defineEmits(['submit'])
|
const emit = defineEmits(['submit'])
|
||||||
|
|
||||||
|
// 初始化表单就进行校验
|
||||||
|
onMounted(()=>{
|
||||||
|
props.initValidate && validate()?.catch(err => {});
|
||||||
|
})
|
||||||
|
|
||||||
|
// 原生提交表单事件
|
||||||
const submit = function () {
|
const submit = function () {
|
||||||
emit('submit',props.model)
|
let _isValidate = false;
|
||||||
|
validate((isValidate, model, errors) => {
|
||||||
|
_isValidate = isValidate as boolean;
|
||||||
|
emit('submit', isValidate, model, errors);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 如果表单失败则阻止提交表单,成功则进行提交表单
|
||||||
|
return _isValidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验表单数据
|
||||||
|
* @param fields 需要校验的表单字段(string|string[]); 该字段如果为function, 则默认为回调函数,校验全部字段;
|
||||||
|
* @param callback 校验表单之后的回调函数
|
||||||
|
**/
|
||||||
|
const validate = function(fields?: string|string[]|FormCallback|null, callback?: FormCallback | null){
|
||||||
|
// 根据参数识别需要校验的表单项
|
||||||
|
let validateItems : LayFormItemContext[] = formItems;
|
||||||
|
if (typeof fields === 'function') {
|
||||||
|
callback = fields;
|
||||||
|
} else if (typeof fields === 'string' || (Array.isArray(fields) && fields.length > 0)) {
|
||||||
|
validateItems = [];
|
||||||
|
const validateFields = !fields ? [] : ([] as string[]).concat(fields);
|
||||||
|
validateFields.forEach(field => formItemMap[field] && validateItems.push(formItemMap[field]));
|
||||||
|
}
|
||||||
|
// 通过调用每个子项进行校验
|
||||||
|
let errorsArrs: ValidateError[] = [];
|
||||||
|
validateItems.forEach(filed => {
|
||||||
|
filed.validate((errors, _fields)=>{
|
||||||
|
errorsArrs = errorsArrs.concat(errors as ValidateError[]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const isValidate = errorsArrs.length === 0;
|
||||||
|
// 有回调则进行回调
|
||||||
|
if (typeof callback === 'function') {
|
||||||
|
isValidate ? callback(true, props.model, null) : callback(false, props.model, errorsArrs);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 没有回调则创建一个Promise的链式调用
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const callbackParams = {
|
||||||
|
isValidate,
|
||||||
|
model : props.model,
|
||||||
|
errors: isValidate ? null : errorsArrs
|
||||||
|
};
|
||||||
|
callbackParams.isValidate ? resolve(callbackParams) : reject(callbackParams);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除校验
|
||||||
|
* @param fields 需要进行清除校验的表单字段(string|string[]); 该字段如果为null, 则默认为全部字段清除校验;
|
||||||
|
**/
|
||||||
|
const clearValidate = function(fields?: string | string[]){
|
||||||
|
const clearFields = !fields ? [] : ([] as string[]).concat(fields);
|
||||||
|
if (clearFields.length === 0) {
|
||||||
|
formItems.forEach(filed => filed.clearValidate());
|
||||||
|
} else {
|
||||||
|
clearFields.forEach(field => formItemMap[field] && formItemMap[field].clearValidate());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置表单所有值
|
||||||
|
**/
|
||||||
|
const reset = function(){
|
||||||
|
for (const key in props.model) {
|
||||||
|
props.model[key] = null;
|
||||||
|
}
|
||||||
|
// 重新校验
|
||||||
|
setTimeout(()=>validate()?.catch(err => {}), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加子项
|
||||||
|
const addField = function(item : LayFormItemContext) {
|
||||||
|
formItems.push(item);
|
||||||
|
formItemMap[item.prop as string] = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({validate, clearValidate, reset});
|
||||||
|
|
||||||
|
provide(layFormKey, reactive({
|
||||||
|
formItems,
|
||||||
|
addField,
|
||||||
|
clearValidate,
|
||||||
|
validate,
|
||||||
|
...toRefs(props)
|
||||||
|
}));
|
||||||
</script>
|
</script>
|
||||||
|
49
src/module/formItem/cnValidateMessage.ts
Normal file
49
src/module/formItem/cnValidateMessage.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import { ValidateMessages } from "async-validator";
|
||||||
|
// 中文翻译 --> 根据 async-validator 中 ValidateMessages 进行翻译
|
||||||
|
export default {
|
||||||
|
default: "%s验证失败",
|
||||||
|
required: "%s不能为空",
|
||||||
|
enum: "%s不在枚举%s里面",
|
||||||
|
whitespace: "%s不能为空",
|
||||||
|
date: {
|
||||||
|
format: "%s日期%s不是一个有效格式的日期%s",
|
||||||
|
parse: "%s无法解析为日期,%s是无效的",
|
||||||
|
invalid: "%s日期%s是无效的"
|
||||||
|
},
|
||||||
|
types: {
|
||||||
|
number: '%s不是一个有效的数字',
|
||||||
|
boolean: '%s不是一个有效的布尔类型',
|
||||||
|
method: '%s不是一个有效的方法',
|
||||||
|
regexp: '%s不是一个有效的正则表达式',
|
||||||
|
integer: '%s不是一个有效的整型数字',
|
||||||
|
float: '%s不是一个有效的浮点小数',
|
||||||
|
array: '%s不是一个有效的数组',
|
||||||
|
object: '%s不是一个有效的对象',
|
||||||
|
enum: '%s不是一个有效的枚举',
|
||||||
|
date: '%s不是一个有效的日期',
|
||||||
|
url: '%s不是一个有效的url',
|
||||||
|
hex: '%s不是一个有效的十六进制',
|
||||||
|
email: '%s不是一个有效的邮箱'
|
||||||
|
},
|
||||||
|
string: {
|
||||||
|
len: "%s必须是长度为%s个字符",
|
||||||
|
min: "%s最小长度为%s个字符",
|
||||||
|
max: "%s最长%s个字符",
|
||||||
|
range: "%s字符长度需要在%s和%s直接"
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
len: "%s长度必须为%s",
|
||||||
|
min: "%s必须小于%s",
|
||||||
|
max: "%s必须大于%s",
|
||||||
|
range: "%s需要在%s和%s之间"
|
||||||
|
},
|
||||||
|
array: {
|
||||||
|
len: "%s长度必须为%s",
|
||||||
|
min: "%s长度必须小于%s",
|
||||||
|
max: "%s长度必须大于%s",
|
||||||
|
range: "%s长度需要在%s和%s之间"
|
||||||
|
},
|
||||||
|
pattern: {
|
||||||
|
"mismatch": "%s值%s不能匹配%s"
|
||||||
|
}
|
||||||
|
} as ValidateMessages;
|
47
src/module/formItem/index.less
Normal file
47
src/module/formItem/index.less
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
@error_color : red;
|
||||||
|
|
||||||
|
.layui-required{
|
||||||
|
color: @error_color;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-form .layui-form-item{
|
||||||
|
.layui-input-block
|
||||||
|
,.layui-input-inline{
|
||||||
|
.layui-form-danger {
|
||||||
|
border-color: #ff5722 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-error-message {
|
||||||
|
color: @error_color;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1;
|
||||||
|
padding-top: 2px;
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-error-message-anim {
|
||||||
|
-ms-transform-origin: 0 0;
|
||||||
|
-webkit-transform-origin: 0 0;
|
||||||
|
transform-origin: 0 0;
|
||||||
|
-webkit-animation: layui-top-show-anim 0.3s ease 1;
|
||||||
|
animation: layui-top-show-anim 0.3s ease 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@keyframes layui-top-show-anim {
|
||||||
|
0% {
|
||||||
|
opacity: 0.3;
|
||||||
|
transform: rotateX(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: rotateX(0);
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +1,140 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item" ref="formItemRef">
|
||||||
<label class="layui-form-label">{{ label }}</label>
|
<label class="layui-form-label">
|
||||||
|
<span v-if="props.prop &&isRequired" :class="['layui-required', 'layui-icon'].concat(layForm.requiredIcons??'')">
|
||||||
|
<slot name="required" :props="{...props, model: layForm.model}">{{layForm.requiredIcons? '' : '*'}}</slot>
|
||||||
|
</span>
|
||||||
|
<slot name="label" :props="{...props, model: layForm.model}">
|
||||||
|
{{ label }}
|
||||||
|
</slot>
|
||||||
|
</label>
|
||||||
<div :class="[mode ? 'layui-input-' + mode : '']">
|
<div :class="[mode ? 'layui-input-' + mode : '']">
|
||||||
<slot />
|
<div ref="slotParent">
|
||||||
|
<slot :props="{...props, model: layForm.model}"/>
|
||||||
|
</div>
|
||||||
|
<span v-if="errorStatus" :class="['layui-error-message', {'layui-error-message-anim': errorStatus}]">{{errorMsg}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup name="LayFormItem" lang="ts">
|
<script setup name="LayFormItem" lang="ts">
|
||||||
import { defineProps, withDefaults } from 'vue'
|
import "./index.less";
|
||||||
|
import { defineProps, inject, withDefaults, ref, reactive, toRefs, onMounted, computed, watch} from 'vue'
|
||||||
|
import {layFormKey, LayFormContext, LayFormItemContext, FieldValidateError} from "../type/form"
|
||||||
|
import Schema, { Rule, RuleItem, Rules, ValidateCallback, ValidateError, ValidateMessages} from 'async-validator';
|
||||||
|
import cnValidateMessage from './cnValidateMessage';
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
|
prop?: string
|
||||||
mode?: string
|
mode?: string
|
||||||
label?: string
|
label?: string
|
||||||
|
errorMessage?: string
|
||||||
|
rules?: Rule
|
||||||
|
required?: boolean
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
mode: 'block'
|
mode: 'block'
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const layForm = inject(layFormKey, {} as LayFormContext)
|
||||||
|
const formItemRef = ref<HTMLDivElement>()
|
||||||
|
const slotParent = ref<HTMLDivElement>()
|
||||||
|
|
||||||
|
// 是否必填
|
||||||
|
const isRequired = computed(()=>{
|
||||||
|
return props.required || layForm.required;
|
||||||
|
})
|
||||||
|
|
||||||
|
// 拼接校验规则
|
||||||
|
const ruleItems = computed(()=>{
|
||||||
|
const prop = props.prop;
|
||||||
|
if (!prop) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
let rulesArrs : RuleItem[] = [];
|
||||||
|
if (isRequired.value) {
|
||||||
|
rulesArrs.push({required: true});
|
||||||
|
}
|
||||||
|
if (props.rules) {
|
||||||
|
rulesArrs = rulesArrs.concat((props.rules as RuleItem | RuleItem[]));
|
||||||
|
}
|
||||||
|
if (layForm.rules && layForm.rules[prop]) {
|
||||||
|
rulesArrs = rulesArrs.concat((layForm.rules[prop] as RuleItem | RuleItem[]));
|
||||||
|
}
|
||||||
|
return rulesArrs;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 值 计算 和 监听
|
||||||
|
const filedValue = computed(()=> props.prop ? layForm.model[props.prop] : undefined);
|
||||||
|
watch(()=>filedValue.value, (val)=> validate());
|
||||||
|
|
||||||
|
// 错误状态和信息
|
||||||
|
const errorStatus = ref(false);
|
||||||
|
const errorMsg = ref();
|
||||||
|
// 校验数据有效性
|
||||||
|
const validate = (callback ?: ValidateCallback)=> {
|
||||||
|
if (props.prop && (ruleItems.value as RuleItem[]).length > 0) {
|
||||||
|
// 校验规则
|
||||||
|
const descriptor : Rules = {};
|
||||||
|
descriptor[layForm.useCN? (props.label||props.prop ): props.prop] = ruleItems.value;
|
||||||
|
const validator = new Schema(descriptor);
|
||||||
|
|
||||||
|
let model : {[key : string]:any} = {};
|
||||||
|
let validateMessage = null;
|
||||||
|
// 使用中文错误提示
|
||||||
|
if (layForm.useCN) {
|
||||||
|
validateMessage = Object.assign({}, cnValidateMessage, layForm.validateMessage);
|
||||||
|
model[props.label||props.prop] = filedValue.value;
|
||||||
|
} else {
|
||||||
|
layForm.validateMessage && (validateMessage = layForm.validateMessage);
|
||||||
|
model[props.prop] = filedValue.value;
|
||||||
|
}
|
||||||
|
// 自定义校验消息
|
||||||
|
layForm.requiredErrorMessage && (validateMessage = Object.assign(validateMessage, {required : layForm.requiredErrorMessage}));
|
||||||
|
validateMessage && validator.messages(validateMessage);
|
||||||
|
|
||||||
|
// 开始校验
|
||||||
|
validator.validate(model, (errors, fields) => {
|
||||||
|
errorStatus.value = errors !== null && errors.length > 0;
|
||||||
|
const slotParentDiv = slotParent.value as HTMLDivElement;
|
||||||
|
if (errorStatus.value) {
|
||||||
|
const _errors = (errors as FieldValidateError[]);
|
||||||
|
// 如果是中文,将错误信息转换成FieldValidateError类型
|
||||||
|
layForm.useCN && _errors.forEach(error => {
|
||||||
|
error.label = props.label;
|
||||||
|
error.field = props.prop;
|
||||||
|
})
|
||||||
|
errorMsg.value = props.errorMessage??_errors[0].message;
|
||||||
|
slotParentDiv.childElementCount > 0 && slotParentDiv.firstElementChild?.classList.add('layui-form-danger');
|
||||||
|
callback && callback(_errors, fields);
|
||||||
|
} else {
|
||||||
|
clearValidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除校验
|
||||||
|
const clearValidate = ()=> {
|
||||||
|
errorStatus.value = false;
|
||||||
|
errorMsg.value = '';
|
||||||
|
const slotParentDiv = slotParent.value as HTMLDivElement;
|
||||||
|
slotParentDiv.childElementCount > 0 && slotParentDiv.firstElementChild?.classList.remove('layui-form-danger');
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({validate, clearValidate});
|
||||||
|
|
||||||
|
onMounted(()=>{
|
||||||
|
if (props.prop) {
|
||||||
|
layForm.addField(reactive({
|
||||||
|
...toRefs(props),
|
||||||
|
$el: formItemRef,
|
||||||
|
validate,
|
||||||
|
clearValidate
|
||||||
|
}) as LayFormItemContext);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -41,10 +41,10 @@ const props = defineProps<{
|
|||||||
const openState = ref(false)
|
const openState = ref(false)
|
||||||
|
|
||||||
const open = function () {
|
const open = function () {
|
||||||
openState.value = true
|
openState.value = !openState.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectItem = reactive({ label: '', value: props.modelValue })
|
const selectItem = reactive({ label: null, value: props.modelValue })
|
||||||
|
|
||||||
provide('selectItem', selectItem)
|
provide('selectItem', selectItem)
|
||||||
provide('openState', openState)
|
provide('openState', openState)
|
||||||
@ -56,4 +56,12 @@ watch(selectItem, function (item) {
|
|||||||
emit('change', item.value)
|
emit('change', item.value)
|
||||||
emit('update:modelValue', item.value)
|
emit('update:modelValue', item.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(()=>props.modelValue, function (value) {
|
||||||
|
if (!value) {
|
||||||
|
selectItem.label = null;
|
||||||
|
selectItem.value = '';
|
||||||
|
emit('update:modelValue', null);
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
37
src/module/type/form.ts
Normal file
37
src/module/type/form.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import type { ValidateCallback, ValidateError, ValidateMessages } from 'async-validator'
|
||||||
|
|
||||||
|
export const layFormKey = 'LayForm'
|
||||||
|
|
||||||
|
export interface LayFormContext {
|
||||||
|
model: modelType
|
||||||
|
required?: boolean
|
||||||
|
requiredErrorMessage?: string
|
||||||
|
validateMessage: ValidateMessages
|
||||||
|
rules?: Record<string, unknown>
|
||||||
|
useCN : boolean
|
||||||
|
requiredIcons?: string
|
||||||
|
addField: (field: LayFormItemContext) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LayFormItemContext {
|
||||||
|
prop?: string
|
||||||
|
$el: HTMLDivElement
|
||||||
|
required?: boolean
|
||||||
|
rules?: Record<string, unknown>
|
||||||
|
validate(callback?: ValidateCallback): void
|
||||||
|
clearValidate(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare type modelType = { [key: string]: any }
|
||||||
|
|
||||||
|
export declare interface FormCallback {
|
||||||
|
(
|
||||||
|
isValid?: boolean,
|
||||||
|
model?: modelType,
|
||||||
|
errors?: ValidateError[] | null
|
||||||
|
): void
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare interface FieldValidateError extends ValidateError {
|
||||||
|
label ?: string
|
||||||
|
}
|
@ -1,2 +1,3 @@
|
|||||||
export * from './public'
|
export * from './public'
|
||||||
export * from './select'
|
export * from './select'
|
||||||
|
export * from './form'
|
||||||
|
Loading…
Reference in New Issue
Block a user