Надеюсь, для меня это тривиальная проблема, и я просто пропустил крошечный магический фрагмент кода: я vue.js
с knockout.js
на vue.js
и мне интересно, есть ли простой способ использовать шаблоны так же, как и в vue.js
как в knockout.js
. В приведенном ниже коде используется функция knockout.js
и работает как ожидалось:
function viewmodel() {
this.person = ko.observable(new person());
}
function person() {
this.first = ko.observable('hello');
this.last = ko.observable('world');
}
ko.applyBindings(new viewmodel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/html" id="person-template">
<p data-bind="text: first"/>
<p data-bind="text: last"/>
</script>
<div>
<div data-bind="template: { name: 'person-template', data: person }"/>
</div>
Однако я не могу понять, как добиться этого в vue.js
Я знаю компоненты в vue.js
и все такое, но я хочу сохранить структуру такой, какой она есть, и не помещать больше кода, специфичного для просмотра, в мои файлы JavaScript. (Я уже не доволен el: '#app'
, но в то же время моя наименьшая проблема) Конечно, этот код не работает:
var app = new Vue({
el: '#app',
data: {
person: {
first: 'hello',
last: 'world'
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script>
<script type="text/x-template" id="person-template">
<p v-text="first"/>
<p v-text="last"/>
</script>
<div id="app">
<div><!-- how? is this even possible? --></div>
</div>
Есть ли способ заставить это работать, только изменяя HTML-часть кода? Предпочтительно только <div>
-Element.
Таким образом, это не совсем изменение шаблона, но здесь может работать одно дополнительное свойство. Укажите шаблон в Vue.
var app = new Vue({
el: '#app',
template: "#person-template",
data: {
person: {
first: 'hello',
last: 'world'
}
}
});
Я также немного изменил ваш шаблон, потому что для шаблона для любого Vue или компонента требуется один корневой элемент. Я рекомендую вам не использовать самозакрывающиеся теги в Vue, поскольку я видел эту проблему. Vue требует действительных HTML5, а самозакрывающиеся теги недействительны HTML5.
<script type="text/x-template" id="person-template">
<div>
<p v-text="person.first"></p>
<p v-text="person.last"></p>
</div>
</script>
Рабочий пример.
Кроме того, очень распространенный способ указания шаблонов таким образом, без использования трюка хакерского скрипта, заключается в использовании элемента шаблона HTML5.
<template id="person-template">
<div>
<p v-text="person.first"></p>
<p v-text="person.last"></p>
</div>
</template>
Наконец, зная, что вы немного недовольны el:"#app"
Вы можете оставить свойство el
вне определения Vue и установить Vue на элемент по вашему выбору с помощью метода $ mount. Поэтому, если вы хотите полностью разогнаться, вы можете сделать что-то подобное.
const renderer = Vue.compile(document.querySelector("#person-template").innerHTML)
const example = {
data: {
person: {
first: 'hello',
last: 'world'
}
}
}
const app = new Vue(Object.assign({}, example, renderer))
app.$mount("#app")
Я должен упомянуть, что никто этого не делает (компиляция их шаблонов вручную, как правило, используется $ mount), о котором я знаю. Это также зависит от использования версии Vue, которая включает компилятор (который у вас может не возникнуть, если вы используете webpack или какой-либо другой инструмент сборки, например). Вы также можете сделать что-то вроде этого:
const app = new Vue(Object.assign({}, example, {template: "#person-template"}))
app.$mount("#app")
который в основном позволит вам указать шаблон, компонент и место для его монтирования отдельно.
person
внутри шаблона, а не только на его свойства. С моим примером KO я мог бы просто повторно использовать шаблон в основном для всего, что имеет эти два свойства. Как и сейчас (по крайней мере, из моего нынешнего понимания) я просто выгрузил способ визуализации человека вместо определения (многоразового) шаблона