【问题标题】:Vue props that aren't explicitly declared未显式声明的 Vue 道具
【发布时间】:2017-07-23 17:06:03
【问题描述】:

我正在尝试类似于redux-form 但在 Vue 和 Vuex 中。基本上它应该使表单的处理更加精简,并减少你编写的样板代码。

我遇到的问题是当我尝试将道具从 HOC 动态传递给组件时。我不太确定该怎么做。在 React 中,您只需执行以下操作:

<VfField unknownPropA="abc" unknownPropB="123" name="test" />

在 VfField.js 中:

export default ({name, ...props}) => <div name={name}><InputComponent {...props} /></div>

这将导致props 成为包含unknownPropAunknownPropB 的对象。

但在 Vue 中,我有一些看起来像这样的代码:

<vf-form @submit="submit" @validate="validate">
  <vf-field type="text" name="username" unknownPropA="abc"></vf-field>
  <vf-field type="password" name="password" unknownPropB="123"></vf-field>
  <button type="submit">Submit</button>
</vf-form>

那么vf-field 怎样才能访问这些“未知”的道具并将它们传递给它们的子组件呢? $vm.$props 只产生了我明确声明的道具,但完全忽略了另一个(unknownPropAunknownPropB)。我正在寻找“动态”传递道具的能力,因为它在许多情况下都非常有用。

注意:

到目前为止,我认为 Vue 非常适合简单的事情,而且启动和运行某些东西比在 React 中要快得多。但是,到目前为止,一旦某些东西“与众不同”,我发现 React 更有帮助。当然,这可能是由于我对 Vue 缺乏了解。

【问题讨论】:

  • 我不认为有一个标准的方法来获取未声明的属性,你可以编写自己的方法来解析 this.$el.attributes 作为一个 mixin,但我的另一个想法是 @Saurabh 在他的答案,它更安全,更好。
  • 模板中的 props 应该写成 kebab-case 风格 unknow-prop-b 并在你的组件中注册为 props: ['unknownPropB'] 接受它们
  • 老实说,我认为说它更好与否是一个品味问题。对我来说,将其编写为第三方库,我认为我的用户最好能够直接在 vf 字段上指定他们的道具,而不是通过“哑”道具指定它们。传递属性对我不起作用,因为用户需要能够传递的不仅仅是字符串。
  • 对不起,但我没有得到这个“传递属性对我不起作用,因为用户需要能够传递的不仅仅是字符串” - 您可以通过道具传递任何类型的数据。
  • 是的,只是JSON.parse

标签: javascript frontend vuejs2 vue.js


【解决方案1】:

这很棘手,当然本机不支持,但是您可以使用 this.$vnode.elm.attributesvnode 获取传递的属性,然后遍历它们并将它们添加到 props 对象(确实需要预先声明)。因为您将自己处理此问题,所以我会将其放在 mixin 中以便可以重复使用,但您可以这样做:

  methods: {
    getProps() {
      let props = this.$vnode.elm.attributes;
      Object.keys(props).forEach(key => {
        this.$set(this.props, props[key].name, props[key].nodeValue)
      });
    }
  },
  data(){
    return{
      props: {}
    }
  }

这样你就可以传递未知的道具,就好像你在你的组件中声明了它们一样。

我制作了一个 JSFiddle 来向您展示该过程:https://jsfiddle.net/2c23Lb5t/

以下是使用mixin 执行此操作的方法:https://jsfiddle.net/fej7wu5f/

【讨论】:

    【解决方案2】:

    您可以使用$attrs 获取任何未被识别为道具的内容:documentation。请注意,相反的情况也存在:您可以使用$props 获取所有道具。

    【讨论】:

      【解决方案3】:

      相反,您可以将对象作为道具传递给孩子,它可以具有您想要的所有属性。

      可能是这样的:

      <VfField :unknownPropObj=yourObj name="test" />
      

      yourObj 可以是:{"A": "abc", "B": "123"}

      因此您只能在子项中定义 prop: unknownPropObj,并访问它的所有属性

      【讨论】:

      • 是的,但我想避免这种情况。通过例如感觉更自然字段本身的“标签”属性,如下所示: 而不是像 。第一个示例既更容易编码(更少的代码),也更容易通过查看 vf 字段来查看实际传递的内容。
      • @OscarLinde 好吧,您说第一个似乎更好,但不幸的是我在 vue 文档中没有看到任何此类支持,因为我认为需要声明它们以使其具有反应性。跨度>
      • 确实 :( 我试图查看文档以及源代码,但找不到任何方法。如果将我的道具传递给另一个道具是我必须做的唯一方法那样的话,但我很不情愿。API 为王,我相信这是一个值得考虑的功能,如果我们是对的,因为它不存在。
      【解决方案4】:

      您可以通过 v-bind="$attrs"

      实现此目的
      <VfField v-bind="$attrs" name="test" />
      

      如果您想手动决定哪个元素将接收属性(默认情况下根元素继承它们),您可以将选项 inheritAttrs: false 传递给子组件。

      <script>
        export default {
          inheritAttrs: false,
        };
      </script>
      

      参考:https://vuejs.org/v2/guide/components-props.html#Disabling-Attribute-Inheritance

      【讨论】:

        猜你喜欢
        • 2017-08-06
        • 1970-01-01
        • 2021-12-01
        • 2020-10-28
        • 2019-07-16
        • 2018-11-21
        • 1970-01-01
        • 2018-04-10
        相关资源
        最近更新 更多