【问题标题】:VuetifyJS: Access v-form disabled state in child componentsVuetifyJS:访问子组件中的 v-form 禁用状态
【发布时间】:2023-01-20 17:53:46
【问题描述】:

Vuetify 组件 v-form 知道一个 disabled 属性,该属性向下发布到子 vuetify 组件,如 v-text-fieldv-input 等。当 v-formdisabled 属性设置为 true 时,所有子输入字段也(自动)被禁用。

但这仅适用于 Vuetify v-input-like 字段,但似乎确实如此不是为自己的组件工作。我希望能够“继承”disabled prop 在子组件中(做我自己的禁用用户界面)。

我不想传递反应性数据道具(在我的例子中是 formDisabled),因为这太乏味了:会有一大堆嵌套的组件 explicitely 需要我不想实现的反应性数据道具:显然它正在使用 Vuetify 自己的组件,但我怎样才能实现 自己也一样吗?

一个例子:

<template>
    <v-form :disabled="formDisabled">
        <!-- 
            works, even WITHOUT explicitely binding formDisabled: 
            textfield gets en-/disabled according to the form state: 
        -->
        <v-text-field />

        <!-- does NOT work: Withoud bind the formDisabled prop, 
             I cannot get the form's disabled state in my own component: -->
        <MyOwnComponent />
    </v-form>
    <v-btn @click="formDisabled = !formDisabled">Toggle</v-btn>
</template>

<script>
export default {
    data() {
        return {
            formDisabled: true
        };
    },
};
</script>

那么,如果不将 formDisabled 数据属性显式绑定到曾经拥有的表单子组件,我该如何找出表单的禁用状态?

【问题讨论】:

  • 看起来 Vuetify 组件有从 v-form 注入的值,所以你可以在你的组件中做同样的事情,我认为它是const {isDisabled} = inject('vuetify:form')。也许也可以从 composables/form.ts 导入注入函数:const {isDisabled} = useForm()。不确定这是否比设置道具更容易。
  • 感谢您的建议,不幸的是,'vuetify:form' 似乎不是上面提供的 var,因此它不被称为可注入属性。我想没有办法设置道具......
  • @AlexSchenkel 在每个子组件中传递道具(禁用状态)不是一个好主意。您可以使用vuex商店或pinia来实现这一点。

标签: javascript vue.js vuetify.js


【解决方案1】:

看看v-input,它是 Vuetify 输入的基础,您可以使用它来构建类似 Vuetify 的输入,这些输入可以像其他 Vuetify 组件一样解决禁用状态(以及所有其他验证)。

如果这对您不起作用,您可以像 Vuetify/v-input 所做的那样手动解决禁用状态,其中禁用状态通过注入从表单传播到输入。

验证 3,我可以像这样注入表单(使用组合 API):

const form = inject(Symbol.for("vuetify:form"))

或者像这样:

import {useForm} from 'vuetify/lib/composables/form'
const form = useForm()

这给了我这个接口的一个对象:

interface FormProvide {
  register: (item: {
    id: number | string
    validate: () => Promise<string[]>
    reset: () => void
    resetValidation: () => void
  }) => void
  unregister: (id: number | string) => void
  update: (id: number | string, isValid: boolean | null, errorMessages: string[]) => void
  items: Ref<FormField[]>
  isDisabled: ComputedRef<boolean>
  isReadonly: ComputedRef<boolean>
  isValidating: Ref<boolean>
  validateOn: Ref<FormProps['validateOn']>
}

然后在你的组件中(来自vuetify/lib/composables/validation):

  const isDisabled = computed(() => !!(props.disabled || form != null && form.isDisabled.value));

为 Vue 2 验证,整个表单对象作为“表单”提供,所以这应该可以工作(我没有 vue2 项目来测试它):

export default {
  inject: ['form'],
  created() {
    console.log(this.form)
  }
}

【讨论】:

    【解决方案2】:

    此问题陈述的一种解决方法是使用全局 mixin,它将应用于每个 Vue 实例,而不显式地作为每个子组件的 prop 传递。

    由于formDisabled 是每个孩子的只读属性,这是现场演示:

    注意:仅出于演示目的,我以纯 Vue 格式对其进行演示,但您可以根据 vuetify 组件对其进行修改并进行测试。

    // This is a global mixin, it is applied to every vue instance. 
    // Mixins must be instantiated *before* your call to new Vue(...)
    Vue.mixin({
      data: function() {
        return {
          get formDisabled() {
            return true;
          }
        }
      }
    })
    
    Vue.component('child', {
      template: '<input type="text" :disabled="formDisabled"/>'
    });
    
    new Vue({
      el: '#app'
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.3/vue.js"></script>
    <div id="app">
      <form :disabled="formDisabled">
        <child></child>
      </form>
    </div>

    【讨论】:

      猜你喜欢
      • 2020-05-20
      • 2019-12-07
      • 2018-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-08
      • 1970-01-01
      相关资源
      最近更新 更多