Reputation: 3277
I'm trying to access an anchor element in a computed property in order to determine whether is should be set to active or remain as is.
I've seen examples using v-for and looping through data properties, but this is a static menu like so:
<template>
<div class="panel panel-default">
<div class="panel-heading">Application Menu</div>
<ul class="list-group">
<a :href="route('applications.index')"
:class="activeClass"
class="list-group-item">Applications</a>
<a :href="route('applications.repository')"
:class=""
class="list-group-item">Token Repository</a>
<a :href="route('applications.notifications')"
:class=""
class="list-group-item">Notifications</a>
</ul>
</div>
</template>
My activeClass
computed prop would compare the href
of the current anchor to the current location of the browser and return active
if they match.
I've consulted all the documentation on the Vue website and Googled extensively, and I've not yet found a way to access the href attribute of the anchor calling the computed property.
Upvotes: 1
Views: 3904
Reputation: 3277
Final solution:
<template>
<div class="panel panel-default">
<div class="panel-heading">Application Menu</div>
<ul class="list-group">
<a :href="route('applications.index')"
:class="activeClass('applications')"
class="list-group-item">Applications</a>
<a :href="route('applications.repository')"
:class="activeClass('repository')"
class="list-group-item">Token Repository</a>
<a :href="route('applications.notifications')"
:class="activeClass('notifications')"
class="list-group-item">Notifications</a>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
currentLink: location.href,
}
},
computed: {
routes() {
return window.routes
},
},
mounted() {
this.setCurrentLink()
},
methods: {
route(url) {
return this.routes.route(url)
},
activeClass(segment) {
return segment == this.currentLink ? 'active' : ''
},
setCurrentLink() {
this.currentLink = new URL(location.href).pathname.split('/').pop();
}
}
}
</script>
Works perfectly without the need to iterate through a loop. I call this a rare use case, but for something small and static it fits the bill.
Thanks to all who contributed.
Upvotes: 1
Reputation: 43881
You are thinking about it wrong. You should not be trying to access the attributes of DOM elements as if they are data. The DOM is not a data store. Data should be in your viewmodel and be used in the DOM.
You should have an array of objects that describe your items. (Also, the only permitted children of a ul
are li
.) You could do something like this:
<ul class="list-group">
<li v-for="item in menuItems">
<a :href="item.route"
:class="isActive(item)"
class="list-group-item">{{model.label}}</a>
</li>
</ul>
If you want to have a computed
that works for each of your items, you would need to make a component for each item. See vuejs using computed property for array elements
Upvotes: 2
Reputation: 13120
You can't do that, and here's why. A computed property should be universal. That is to say, its value is not determined by who is accessing it. If you access this.activeClass
from inside a method, its value should be the same as activeClass
inside a template, assuming the state information it depends on is the same. (And who is accessing it is not state information)
If you're using Vue-Router, you can however just compare the value of $route.path and use a different class. For example:
<a :href="route('applications.index')"
:class="$route.path === 'whatever' ? 'active-class' : 'inactive-class'">Applications</a>
Upvotes: 2