Встроенный шаблон в vue

#vuejs2 #javalin

#vuejs2 #javalin

Вопрос:

Я хотел бы использовать локальный компонент в VueJS:

Мой файл компонента (немного очищен):

 <template id="heroValuePair">
    <td class="inner label">{{label}}</td>
    <td class="inner value">{{c}}</td>
    <td class="inner value">
        {{t}}
        <span v-if="c < t" class="more">( {{t-c}})</span>
        <span v-if="c > t" class="less">({{t-c}})</span>
    </td>
</template>


<template id="hero">

    <table class="hero card" border="0" cellpadding="0" cellspacing="0">
        <tr>
           <td>other data...</td>
       </tr>
        <tr>
            <hvp label="Label" v-bind:c="current.level" :t="target.level" :key="hero.id"/>
        </tr>
    </table>
</template>

<script>
  var HeroValuePair = {
        template: "#heroValuePair",
        props: {
            label : String,
            c : Number,
            t : Number
        },
        created() {
            console.log("HVP: " this.c " " this.t);
        }
    };


    Vue.component("Hero", {
        template: "#hero",
        props: {
            heroId : String
        },
        components: {
            "hvp" : HeroValuePair
        },
        data: () => ({
            hero: {},
            current: {},
            target: {}
        }),
        computed: {

        },
        created() {
            fetch("/api/hero/" this.heroId)
                .then(res => res.json())
                .then(res => {
                    this.hero = res.hero
                    this.current = res.current
                    this.target = res.target
                 })
        }
    });

</script>
<style>
</style>
  

Этот внешний шаблон героя используется в итераторе списка:

 <template id="card-list">
    <table>
        Card list
       <div id="">
           <div v-for="card in cards" class="entry">
               <Hero :hero-id="card.hero.id" :key="card.hero.id"/>
           </div>
       </div>

    </table>

</template>
<script>
    Vue.component("card-list", {
        template: "#card-list",
        data: () => ({
            cards: [],
        }),
        created() {
            fetch("/api/cards")
                .then(res => res.json())
                .then(res => {
                    this.cards = res.heroes
                 })
                .catch((e) => alert("Error while fetching cards: " e));
        }
    });

</script>
<style>
</style>

  

Однако, когда я отображаю список карточек, он выдает только список первых td в hvp шаблоне:

введите описание изображения здесь

Когда я закомментирую вызов hpv страницы, он отображается правильно со всем HTML-кодом из шаблона Hero.

Я попытался выяснить, какой шаг я пропустил, но не могу найти ключ. Последняя информация: я использовал JavalinVue для поддержки серверной части, а не Vue CLI на основе nodejs. Я не знаю, оказывает ли это какое-либо влияние, но может быть важным.

ОБНОВЛЕНИЕ 1

После того, как ИВО ГЕЛОВ обнаружил проблему с несколькими корневыми тегами, и поскольку я не могу перейти на Vue3, я попытался сделать его функциональным шаблоном, как он предложил. Я удалил шаблон и создал render функцию:

 
  var HeroValuePair =  {
        template: "#heroValuePair",
        functional: true,
        props: {
            label : String,
            c : Number,
            t : Number
        },
        render(createElement, context) {
            console.log("HVP: " context.props.c " " context.props.t);
            if (typeof context.props.c === undefined) return createElement("td"  )
            else return [
                createElement("td", context.props.label  ),
                createElement("td", context.props.c  ),
                createElement("td", context.props.t  )
            ]
        }
    }
  

Хотя консоль указала, что рендеринг вызывается правильно, результат тот же: не отображаются ни отображаемые узлы, ни родительский компонент Hero. Я попытался перейти в другой файл, попробовал функциональный формат шаблона, но ничего не получилось.

Комментарии:

1. Если вы используете Vue 2.x — он не поддерживает шаблоны с более чем 1 корневым узлом (а ваш компонент HVP имеет 3 TD узла). Вы должны либо использовать Vue 3.x, либо преобразовать HVP в функциональный компонент с функцией визуализации вместо шаблона. ИЛИ вы можете использовать github.com/y-nk/vue-fragments

2. @IVOGELOV: Спасибо за совет. Я пропустил ту часть, когда не было ни одного корневого узла. Переключение на Vue3 не вариант, поэтому я попытался использовать рендеринг с функциональным компонентом, но это не решило проблему.

3. dzone.com/articles /… или используйте Vue-фрагменты