Skip to content

Commit fee1503

Browse files
VdustRSamuell1
authored andcommitted
feat: router link components improvements (#1651)
* fix(MdTab): exact router fix exact router for active class fix #1644 * fix(MdList): non-exact router active style keep non-exact list item active when matched * fix(MdBottomBar router): elegant router with active class better router active with class instead of comparing `to` prop * fix(MdTabs): elegant router with active class better router active with class instead of comparing `to` prop * fix(MdBottomBar): fix bugs prevent active bar item directly in sync route mode * docs(WithRouter): discriptions about working with vue router * fix(MdTabs): better setIndicatorStyles performance with throttling * fix(MdTabs): fix bugs * docs(TabRouter): Better example Remove tabs in tabs because that's a bad idea * docs(TabRouter): remove unused codes * feat(MdSteppers): elegant router with active class better router active with class instead of comparing `to` prop * docs(WithRouter): add md-step * feat(MdStep): support all router-link props * refactor(MdThrottling): reduce duplicated code for getting options * fix(MdThrottling): typo * fix(routes): doc production mapRoutes method replace string * refactor(MdButton): lint complexity
1 parent 2b675c9 commit fee1503

File tree

21 files changed

+280
-205
lines changed

21 files changed

+280
-205
lines changed

docs/app/i18n/en-US/pages.js

+3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ export default {
5252
title: 'Themes - Advanced',
5353
nav: 'Advanced'
5454
},
55+
withRouter: {
56+
title: 'Work with Vue Router'
57+
},
5558
components: {
5659
title: 'Components',
5760
},

docs/app/pages/Components/BottomBar/examples/BarRouter.vue

+13-2
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,26 @@
22
<div>
33
<div class="phone-viewport">
44
<md-bottom-bar md-sync-route>
5-
<md-bottom-bar-item to="/components/bottom-bar/home" md-label="Home" md-icon="home"></md-bottom-bar-item>
5+
<md-bottom-bar-item to="/components/bottom-bar" exact md-label="Home" md-icon="home"></md-bottom-bar-item>
66
<md-bottom-bar-item to="/components/bottom-bar/posts" md-label="Posts" md-icon="/assets/icon-whatshot.svg"></md-bottom-bar-item>
77
<md-bottom-bar-item to="/components/bottom-bar/favorites" md-label="Favorites" md-icon="favorite"></md-bottom-bar-item>
88
</md-bottom-bar>
99
</div>
1010

1111
<div class="phone-viewport">
1212
<md-bottom-bar class="md-accent" md-sync-route>
13-
<md-bottom-bar-item to="/components/bottom-bar/home" md-label="Home" md-icon="home"></md-bottom-bar-item>
13+
<md-bottom-bar-item to="/components/bottom-bar" exact md-label="Home" md-icon="home"></md-bottom-bar-item>
1414
<md-bottom-bar-item to="/components/bottom-bar/posts" md-label="Posts" md-icon="/assets/icon-whatshot.svg"></md-bottom-bar-item>
1515
<md-bottom-bar-item to="/components/bottom-bar/favorites" md-label="Favorites" md-icon="favorite"></md-bottom-bar-item>
1616
</md-bottom-bar>
1717
</div>
18+
19+
<div class="phone-viewport">
20+
<md-bottom-bar class="md-accent" md-sync-route>
21+
<md-bottom-bar-item to="/components/bottom-bar/posts/1" md-label="Post 1" md-icon="/assets/icon-whatshot.svg"></md-bottom-bar-item>
22+
<md-bottom-bar-item to="/components/bottom-bar/posts/2" md-label="Post 2" md-icon="/assets/icon-whatshot.svg"></md-bottom-bar-item>
23+
</md-bottom-bar>
24+
</div>
1825
</div>
1926
</template>
2027

@@ -34,4 +41,8 @@
3441
border: 1px solid rgba(#000, .26);
3542
background: rgba(#000, .06);
3643
}
44+
45+
.md-bottom-bar .md-bottom-bar-item.router-link-active {
46+
text-shadow: 0 0 5px;
47+
}
3748
</style>

docs/app/pages/Components/List/examples/ListTypes.vue

+10-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@
44
<md-list-item>Plain Text</md-list-item>
55
<md-list-item @click="alert">Button</md-list-item>
66
<md-list-item href="https://google.com" target="_blank">Link</md-list-item>
7-
<md-list-item to="/components/list/router">Link Router</md-list-item>
8-
<md-list-item to="/components/list">Link Router Active Color</md-list-item>
7+
<md-list-item to="/components/list" exact>Router <code>/</code></md-list-item>
8+
<md-list-item to="/components/list/router">Router <code>/router/**</code></md-list-item>
9+
</md-list>
10+
<md-list>
11+
<md-list-item to="/components/list/router/1">Router <code>/router/1</code></md-list-item>
12+
<md-list-item to="/components/list/router/2">Router <code>/router/2</code></md-list-item>
913
</md-list>
1014
</div>
1115
</template>
@@ -29,4 +33,8 @@ export default {
2933
vertical-align: top;
3034
border: 1px solid rgba(#000, .12);
3135
}
36+
37+
.md-list .router-link-active {
38+
text-shadow: 0 0 5px;
39+
}
3240
</style>

docs/app/pages/Components/Steppers/examples/StepperRoute.vue

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<div>
33
<md-steppers md-sync-route md-dynamic-height>
4-
<md-step id="first" to="/components/steppers/first" md-label="First Step">
4+
<md-step id="first" to="/components/steppers" exact md-label="First Step">
55
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias doloribus eveniet quaerat modi cumque quos sed, temporibus nemo eius amet aliquid, illo minus blanditiis tempore, dolores voluptas dolore placeat nulla.</p>
66
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias doloribus eveniet quaerat modi cumque quos sed, temporibus nemo eius amet aliquid, illo minus blanditiis tempore, dolores voluptas dolore placeat nulla.</p>
77
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias doloribus eveniet quaerat modi cumque quos sed, temporibus nemo eius amet aliquid, illo minus blanditiis tempore, dolores voluptas dolore placeat nulla.</p>
@@ -12,13 +12,21 @@
1212
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias doloribus eveniet quaerat modi cumque quos sed, temporibus nemo eius amet aliquid, illo minus blanditiis tempore, dolores voluptas dolore placeat nulla.</p>
1313
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias doloribus eveniet quaerat modi cumque quos sed, temporibus nemo eius amet aliquid, illo minus blanditiis tempore, dolores voluptas dolore placeat nulla.</p>
1414
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias doloribus eveniet quaerat modi cumque quos sed, temporibus nemo eius amet aliquid, illo minus blanditiis tempore, dolores voluptas dolore placeat nulla.</p>
15+
<md-list>
16+
<md-list-item to="/components/steppers/second/sub1">Subpage 1</md-list-item>
17+
<md-list-item to="/components/steppers/second/sub2">Subpage 2</md-list-item>
18+
</md-list>
1519
</md-step>
1620

1721
<md-step id="third" to="/components/steppers/third" md-label="Third Step">
1822
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias doloribus eveniet quaerat modi cumque quos sed, temporibus nemo eius amet aliquid, illo minus blanditiis tempore, dolores voluptas dolore placeat nulla.</p>
1923
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias doloribus eveniet quaerat modi cumque quos sed, temporibus nemo eius amet aliquid, illo minus blanditiis tempore, dolores voluptas dolore placeat nulla.</p>
2024
</md-step>
2125
</md-steppers>
26+
<md-list>
27+
<md-list-item to="/components/steppers/second/sub1">Subpage 2-1</md-list-item>
28+
<md-list-item to="/components/steppers/second/sub2">Subpage 2-2</md-list-item>
29+
</md-list>
2230
</div>
2331
</template>
2432

docs/app/pages/Components/Tabs/examples/TabContent.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<div>
33
<md-tabs md-sync-route>
4-
<md-tab id="tab-home" md-label="Home" to="/components/tabs/home">
4+
<md-tab id="tab-home" md-label="Home" to="/components/tabs" exact>
55
Home Tab
66
</md-tab>
77

Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
<template>
22
<div>
33
<md-tabs md-sync-route>
4-
<md-tab id="tab-home" md-label="Home" to="/components/tabs/home"></md-tab>
5-
<md-tab id="tab-pages" md-label="Pages" to="/components/tabs/pages"></md-tab>
4+
<md-tab id="tab-home" md-label="Home" to="/components/tabs" exact></md-tab>
5+
<md-tab id="tab-pages" md-label="Pages" to="/components/tabs/pages">
6+
<md-list>
7+
<md-list-item to="/components/tabs/pages/1">Go to Subpage 1</md-list-item>
8+
<md-list-item to="/components/tabs/pages/2">Go to Subpage 2</md-list-item>
9+
</md-list>
10+
</md-tab>
611
<md-tab id="tab-posts" md-label="Posts" to="/components/tabs/posts"></md-tab>
7-
<md-tab id="tab-settings" md-label="Settings" to="/components/tabs/settings"></md-tab>
12+
<md-tab id="tab-favorites" md-label="Favorites" to="/components/tabs/favorites"></md-tab>
813
<md-tab id="tab-disabled" md-label="Disabled" md-disabled></md-tab>
914
</md-tabs>
15+
<h2>Mirror Subpage</h2>
16+
<md-tabs md-sync-route>
17+
<md-tab id="tab-pages-1" md-label="Pages 1" to="/components/tabs/pages/1">Subpage 1</md-tab>
18+
<md-tab id="tab-pages-2" md-label="Pages 2" to="/components/tabs/pages/2">Subpage 2</md-tab>
19+
</md-tabs>
1020
</div>
1121
</template>
1222

@@ -15,3 +25,9 @@
1525
name: 'TabRouter'
1626
}
1727
</script>
28+
29+
<style lang="scss" scoped>
30+
.md-tabs /deep/ .md-tabs-navigation .md-button.router-link-active {
31+
text-shadow: 0 0 5px;
32+
}
33+
</style>

docs/app/pages/WithRouter.vue

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<template>
2+
<page-container centered :title="$t('pages.withRouter.title')">
3+
<div class="page-container-section">
4+
<h2 class="md-headline">Vue Material Router Link Components</h2>
5+
<p>Vue router supported with <code><router-link to="/components/tabs">md-tab</router-link></code>, <code><router-link to="/components/list">md-list-item</router-link></code>, <code><router-link to="/components/bottom-bar">md-bottom-bar-item</router-link></code> and <code><router-link to="/components/steppers">md-step</router-link></code> so far.</p>
6+
<p>Vue Material router link components will be auto-generated with the prop <code>to</code>. All <a href="https://router.vuejs.org/en/api/router-link.html"><code>router-link</code> props</a> except <code>tag</code> accepted.</p>
7+
<h2 class="md-headline">Work with Router option <code>linkActiveClass</code></h2>
8+
<p>Since Vue Router doesn't expose <code>isSameRoute</code> and <code>isIncludedRoute</code> methods, Vue Material cannot detect which links are active. Vue Material inject <code>linkActiveClass</code> with an extra active class to interact with router. Therefore, if you want to using an custom class for active link as default, you need to setup like this:</p>
9+
<code-example title="Individual components">
10+
const linkActiveClass = 'my-link-active-class'
11+
12+
// pass custom class to Vue Material
13+
Vue.material.router.linkActiveClass = linkActiveClass
14+
15+
// pass custom class to Vue Router
16+
router = new VueRouter({
17+
routes,
18+
linkActiveClass
19+
})
20+
21+
const app = new Vue({
22+
name: 'Root',
23+
router,
24+
})
25+
26+
</code-example>
27+
</div>
28+
</page-container>
29+
</template>
30+
31+
<script>
32+
export default {
33+
name: 'WithRouter'
34+
}
35+
</script>

docs/app/routes.js

+10-5
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export const routes = [
4545
page: 'Components/Datepicker/Datepicker.vue'
4646
},
4747
{
48-
path: '/components/steppers/:optional?',
48+
path: '/components/steppers/:optional?/:sub?',
4949
name: 'components/steppers',
5050
page: 'Components/Steppers/Steppers.vue'
5151
},
@@ -70,12 +70,12 @@ export const routes = [
7070
page: 'Components/Snackbar/Snackbar.vue'
7171
},
7272
{
73-
path: '/components/tabs/:optional?',
73+
path: '/components/tabs/:optional?/:sub?',
7474
name: 'components/tabs',
7575
page: 'Components/Tabs/Tabs.vue'
7676
},
7777
{
78-
path: '/components/bottom-bar/:optional?',
78+
path: '/components/bottom-bar/:optional?/:sub?',
7979
name: 'components/bottom-bar',
8080
page: 'Components/BottomBar/BottomBar.vue'
8181
},
@@ -207,7 +207,7 @@ export const routes = [
207207
page: 'Components/File/File.vue'
208208
},
209209
{
210-
path: '/components/list/:optional?',
210+
path: '/components/list/:optional?/:sub?',
211211
name: 'components/list',
212212
page: 'Components/List/List.vue'
213213
},
@@ -262,6 +262,11 @@ export const routes = [
262262
name: 'ui-elements/typography',
263263
page: 'UiElements/Typography/Typography.vue'
264264
},
265+
{
266+
path: '/with-router',
267+
name: 'with-router',
268+
page: 'WithRouter.vue'
269+
},
265270
{
266271
path: '*',
267272
name: 'error',
@@ -274,7 +279,7 @@ export const mapRoutes = () => {
274279

275280
routes.forEach(route => {
276281
if (!route.redirect && route.path !== '*') {
277-
mappedRoutes.push(route.path.replace('/:optional?', ''))
282+
mappedRoutes.push(route.path.replace('/:optional?/:sub?', ''))
278283
}
279284
})
280285

docs/app/template/MainNavContent.vue

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
<router-link to="/themes/advanced">{{ $t('pages.themeAdvanced.nav') }}</router-link>
1515
</div>
1616

17+
<router-link to="/with-router">{{ $t('pages.withRouter.title') }}</router-link>
18+
1719
<router-link to="/ui-elements">{{ $t('pages.uiElements.title') }}</router-link>
1820
<div class="main-nav-level">
1921
<router-link to="/ui-elements/elevation">{{ $t('pages.elevation.title') }}</router-link>

src/components/MdBottomBar/MdBottomBar.vue

+13-50
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,16 @@
2525
...MdPropValidator('md-type', ['fixed', 'shift'])
2626
}
2727
},
28-
data: () => ({
29-
MdBottomBar: {
30-
mouseEvent: null,
31-
activeItem: null,
32-
items: {}
28+
data () {
29+
return {
30+
MdBottomBar: {
31+
mouseEvent: null,
32+
activeItem: null,
33+
items: {},
34+
syncRoute: this.mdSyncRoute
35+
}
3336
}
34-
}),
37+
},
3538
provide () {
3639
return {
3740
MdBottomBar: this.MdBottomBar
@@ -50,21 +53,12 @@
5053
watch: {
5154
activeItem () {
5255
this.$emit('md-changed', this.activeItem)
56+
},
57+
mdSyncRoute () {
58+
this.MdBottomBar.syncRoute = mdSyncRoute
5359
}
5460
},
5561
methods: {
56-
setupWatchers () {
57-
if (this.mdSyncRoute) {
58-
this.$watch('$route', {
59-
deep: true,
60-
handler () {
61-
if (this.mdSyncRoute) {
62-
this.setActiveItemByRoute()
63-
}
64-
}
65-
})
66-
}
67-
},
6862
hasActiveItem () {
6963
return this.MdBottomBar.activeItem || this.mdActiveItem
7064
},
@@ -84,47 +78,16 @@
8478
} else {
8579
this.MdBottomBar.activeItem = this.mdActiveItem
8680
}
87-
},
88-
setActiveItemByRoute () {
89-
const { items, keys } = this.getItemsAndKeys()
90-
let tabIndex = null
91-
92-
if (this.$router) {
93-
keys.forEach((key, index) => {
94-
const item = items[key]
95-
const toProp = item.props.to
96-
97-
if (toProp && toProp === this.$route.path) {
98-
tabIndex = index
99-
}
100-
})
101-
}
102-
103-
if (!this.hasActiveItem()) {
104-
if (keys[tabIndex]) {
105-
this.MdBottomBar.activeItem = keys[tabIndex]
106-
} else {
107-
this.MdBottomBar.activeItem = keys[0]
108-
}
109-
} else if (keys[tabIndex]) {
110-
this.MdBottomBar.activeItem = keys[tabIndex]
111-
}
11281
}
11382
},
11483
created () {
11584
this.MdBottomBar.type = this.mdType
11685
},
11786
mounted () {
11887
this.$nextTick().then(() => {
119-
if (this.mdSyncRoute) {
120-
this.setActiveItemByRoute()
121-
} else {
88+
if (!this.mdSyncRoute) {
12289
this.setActiveItemByIndex(0)
12390
}
124-
125-
window.setTimeout(() => {
126-
this.setupWatchers()
127-
}, 100)
12891
})
12992
13093
}

src/components/MdBottomBar/MdBottomBarItem.vue

+5-3
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,20 @@
2020

2121
<script>
2222
import MdAssetIcon from 'core/mixins/MdAssetIcon/MdAssetIcon'
23+
import MdRouterLink from 'core/mixins/MdRouterLink/MdRouterLink'
2324
import MdUuid from 'core/utils/MdUuid'
2425
import MdRouterLinkProps from 'core/utils/MdRouterLinkProps'
2526
2627
const ignoredProps = ['id', 'mdLabel', 'mdIcon', 'mdDisabled']
2728
2829
export default {
2930
name: 'MdBottomBarItem',
30-
mixins: [MdAssetIcon],
31+
mixins: [MdAssetIcon, MdRouterLink],
3132
props: {
3233
id: {
3334
type: String,
3435
default: () => 'md-bottom-bar-item-' + MdUuid()
3536
},
36-
to: null,
3737
mdLabel: String,
3838
mdIcon: String,
3939
mdDisabled: Boolean
@@ -101,7 +101,9 @@
101101
})
102102
},
103103
setActiveItem ($event) {
104-
this.MdBottomBar.activeItem = this.id
104+
if (!this.MdBottomBar.syncRoute) {
105+
this.MdBottomBar.activeItem = this.id
106+
}
105107
106108
if (this.MdBottomBar.type === 'shift') {
107109
this.MdBottomBar.mouseEvent = $event

0 commit comments

Comments
 (0)