vuejs / Discussion

Vue.js discussion
167 stars 17 forks source link

Problems with nested views #270

Open swift1 opened 9 years ago

swift1 commented 9 years ago

Hi guys. I've created a manual router, but it only seems to work up until the first level. Does anyone see what's wrong here? Any help would be appreciated.

(The problem is that the sub view's sub view does not show up, like this:

<p>sub1</p>

)

vue.$children[0].currentSubView

is being set correctly, but it doesn't update the binding:

<component is="{{currentSubView}}"></component>

https://jsfiddle.net/9678Lor5/1/

<div id="app">
    <ul>
        <li><a href="#/">top</a></li>
        <li><a href="#/sub">sub</a></li>
        <li><a href="#/sub/sub1">sub/sub1</a></li>
        <li><a href="#/sub/sub2">sub/sub2</a></li>
    </ul>

    <component is="{{currentView}}"></component>
</div>

<script id="top" type="x-template">
    <div>top view</div>
</script>

<script id="sub" type="x-template">
    <div>sub view</div>

    <component is="{{currentSubView}}"></component>
</script>
var vue = new Vue({   
    el: '#app',
    data: {
        currentView: 'top',
    },
    components: {
        'top': {
            template: '#top'
        },
        'sub': {    
            template: '#sub',
            data: {
                currentSubView: 'sub1'
            },
            components: {
                'sub1': { 
                    template: '<p>sub1</p>'
                },
                'sub2': { 
                    template: '<p>sub2</p>'
                },
                'sub3': { 
                    template: '<p>sub3</p>'
                }
              }
        }
    }
})

window.addEventListener("hashchange", function(hash){
    var url = hash.newURL.substr(hash.newURL.indexOf("#")+1);
    console.log(url);
    switch(url){
        case "/":
            vue.currentView = "top";
        break;
        case "/sub":
            vue.currentView = "sub";
        break;
        case "/sub/sub1":
            vue.currentView = "sub";
            vue.$children[0].currentSubView = "sub1";
        break;
        case "/sub/sub2":
            vue.currentView = "sub";
            vue.$children[0].currentSubView = "sub2";
        break;
    }
});
swift1 commented 9 years ago

I've also tried to add

compiled: function(){
    console.log('compiled');
    this.$on('broadcast', function(val){
        console.log('incoming broadcast: ' + JSON.stringify(val));
        this.$data = val;
    })
}

to the sub component, but nothing happens when i run

vue.$children[0].$broadcast({currentSubView: "sub2"});

so I'm kinda lost atm :(

edit: I was missing a parameter in the broadcast :palm_tree:

swift1 commented 9 years ago

I finally got it to work :smile: :smile: :smile:

It might not be the best way to do it, but at least it works: https://jsfiddle.net/9678Lor5/7/

If you have any tips on how to improve it, I'd like to know it :smiley:

I guess the clue was to realize that it's not possible to nest more than one sub-level of components inside a component.