128 lines
2.1 KiB
Vue
128 lines
2.1 KiB
Vue
<template>
|
|
<nav
|
|
v-outside="collapseToc"
|
|
class="one-toc"
|
|
:class="{ expanded }"
|
|
>
|
|
<veui-anchor
|
|
ui="s"
|
|
target-offset="120px"
|
|
:items="flattenItems"
|
|
/>
|
|
<div
|
|
class="toggle"
|
|
@click="toggleToc"
|
|
>
|
|
<veui-icon
|
|
class="collapsed-icon"
|
|
name="list-unordered"
|
|
/>
|
|
</div>
|
|
</nav>
|
|
</template>
|
|
|
|
<script>
|
|
import { Anchor, Icon } from 'veui'
|
|
import outside from 'veui/directives/outside'
|
|
import 'veui-theme-dls-icons/list-unordered'
|
|
|
|
export default {
|
|
name: 'one-toc',
|
|
directives: {
|
|
outside
|
|
},
|
|
components: {
|
|
'veui-anchor': Anchor,
|
|
'veui-icon': Icon
|
|
},
|
|
props: {
|
|
items: {
|
|
type: Array,
|
|
default: () => []
|
|
}
|
|
},
|
|
data () {
|
|
return {
|
|
expanded: false
|
|
}
|
|
},
|
|
computed: {
|
|
flattenItems () {
|
|
return this.items.flatMap(
|
|
({ children }) => (children || []).map(({ children, ...child }) => child) || []
|
|
)
|
|
}
|
|
},
|
|
methods: {
|
|
toggleToc () {
|
|
this.expanded = !this.expanded
|
|
},
|
|
collapseToc () {
|
|
if (this.expanded) {
|
|
this.expanded = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="stylus" scoped>
|
|
.toggle
|
|
display none
|
|
|
|
@media (max-width 480px)
|
|
.one-toc
|
|
background-color #fff
|
|
z-index 20
|
|
top 0
|
|
right 0
|
|
bottom 0
|
|
left auto
|
|
padding 40px 60px 40px 0
|
|
transition transform 0.3s
|
|
transform translateX(100%)
|
|
|
|
&::before
|
|
content ''
|
|
position absolute
|
|
top 0
|
|
bottom 0
|
|
left 0
|
|
width 1px
|
|
background-color #e2e6f0
|
|
|
|
&.expanded
|
|
transform translateX(0)
|
|
|
|
.toggle
|
|
z-index -1
|
|
display flex
|
|
align-items center
|
|
justify-content center
|
|
width 36px
|
|
height 36px
|
|
position absolute
|
|
top 80px
|
|
right 100%
|
|
border 1px solid #e2e6f0
|
|
border-top-left-radius 4px
|
|
border-bottom-left-radius 4px
|
|
background-color #fff
|
|
box-shadow 0 0 12px rgba(0, 0, 0, 0.1)
|
|
font-size 20px
|
|
transition transform 0.3s, opacity 0.3s
|
|
|
|
&::before
|
|
content ""
|
|
position absolute
|
|
top 0
|
|
bottom 0
|
|
right -19px
|
|
width 20px
|
|
background-color #fff
|
|
|
|
&.expanded .toggle
|
|
transform translateX(100%)
|
|
opacity 0
|
|
</style>
|