简体   繁体   English

在Vue中,我可以转移道具吗?

[英]In Vue, can I transfer props?

Imagine I have a <progress-bar> UI component and I want to create an <app-progress-bar> component that is the same as the <progress-bar> but with some style tweaks.想象一下,我有一个<progress-bar> UI 组件,我想创建一个<app-progress-bar>组件,它与<progress-bar>相同,但有一些样式调整。

AppProgressBar.vue: AppProgressBar.vue:

<template> <progress-bar class="app-progress-bar"></progress-bar> </template>

This will break because <progress-bar> requires a percent prop.这会中断,因为<progress-bar>需要percent属性。 So I can pass it in:所以我可以把它传入:

<progress-bar class="app-progress-bar" percent="percent"></progress-bar>

This seems fine, but is brittle when <progress-bar> has many props.这看起来很好,但是当<progress-bar>有很多道具时很脆弱。 Can I simply pass through all props?我可以简单地通过所有道具吗? Theoretical syntax:理论语法:

<progress-bar class="app-progress-bar" {...props}></progress-bar>

Which is similar to React/JSX.这类似于 React/JSX。

Like already answered, extending the component would be a nice way to create your components in this scenario.就像已经回答的那样,扩展组件将是在这种情况下创建组件的好方法。 Similar to class inheritance in other languages.类似于其他语言中的类继承。

However, you can also pass an object as prop.但是,您也可以将对象作为道具传递。 If you want to keep things clean, and don't want to extend your components, you could pass a prop like this:如果你想保持干净,不想扩展你的组件,你可以像这样传递一个 prop:

//object with many values that you need to pass. for ex.
myObjectWithSuff: { percent: 10%, someOtherStuff: value, ... } 

<progress-bar class="app-progress-bar" myProp="myObjectWithStuff"></progress-bar>

Inside the progress-bar component, declare the prop myProp .progress-bar组件中,声明道具myProp Then you can access any properties on that object.然后您可以访问该对象的任何属性。 For example: this.myProp.percent .例如: this.myProp.percent

This is just quick and simple, but depending on your architecture, extending components may be the way to go.这既快速又简单,但根据您的架构,扩展组件可能是可行的方法。

After researching this, I don't think it's possible.经过研究,我认为这是不可能的。 Instead, you can extend a component and put an extraClass key on data or computed :相反,您可以extend一个组件并在datacomputed上放置一个extraClass键:

import ProgressBar from './ProgressBar'

export default {
  extends: ProgressBar,
  data() {
    return { extraClass: 'app-progress-bar' }
  }
}

ProgressBar.vue:进度条.vue:

<template>
  <div class="progress-bar" :class="extraClass">...</div>
</template>

This isn't as clean or flexible as React, but it works.这不像 React 那样干净或灵活,但它确实有效。

Abstract抽象的

This can be done by binding $attrs to the child.这可以通过将 $attrs 绑定到孩子来完成。 So in your case it would be:因此,在您的情况下,它将是:

<template>
  <progress-bar v-bind="$attrs" class="app-progress-bar"></progress-bar>
</template>

Link to Docs链接到文档

vm.$attrs: Contains parent-scope attribute bindings (except for class and style)...and can be passed down to an inner component vm.$attrs:包含父范围属性绑定(类和样式除外)...并且可以向下传递给内部组件

Source: Vue $attrs documentation来源: Vue $attrs 文档

Example例子

Let's say that a component called <inner> has a boolean prop called dark and a string prop called color .假设一个名为<inner>的组件有一个名为dark的布尔属性和一个名为color的字符串属性。

Now let's define an outer component called <outer> which wraps <inner> in its definition.现在让我们定义一个名为<outer>的外部组件,它在其定义中包装了<inner>

<template>
  <inner></inner>
</template>
.
.
.
name: 'outer'

The issue here is if we use the <outer> component, we can't transfer the dark and color props through to the <inner> component which knows what to do with them.这里的问题是,如果我们使用<outer>组件,我们无法将深色和彩色道具传递给知道如何处理它们的<inner>组件。 For example <inner dark color="blue"></inner> works, but <outer dark color="blue"></outer> doesn't.例如<inner dark color="blue"></inner>有效,但<outer dark color="blue"></outer>无效。

If you change the definition of <outer> to include the $attrs binding, it will transfer all the props for you (this doesn't include style and class ).如果您更改<outer>的定义以包含$attrs绑定,它将为您传输所有道具(这不包括styleclass )。 Here is the new definition:这是新定义:

<template>
  <inner v-bind="$attrs"></inner>
</template>
.
.
.
name: 'outer'

Now you can use <outer dark color="blue"></outer> .现在您可以使用<outer dark color="blue"></outer>了。

Additional note附加说明

You can also use the inheritAttrs prop to prevent this behaviour by default.您还可以默认使用inheritAttrs来防止这种行为。 You can take a look at the official Vue docs here and I also found this JSFiddle which gives an example of inheritAttrs being used.你可以在这里查看官方的 Vue 文档,我还发现了这个 JSFiddle ,它给出了一个使用inheritAttrs的例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM