web-dev-qa-db-fra.com

vue.js - Organiser une grande application d'une seule page avec plusieurs vues

Je joue avec le nouveau framework MVVM - Vue.js ( http://vuejs.org/ ).

C'était vraiment sympa dans des exemples et des démos simples, mais maintenant j'essaie de créer un grand SPA avec plusieurs vues et je me rends compte que le meilleur modèle pour le faire n'est pas décrit dans les documents du framework.

Le problème principal est que je ne sais pas comment gérer les vues sur différents itinéraires.

Par exemple, j'utilise Director ( https://github.com/flatiron/director ) pour le routage mais comment puis-je changer de vue?

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();

Dois-je créer des ViewModels Vue.js séparés et juste display:block / display:none comme dans cet exemple?

Quelle serait la bonne façon selon vous? Merci!

32
Kosmetika

Les sous-vues imbriquées peuvent être résolues à l'aide de v-view et 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/

24
koba04

La façon officiellement recommandée d'utiliser le routage dans les applications vuejs est d'utiliser vue-router :

Citant de la documentation:

vue-router Est le routeur officiel de Vue.js . Il s'intègre profondément au cœur de Vue.js pour que la création d'applications à page unique avec Vue.js soit un jeu d'enfant. Les fonctionnalités incluent:

  • Cartographie de route/vue imbriquée
  • Configuration de routeur modulaire basée sur les composants
  • Paramètres de route, requête, caractères génériques
  • Afficher les effets de transition optimisés par le système de transition de Vue.js
  • Contrôle de navigation à grain fin
  • Liens avec les classes CSS actives automatiques
  • Mode historique HTML5 ou mode de hachage, avec repli automatique dans IE9
  • Restaurer la position de défilement lors du retour en mode historique

Le bien écrit documentation développe davantage sur Modular, component-based router configuration, Y compris des exemples sur la gestion des routes imbriquées.

Une sortie router-view Est mise à disposition dans laquelle la configuration de l'itinéraire peut spécifier le composant à restituer. Ces composants peuvent contenir des prises router-view Intégrées permettant la gestion des itinéraires imbriqués orientés composants.

Exemple de la documentation:

<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's <router-view>
        // when /foo/bar is matched
        component: Bar
      },
      '/baz': {
        // Same for Baz, but only when /foo/baz is matched
        component: Baz
      }
    }
  }
})
15
lorefnon

Vous pourriez être en mesure d'utiliser v-view et le composant?

comme ça.

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
koba04

Vous pouvez utiliser des vues nommées si vous ne souhaitez pas les imbriquer.

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/

Le violon provient du doc: https://router.vuejs.org/en/essentials/named-views.html

0
paibamboo