Vuejs将道具从对象传递到动态组件中

时间:2019-01-29 19:40:43

标签: javascript vue.js vuejs2 vue-component

我正在制作一个仪表板应用程序,有人可以在其中将任何小部件以任何顺序添加到其仪表板。一切正常,但是我试图消除一些技术债务并进行清理。

为简单起见,假设一个仪表板可以具有2个小部件(“时钟”和“天气”)。这些小部件需要仪表板记录中的一些数据。这些小部件可以在页面上以任何顺序排列。

我就是这样包括他们的。

data () {
    return {
      widget1: 'Clock',
      widget2: 'Weather',
      widgetData: {
        weather: {
          long: '12.23.34',
          lat: '23.34.45'
        },
        Clock: {
          timeFormat: '24Hour',
          dateFormat: 'US'
         }
      }
    }
}

然后在HTML中

<component v-bind:is="this.widget1" :widgetData="widgetData"></component>

<component v-bind:is="this.widget2" :widgetData="widgetData"></component>

现在我要做的是

<!-- if this.widget1 is Clock then :widgetData should equals widgetData.Clock -->

<component v-bind:is="this.widget1" :widgetData="widgetData.this.widget1"></component>

<!-- if this.widget2 is Weather then :widgetData should equals widgetData.Weather -->

<component v-bind:is="this.widget2" :widgetData="widgetData.this.widget2"></component>

以便this.widget1可以同时填充:is并向下钻取到:widgetData对象,以便Im不会将整个对象传递给每个组件

我的示例仅考虑了2个小部件,但实际上,一个简单的仪表板最多可以包含9个。

我已经尝试了很多类似

的方法

:widgetData="widgetData.{{this.widget1}}"
:widgetData="widgetData.${this.widget1}"

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

如果您愿意对数字进行硬编码:

:widgetData="widgetData[widget1]"

以此类推

答案 1 :(得分:1)

您可以尝试使用一种函数,该函数将采用小部件类型并返回所需数据。

:widgetData="getWidgetData(this.widget1)"

...

method: {
  getWidgetData(widgetType) {
    if (widgetType == "Clock") {
      return clockData;
    }
    if (widgetType == "Weather") {
      return weatherData;
    }
  }
}

如果您的商店变得比数组更复杂,这将特别有用。

答案 2 :(得分:1)

所以,如果是我,我会稍微重新构架。我实际上将使用您创建的对象,而不仅仅是为每个组件显式调用小部件组件。鉴于:

data () {
    return {
      widgetData: {
        Weather: {
          long: '12.23.34',
          lat: '23.34.45'
        },
        Clock: {
          timeFormat: '24Hour',
          dateFormat: 'US'
         }
      }
    }
}

鉴于此,您的键与小部件类型相同,并且数据为值。因此,您可以这样做:

<div v-for="(value, key) in widgetData">
  <component :is="key" :widgetData="value" />
</div>

或者,如果您不希望包装div,您也应该只能使用该组件:

<component v-for="(value, key) in widgetData" :is="key" :widgetData="value" />

-如果正如注释所建议的那样,可以设置顺序,那么我实际上会稍微更改您的数据模型以完成相同的操作。在这种情况下,小部件在数组中的索引将是小部件进入的顺序:

data () {
    return {
      widgetData: [
       { type: "Weather",
         data: {
          long: '12.23.34',
          lat: '23.34.45'
        },
        { type: "Clock",
          data: {
          timeFormat: '24Hour',
          dateFormat: 'US'
         }
      }
    ]
}

在这种情况下,组件绑定将像这样:

<component v-for="widget in widgetData" :is="widget.type" :widgetData="widget.data" />