gpt4 book ai didi

vue.js - Vue 3 从插槽访问子组件

转载 作者:行者123 更新时间:2023-12-05 04:57:28 25 4
gpt4 key购买 nike

我目前正在进行自定义验证,如果可能的话,我想访问子组件并调用其中的方法。

表单包装器

<template>
<form @submit.prevent="handleSubmit">
<slot></slot>
</form>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
setup(props, { slots }) {
const validate = (): boolean => {
if (slots.default) {
slots.default().forEach((vNode) => {
if (vNode.props && vNode.props.rules) {
if (vNode.component) {
vNode.component.emit('validate');
}
}
});
}

return false;
};

const handleSubmit = (ev: any): void => {
validate();
};

return {
handleSubmit,
};
},
});
</script>

当我调用 slot.default() 时,我得到了正确的子组件列表并且可以看到它们的属性。但是,vNode.component 始终为 null

我的代码基于这个 example但它适用于 vue 2。

如果有人能帮助我,那就太好了,或者这甚至有可能做到。

最佳答案

我找到了另一个解决方案,灵感来自 quasar 框架。

  1. 表单组件提供()绑定(bind)和解除绑定(bind)功能。
    bind() 将验证函数推送到数组并存储在 Form 组件中。
  2. Input 组件从父 Form 组件注入(inject)绑定(bind)和解除绑定(bind)功能。
    使用 self validate() 函数和 uid 运行 bind()
  3. 表单从提交按钮监听提交事件。
    遍历所有这些 validate() 数组,如果没有问题则 emit('submit')

表单组件

import {
defineComponent,
onBeforeUnmount,
onMounted,
reactive,
toRefs,
provide
} from "vue";
export default defineComponent({
name: "Form",
emits: ["submit"],
setup(props, { emit }) {
const state = reactive({
validateComponents: []
});
provide("form", {
bind,
unbind
});
onMounted(() => {
state.form.addEventListener("submit", onSubmit);
});
onBeforeUnmount(() => {
state.form.removeEventListener("submit", onSubmit);
});
function bind(component) {
state.validateComponents.push(component);
}
function unbind(uid) {
const index = state.validateComponents.findIndex(c => c.uid === uid);
if (index > -1) {
state.validateComponents.splice(index, 1);
}
}
function validate() {
let valid = true;
for (const component of state.validateComponents) {
const result = component.validate();
if (!result) {
valid = false;
}
}
return valid;
}
function onSubmit() {
const valid = validate();
if (valid) {
emit("submit");
}
}
}
});

输入组件

import { defineComponent } from "vue";
export default defineComponent({
name: "Input",
props: {
rules: {
default: () => [],
type: Array
},
modelValue: {
default: null,
type: String
}
}
setup(props) {
const form = inject("form");
const uid = getCurrentInstance().uid;
onMounted(() => {
form.bind({ validate, uid });
});
onBeforeUnmount(() => {
form.unbind(uid);
});
function validate() {
// validate logic here
let result = true;
props.rules.forEach(rule => {
const value = rule(props.modelValue);
if(!value) result = value;
})
return result;
}
}
});

用法

<template>
<form @submit="onSubmit">
<!-- rules function -->
<input :rules="[(v) => true]">
<button label="submit form" type="submit">
</form>
</template>

关于vue.js - Vue 3 从插槽访问子组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64407883/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com