Можно ли назвать компонент из данных? - PullRequest
0 голосов
/ 27 декабря 2018

У меня есть три иконки компонентов <DiscoverIcon>, <FeedIcon>, <ProfileIcon> и в цикле табуляции я хочу иметь возможность использовать разные иконки для каждого соответствующего заголовка.

Я пробовал элемент списка, например

{ key: 1, icon: <div class='iconbgd'><DiscoverIcon /></div>, text: 'Discover', route: '/discover'}

и звонок {{ link.icon }}, а также

{ key: 1, text: 'Discover', route: '/discover'}

и звонок <div class='iconbgd'><{{link.text}}Icon /></div>

<template>
  <v-tabs fixed-tabs>
    <v-tab
      v-for="link in links"
      :key="link.key"
    >
      <div class='iconbgd'><{{link.text}}Icon /></div><h4>{{ link.text }}</h4>
    </v-tab>
  </v-tabs>
</template>
<script>
import DiscoverIcon from '../components/icons/DiscoverIcon'
import FeedIcon from '../components/icons/FeedIcon'
import ProfileIcon from '../components/icons/ProfileIcon' 

export default {
  components: {
      DiscoverIcon,
      FeedIcon,
      ProfileIcon
    },
  name: 'App',
  data () {
    return {
      links: [
          { key: 1, icon: <div class='iconbgd'><DiscoverIcon /></div>, text: 'Discover', route: '/discover'},
          { key: 2, icon: <div class='iconbgd'><FeedIcon /></div>, text: 'Feed', route: '/feed'},
          { key: 3, icon: <div class='iconbgd'><ProfileIcon /></div>, text: 'Profile', route: '/profile'}
      ]
    }
  }
}
</script>


<style>
.iconbgd svg{
  fill:url(#grad1);
  width: 30px;
  height: auto;
  padding-right: 5px;
}
</style>

Это компонент вкладок Vuetify для этого варианта использования, но работа с ним не связана с использованием вкладок, но мой ожидаемый результат - возможность циклически проходить и в каждой вкладке использовать отдельный коррелированный компонент, а не просто создавать три отдельные кнопки, которыеУ меня сейчас есть.

Ответы [ 2 ]

0 голосов
/ 29 декабря 2018

Спасибо большое!Несколько настроек, и это работает.

<v-tabs fixed-tabs color='transparent' slider-color='#1341B2'>
         <v-tab v-for="link in links" :key="link.key" :to="link.route">
            <div class="iconbgd">
                <component :is="link.label + 'Icon'" :key="link.key"/>
            </div>
            <h4>{{link.label}}</h4>
        </v-tab>
    </v-tabs>
0 голосов
/ 27 декабря 2018

Прежде всего {{link.icon}} не предназначен для отображения в виде HTML.Вы должны использовать другой подход.

<div class='iconbgd'><{{link.text}}Icon /> равно <div class='iconbgd' v-text="link.text"><Icon />.Поэтому Vue имеет директиву v-html для HTML, вы можете прочитать здесь больше о разновидностях директив .

Тем не менее, старайтесь избегать v-html, когда это возможно и так как различные {{link.icon}} очень похожи, вы могли бы сделать это легко без v-html.

Похоже, вы пытаетесь связать компоненты <{{link.text}}Icon />. Динамические компоненты - это то, что вы ищете, и они очень мощные.

Я быстро просмотрел документацию Vuetify для v-tabs и немного ее изменил, однако никогда раньше не использовал иэто не проверено .Это должно быть то, что вы пытаетесь достичь:

<template>
  <v-tabs fixed-tabs>
    <v-tab v-for="link in links" :key="link.key">
      <div class="iconbgd">{{link.label}}</div>
    </v-tab>
    <v-tab-item v-for="link in links" :key="link.key">
      <h4>{{link.label}}</h4>
      <component :is="link.label + 'Icon'" :key="link.key"/>
    </v-tab-item>
  </v-tabs>
</template>

<script>
import DiscoverIcon from '../components/icons/DiscoverIcon';
import FeedIcon from '../components/icons/FeedIcon';
import ProfileIcon from '../components/icons/ProfileIcon';

export default {
  data() {
    return {
      links: [
        {
          key: 1,
          label: 'Discover',
          route: '/discover'
        },
        {
          key: 2,
          label: 'Feed',
          route: '/feed'
        },
        {
          key: 3,
          label: 'Profile',
          route: '/profile'
        }
      ]
    };
  },
  name: 'App',
  components: {
    DiscoverIcon,
    FeedIcon,
    ProfileIcon
  }
};
</script>


<style>
.iconbgd svg {
  fill: url(#grad1);
  width: 30px;
  height: auto;
  padding-right: 5px;
}
</style>
...