-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
breadcrumb.vue
executable file
·92 lines (82 loc) · 3.14 KB
/
breadcrumb.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<template>
<ol class="breadcrumb">
<li v-for="normalizedItem in normalizedItems"
:class="['breadcrumb-item', normalizedItem.active ? 'active' : null]"
@click="onClick(normalizedItem._originalItem)"
role="presentation">
<span v-if="normalizedItem.active"
:aria-current="ariaCurrent"
v-html="normalizedItem.text"></span>
<b-link v-else
v-bind="normalizedItem._linkProps"
v-html="normalizedItem.text"></b-link>
</li>
<slot></slot>
</ol>
</template>
<script>
import bLink from './link.vue';
import { props as linkProps } from '../mixins/link';
import arrayIncludes from '../utils/arrayIncludes';
const bLinkPropKeys = Object.keys(linkProps);
export default {
components: { bLink },
computed: {
normalizedItems() {
let userDefinedActive = false;
const originalItemsLength = this.items.length;
return this.items.map((item, index) => {
let normalizedItem = { _originalItem: item };
// if no active state is defined,
// default to the last item in the array as active
const isLast = index === originalItemsLength - 1;
// nothing defined except the text
if (typeof item === 'string') {
Object.assign(normalizedItem, { text: item, link: '#', active: isLast });
} else {
Object.assign(normalizedItem, item);
}
// don't default the active state if given a boolean value,
// or if a user defined value has already been given
if (normalizedItem.active !== true && normalizedItem.active !== false && !userDefinedActive) {
normalizedItem.active = isLast;
} else if (normalizedItem.active) {
// here we know we've been given an active value,
// so we won't set a default value
userDefinedActive = true;
}
if (normalizedItem.link) {
// default the link value to bLink's href prop
normalizedItem.href = normalizedItem.link;
}
// stuff all the bLink props into a single place
// so we can bind to the component
// for dynamic prop proxying
normalizedItem._linkProps = Object.keys(normalizedItem).reduce((memo, itemProp) => {
if (arrayIncludes(bLinkPropKeys, itemProp)) {
memo[itemProp] = normalizedItem[itemProp];
}
return memo;
}, {});
return normalizedItem;
});
}
},
props: {
items: {
type: Array,
default: () => [],
required: true
},
ariaCurrent: {
type: String,
default: 'location'
}
},
methods: {
onClick(item) {
this.$emit('click', item);
}
}
};
</script>