未显式声明的 Vue 道具

Posted

技术标签:

【中文标题】未显式声明的 Vue 道具【英文标题】:Vue props that aren't explicitly declared 【发布时间】: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 【参考方案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

【讨论】:

以上是关于未显式声明的 Vue 道具的主要内容,如果未能解决你的问题,请参考以下文章

即使未显式修改数组值也已修改[重复]

访问在 TF 2.0 中未显式公开为层的 Keras 模型的中间张量

怎么证明未显式定义构造方法时,编译器会自动生成无参的构造方法?

浅析SQL查询语句未显式指定排序方式,无法保证同样的查询每次排序结果都一致的原因

存储类作用域生命周期链接属性

5.FastAPI显式声明参数