samturrell / vue-breadcrumbs

Breadcrumbs for Vue.js
MIT License
146 stars 27 forks source link

Update breadcrumb value from component #1

Open levani opened 8 years ago

levani commented 8 years ago

Is it possible to update breadcrumb value from the component? For example when I go to article page, I want to show the title of the article in breadcrumb, not something general like "Article page".

samturrell commented 8 years ago

If the article page is going to be the last item in the breadcrumbs, you could use the $breadcrumbs property, loop it and then append your data to the end. e.g.

<ul>
    <li v-for="crumb in $breadcrumbs">
        <a v-link="crumb">{{ crumb.handler.breadcrumb }}</a>
    </li>
    <li>
        {{ article.title }}
    </li>
</ul>
samturrell commented 8 years ago

Implemented in branch issue-1, but does not update the dom until a second navigation occurs, which obviously isn't ideal.

I've tracked it down to a single line of code in the vue-router package Object.freeze() on the Router, commenting this out allows the dom to update freely, but obviously this isn't a viable fix.

Wondering if there's another way to enable the reactive state?

asmaps commented 8 years ago

@samturrell probably with $set or Vue.set - described here: https://vuejs.org/guide/reactivity.html#Change-Detection-Caveats

Same for arrays: https://vuejs.org/guide/list.html#Caveats

asmaps commented 8 years ago

Ok, I see what you mean. The problem is the same if you use $set.

samturrell commented 8 years ago

Some work i did on this a little while ago can be viewed here: https://github.com/samturrell/vue-breadcrumbs/blob/issue-1/src/index.js

Basically it's leveraging the internal Vue.util.defineReactive helper to listen for changes, but only changes on second page load.

asmaps commented 8 years ago

Yes, I checked it out and am currently trying around with it, but also couldn't find a solution yet.

asmaps commented 8 years ago

I'm thinking about setting a 'breadcrumb' (computed?) property in the displayed component itself, but it seems like there is no link from the route to the actual component object.

samturrell commented 8 years ago

In my branch it's available as this.$breadcrumb (https://github.com/samturrell/vue-breadcrumbs/blob/issue-1/examples/index.js)

asmaps commented 8 years ago

Sure, I saw that, but you're still storing it in the route object (which is frozen) via the setter, not in the component object (which is not frozen). I'm more thinking about something like this (note the crumbs.push(...) line):

Plugin:

Object.defineProperties(Vue.prototype, {
$breadcrumbs: {
      get: function () {
        var crumbs = [];
        for (var i = 0; i < this.$route.matched.length; i++) {
          if (componentObject.breadcrumbText) {
            crumbs.push({route: this.$route.matched[i], text: componentObject.breadcrumbText});
          }
        }
        return crumbs;
      },
    },
}

In component:

export default {
  computed: {
    breadcrumb () {
      return this.foo.bar
    }
  }
}

The problem is that I can't find a way to get componentObject (this.$route.matched[i].handler.component is just the definition, not the actual object)

PS: I'm asmaps on freenode - so we don't need to chat over the github comments :-D

StreetStrider commented 7 years ago

Good way to achieve that is to support some form of simple DSL inside { breadcrumb: ... } and the ability to reference things from component's scope and current route.

{ breadcrumb: [ '$scope', 'title' ]}
// or
{ breadcrumb: ($scope) => $scope.title }

This would allow to access router and other constructs as well, since router injected into component's instance as everything else.

Leshgan commented 7 years ago

So? Is there any solution?

samturrell commented 7 years ago

Hey guys, i'll try to look into this again this weekend if i have some time. Otherwise I'm happy to accept a PR 😄

ChadTaljaardt commented 7 years ago

@samturrell Have you played with this?

samturrell commented 7 years ago

I've been looking into this for a couple of hours now. I've managed to sync up the data in the meta with a $breadcrumb value in the components data, but not have this be reactive on the page. The issue being that the $breadcrumbs data itself is not reactive simply because it is based on the $route data, and not any one component instance.

I somehow need to trigger a recalculation of the $breadcrumbs getter when a a components $breadcrumb data is updated.

ChadTaljaardt commented 6 years ago

@asmaps Did you find a solution to this?

asmaps commented 6 years ago

@ChadTaljaardt no, but I'm also not using this package anymore. And also I'm not using breadcrumbs anymore