#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-fragments2. @IVOGELOV: Спасибо за совет. Я пропустил ту часть, когда не было ни одного корневого узла. Переключение на Vue3 не вариант, поэтому я попытался использовать рендеринг с функциональным компонентом, но это не решило проблему.
3. dzone.com/articles /… или используйте Vue-фрагменты