Vue.js - организация большого одностраничного приложения с несколькими видами
Я играю с новой инфраструктурой MVVM - Vue.js (http://vuejs.org/).
Это было очень приятно в простых примерах и демонстрациях, но теперь я пытаюсь создать большой SPA с несколькими представлениями, и я понимаю, что лучший шаблон, как это сделать, не описывается в документах инфраструктуры.
Основная проблема заключается в том, что я не знаю, как обрабатывать представления на разных маршрутах.
Например, я использую Director (https://github.com/flatiron/director) для маршрутизации, но как я могу изменить виды?
var booksCtrl = function () {
var booksViewModel = new Vue({
el: '#books'
data: { ... }
ready: function () {
// hide previous ViewModel and display this one??
}
});
};
var editBookCtrl = function (id) {
var editBookViewModel = new Vue({
el: '#editBook'
data: { ... }
ready: function () {
// hide previous ViewModel and display this one??
}
});
};
var routes = {
'/books': booksCtrl,
'/books/:id/edit': editBookCtrl
};
var router = new Router(routes);
router.init();
Нужно ли создавать отдельные VMM ViewModels и просто display:block / display:none
их как в этом примере?
Как вы считаете правильным? Спасибо!
Ответы
Ответ 1
Вложенные подзапросы могут быть разрешены с помощью v-view и v-ref.
HTML
<div id="main">
<div v-view="currentView" v-ref="view"></div>
</div>
<ul>
<li><a href="#/">top</a></li>
<li><a href="#/nest/view1">nest/view1</a></li>
<li><a href="#/nest/view2">nest/view2</a></li>
</ul>
<script id="top" type="x-template">
<div>top view</div>
</script>
<script id="nest" type="x-template">
<div>
<span>nest view</span>
<div v-view="subview"></div>
</div>
</script>
Javascript
Vue.component('top', Vue.extend({
template: "#top",
}));
Vue.component('nest', Vue.extend({
template: '#nest',
components: {
view1: Vue.extend({
template: '<span>this is subview 1</span>',
}),
view2: Vue.extend({
template: '<span>this is subview 2</span>',
}),
},
data: {
subview: "view1",
},
}));
var main = new Vue({
el: "#main",
data: {
currentView: "top",
},
});
var router = new Router({
'/': function() { main.currentView = 'top' },
'/nest/:view': function(view) {
main.currentView = 'nest';
main.$.view.subview = view;
},
});
router.init();
jsfiddle: http://jsfiddle.net/koba04/WgSK9/1/
Ответ 2
Официально рекомендуемым способом использования маршрутизации в приложениях vuejs является использование vue-router:
Цитата из документации:
vue-router
является официальным маршрутизатором для Vue.js. Это глубоко интегрируется с ядром Vue.js для создания единой страницы Приложения с Vue.js - легкий ветерок. Особенности включают:
- Вложенное отображение маршрута/просмотра
- Модульная конфигурация маршрутизатора на основе компонентов
- Параметры маршрута, запрос, групповые символы
- Просмотр эффектов перехода на основе системы перехода Vue.js
- Четкое управление навигацией
- Ссылки с автоматическими активными классами CSS
- Режим истории HTML5 или хеш-режим с автоматическим резервным копированием в IE9
- Восстановить положение прокрутки при возвращении в режиме истории
Хорошо написанная документация подробно описывает Modular, component-based router configuration
, включая примеры обработки вложенных маршрутов.
A router-view
доступен доступ, в котором конфигурация маршрута может указать, какой компонент должен отображать. Эти компоненты могут содержать встроенные выходы router-view
, позволяющие управлять вложенными маршрутами, ориентированными на компоненты.
Пример из документов:
<div id="app">
<router-view></router-view>
</div>
router.map({
'/foo': {
component: Foo,
// add a subRoutes map under /foo
subRoutes: {
'/bar': {
// Bar will be rendered inside Foo <router-view>
// when /foo/bar is matched
component: Bar
},
'/baz': {
// Same for Baz, but only when /foo/baz is matched
component: Baz
}
}
}
})
Ответ 3
Возможно, вы сможете использовать v-view и компонент?
как это.
Javascript
Vue.component('top', Vue.extend({
template: "<div>top view</div>",
}));
Vue.component('other', Vue.extend({
template: "<div>other view</div>",
}));
var main = new Vue({
el: "#main",
data: {
currentView: "top",
},
});
var router = new Router({
'/': function() { main.currentView = 'top' },
'/other': function() { main.currentView = 'other' },
});
router.init();
HTML
<div id="main">
<div v-view="currentView"></div>
</div>
Ответ 4
Вы можете использовать Named Views, если вы не хотите их вставлять.
HTML
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
Javascript
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
const Baz = { template: '<div>baz</div>' }
const router = new VueRouter({
mode: 'history',
routes: [
{
path: '/',
// a single route can define multiple named components
// which will be rendered into <router-view>s with corresponding names.
components: {
default: Foo,
a: Bar,
b: Baz
}
},
{
path: '/other',
components: {
default: Baz,
a: Bar,
b: Foo
}
}
]
})
jsfiddle: https://jsfiddle.net/posva/6du90epg/
Сценарий из документа: https://router.vuejs.org/en/essentials/named-views.html