diff --git a/packages/devui-vue/devui/form/index.ts b/packages/devui-vue/devui/form/index.ts
index bdbb61bbf6e0ac8c1efc924b0cbf2356d5bf84fa..eaab6cdba3b8debf7846fb0f41b9bac11263e46b 100644
--- a/packages/devui-vue/devui/form/index.ts
+++ b/packages/devui-vue/devui/form/index.ts
@@ -4,6 +4,7 @@ import FormLabel from './src/form-label/form-label';
import FormItem from './src/form-item/form-item';
import FormControl from './src/form-control/form-control';
import FormOperation from './src/form-operation/form-operation';
+import CrossComponentValidateDemo from './src/cross-component-validate-demo/cross-component-validate-demo';
import dValidateRules from './src/directive/d-validate-rules';
Form.install = function(app: App) {
@@ -27,7 +28,11 @@ FormOperation.install = function(app: App) {
app.component(FormOperation.name, FormOperation)
}
-export { Form, FormLabel, FormItem, FormControl, FormOperation }
+CrossComponentValidateDemo.install = function(app: App) {
+ app.component(CrossComponentValidateDemo.name, CrossComponentValidateDemo)
+}
+
+export { Form, FormLabel, FormItem, FormControl, FormOperation, CrossComponentValidateDemo }
export default {
title: 'Form 表单',
@@ -39,5 +44,6 @@ export default {
app.use(FormItem as any);
app.use(FormControl as any);
app.use(FormOperation as any);
+ app.use(CrossComponentValidateDemo as any);
}
}
diff --git a/packages/devui-vue/devui/form/src/cross-component-validate-demo/cross-component-validate-demo.scss b/packages/devui-vue/devui/form/src/cross-component-validate-demo/cross-component-validate-demo.scss
new file mode 100644
index 0000000000000000000000000000000000000000..57aa9c1e402fca1d48b13ec8642e14f57ec6f281
--- /dev/null
+++ b/packages/devui-vue/devui/form/src/cross-component-validate-demo/cross-component-validate-demo.scss
@@ -0,0 +1,3 @@
+.devui-form-cross-component-validate-demo {
+
+}
diff --git a/packages/devui-vue/devui/form/src/cross-component-validate-demo/cross-component-validate-demo.tsx b/packages/devui-vue/devui/form/src/cross-component-validate-demo/cross-component-validate-demo.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..0aecb224bcf568bceb40170545201b3bbdfc61b4
--- /dev/null
+++ b/packages/devui-vue/devui/form/src/cross-component-validate-demo/cross-component-validate-demo.tsx
@@ -0,0 +1,42 @@
+import { defineComponent, ref, watch } from 'vue';
+import './cross-component-validate-demo.scss';
+
+export default defineComponent({
+ name: 'CrossComponentValidateDemo',
+ props: {
+ age: {
+ type: [Number, String],
+ default: 0
+ }
+ },
+ emits: ['ageChange'],
+ setup(props, ctx) {
+ const ageData = ref(props.age);
+
+ const customAsyncValidator = (rule, value) => {
+ return value >= 0 && value <= 200;
+ }
+
+ watch(() => props.age, (newVal) => {
+ ageData.value = newVal;
+ })
+
+ return () => {
+ return
+ {
+ ctx.emit('ageChange', val);
+ }} v-d-validate-rules={{
+ rules: {
+ asyncValidators: [
+ {message: '年龄范围必须在0~200之间', asyncValidator: customAsyncValidator}
+ ]
+ },
+ options: {
+ updateOn: 'input',
+ asyncDebounceTime: 500
+ }
+ }} />
+
+ }
+ }
+})
\ No newline at end of file
diff --git a/packages/devui-vue/devui/form/src/directive/d-validate-rules.ts b/packages/devui-vue/devui/form/src/directive/d-validate-rules.ts
index 87edc1a694b8d03a6e91540add0499e5a5ba0e4c..67388384b01ab1991a6bbf3afb8750b546d81c9b 100644
--- a/packages/devui-vue/devui/form/src/directive/d-validate-rules.ts
+++ b/packages/devui-vue/devui/form/src/directive/d-validate-rules.ts
@@ -246,7 +246,7 @@ function getRefName(binding: DirectiveBinding): string {
function getFormName(binding: DirectiveBinding): string {
const _refs = binding.instance.$refs;
const key = Object.keys(_refs)[0];
- return _refs[key]['name'];
+ return _refs[key] ? _refs[key]['name'] : '';
}
// 校验处理函数
@@ -277,10 +277,22 @@ function checkValidPopsition(positionStr: string): boolean {
return isValid
}
+// 获取FormControl标签上的uid
+function getDfcUID(el: HTMLElement) {
+ if(el.tagName === "BODY") return "";
+ if(el.dataset['uid']) return el.dataset['uid'];
+ let parent = el.parentElement;
+ if(parent.dataset['uid']?.startsWith('dfc-')) {
+ return parent.dataset['uid'];
+ } else {
+ return getDfcUID(parent.parentElement);
+ }
+}
+
export default {
mounted(el: HTMLElement, binding: DirectiveBinding, vnode: VNode): void {
const isFormTag = el.tagName === 'FORM';
- const dfcUID = el.parentNode.parentNode.parentElement.dataset.uid;
+ let dfcUID = getDfcUID(el);
const refName = getRefName(binding);
const hasOptions = isObject(binding.value) && hasKey(binding.value, 'options');
@@ -392,6 +404,9 @@ export default {
const validator = new AsyncValidator(descriptor);
const htmlEventValidateHandler = (e) => {
+ // 监听事件的回调函数中需重新获取dfcUID
+ // 当d-validate-rules指令用在跨组件验证时,因子组件先mounted,这时父组件还未mounted,拿不到父组件的data-uid,所以这里需重新获取dfcUID
+ dfcUID = getDfcUID(el);
const modelValue = e.target.value;
if(messageShowType === MessageShowTypeEnum.popover) {
EventBus.emit("showPopoverErrorMessage", {showPopover: false, message: "", uid: dfcUID} as ShowPopoverErrorMessageEventData);
diff --git a/packages/devui-vue/docs/components/form/index.md b/packages/devui-vue/docs/components/form/index.md
index 13591a26d1a139e9b576ffa33b406c67e53d8e10..7d7e823d61898074043f0e42687a9e5607c5ec8b 100644
--- a/packages/devui-vue/docs/components/form/index.md
+++ b/packages/devui-vue/docs/components/form/index.md
@@ -1502,28 +1502,33 @@ export default defineComponent({
### 跨组件验证
-> todo
+> done
+可以在子组件的数据录入类组件中使用`v-d-validate-rules`指令进行表单验证。
:::demo
```vue
-
+
- Name
+ Name
Age
-
-
+
+
+
+ 提交
+ 重置
+
@@ -1532,15 +1537,30 @@ import {defineComponent, reactive, ref} from 'vue';
export default defineComponent({
setup(props, ctx) {
- const dFormWithComponent = ref(null);
+ const dFormCrossComponentValidate = ref(null);
let formModel = reactive({
name: 'AlanLee',
- age: '24',
+ age: 24,
});
+ const resetForm = () => {
+ dFormCrossComponentValidate.value.resetFormFields();
+ }
+
+ const onSubmit = (e) => {
+ console.log('@submit', formModel);
+ }
+
+ const onAgeChange = val => {
+ formModel.age = val;
+ }
+
return {
- dFormWithComponent,
+ dFormCrossComponentValidate,
formModel,
+ resetForm,
+ onSubmit,
+ onAgeChange
}
}
})
@@ -1556,6 +1576,52 @@ export default defineComponent({
}
+
+
+
```
:::