0

这是我使用的代码。

<template>
  <div class="button-layout" :style="`margin: ${margin}; text-align: ${align};`">
    <component
      :is="buttonComponent"
      v-for="(button, index) in buttons.filter(btn => btn.url)"
      :key="button.label"
      :label="button.label"
      v-scroll-to="button.url"
      :style="`margin-left: ${index === 0 ? '' : space};`" />
    <component
      :is="buttonComponent"
      v-for="(button, index) in buttons.filter(btn => !btn.url)"
      :key="button.label"
      :label="button.label"
      :type="button.type"
      :style="`margin-left: ${index === 0 ? '' : space};`" />
  </div>
</template>

<script>
export default {
  name: "ButtonLayout",
  components: {  },
  props: {
    button: String,
    margin: String,
    align: String,
    space: String,
    buttons: Array
  },
  computed: {
    buttonComponent() {
      return () => import(`./button/${this.button}`)
    }
  }
};
</script>

我可以使用这两个对象结构列表,它工作正常。

[
    { url: '#video', label: lang.video },
    { url: '#info', label: lang.info }
]
[
    { type: 'reset', label: lang.clear },
    { type: 'submit', label: lang.send }
]

由于我不喜欢重复我的代码,我尝试根据列表中的第一个对象动态添加属性typev-scroll-to但是它不起作用。实现它的最佳方法是什么?(见下面的代码)

<template>
  <div class="button-layout" :style="`margin: ${margin}; text-align: ${align};`">
    <component
      :is="buttonComponent"
      v-for="(button, index) in buttons"
      :key="button.label"
      :label="button.label"
      v-bind:[optionalDirective.directive]="button[optionalDirective.key]"
      :style="`margin-left: ${index === 0 ? '' : space};`" />
  </div>
</template>

<script>
export default {
  name: "ButtonLayout",
  components: {  },
  props: {
    button: String,
    margin: String,
    align: String,
    space: String,
    buttons: Array
  },
  computed: {
    buttonComponent() {
      return () => import(`./button/${this.button}`)
    },
    optionalDirective(){
      if(this.buttons[0].url) {
        return {
          directive: 'v-scroll-to',
          key: 'url'
        }
      } else {
        return {
          directive: 'type',
          key: 'type'
        }
      }
    }
  }
};
</script>
4

2 回答 2

0

由于v-scroll-to无法绑定v-bind,我发现了一些实际解决我的问题并避免重复代码两次的解决方法。我将 绑定@click到一个检查url值的方法,$scollTo如果需要,它解决了我的问题。

<template>
  <div class="button-layout" :style="`margin: ${margin}; text-align: ${align};`">
    <component
      :is="buttonComponent"
      v-for="(button, index) in buttons"
      :key="button.label"
      :label="button.label"
      v-bind="type(button.type)"
      @click="scrollTo(button.url)"
      :style="`margin-left: ${index === 0 ? '' : space};`"
    />
  </div>
</template>

<script>
export default {
  name: "ButtonLayout",
  components: {},
  props: {
    button: String,
    margin: String,
    align: String,
    space: String,
    buttons: Array
  },
  methods: {
    type(type) {
      return type ? { type } : {}
    },
    scrollTo(url) {
      if (url) this.$scrollTo(url)
    }
  },
  computed: {
    buttonComponent() {
      return () => import(`./button/${this.button}`);
    }
  }
};
</script>
于 2020-04-15T06:58:08.250 回答
0

您可以将对象传递给v-bind它,它将根据对象的键创建 html 属性。

像这样的东西应该工作

<component
      :is="buttonComponent"
      v-for="(button, index) in buttons"
      :key="button.label"
      :label="button.label"
      v-bind="{[button.url ? 'v-scroll-to' : 'type' ] : (button.url || button.type} }"
      :style="`margin-left: ${index === 0 ? '' : space};`" />

或者您可以声明一个返回所需对象的新方法

methods: {
  buttonDirective (button) {
   if (button.url) {
     return {
       'v-scroll-to': button.url
     }
   } else {
     return {
       'type': button.type
     }
   }
  }
}

然后调用它component

<component
      :is="buttonComponent"
      v-for="(button, index) in buttons"
      :key="button.label"
      :label="button.label"
      v-bind="buttonDirective(button)"
      :style="`margin-left: ${index === 0 ? '' : space};`" />
于 2020-04-15T06:07:07.310 回答