Commit caa7ba030ad86973b7f846fe8539a9c3af38f066

Authored by Aaron
1 parent 15c8e131
Exists in master and in 1 other branch legacy

组件布局增加右侧锚点导航

examples/views/docs/detail.md
@@ -56,7 +56,7 @@ export default { @@ -56,7 +56,7 @@ export default {
56 56
57 --- 57 ---
58 58
59 -1231 59 +## API
60 60
61 ## Attribute 属性 61 ## Attribute 属性
62 62
examples/views/docs/form.md
@@ -108,6 +108,8 @@ export default { @@ -108,6 +108,8 @@ export default {
108 108
109 ::: 109 :::
110 110
  111 +## API
  112 +
111 ## Attribute 属性 113 ## Attribute 属性
112 114
113 参数|说明|类型|可选值|默认值 115 参数|说明|类型|可选值|默认值
examples/views/docs/scheme.md
@@ -85,6 +85,8 @@ export default { @@ -85,6 +85,8 @@ export default {
85 85
86 ::: 86 :::
87 87
  88 +## API
  89 +
88 ## Attribute 属性 90 ## Attribute 属性
89 91
90 参数|说明|类型|可选值|默认值 92 参数|说明|类型|可选值|默认值
examples/views/docs/search.md
@@ -100,6 +100,8 @@ export default { @@ -100,6 +100,8 @@ export default {
100 100
101 ::: 101 :::
102 102
  103 +## API
  104 +
103 ## Attribute 属性 105 ## Attribute 属性
104 106
105 参数|说明|类型|可选值|默认值 107 参数|说明|类型|可选值|默认值
examples/views/docs/select.md
@@ -63,6 +63,8 @@ export default { @@ -63,6 +63,8 @@ export default {
63 63
64 ::: 64 :::
65 65
  66 +## API
  67 +
66 ## Attribute 属性 68 ## Attribute 属性
67 69
68 参数|说明|类型|可选值|默认值 70 参数|说明|类型|可选值|默认值
examples/views/docs/table.md
@@ -121,6 +121,7 @@ export default { @@ -121,6 +121,7 @@ export default {
121 121
122 ::: 122 :::
123 123
  124 +## API
124 125
125 ## Attribute 属性 126 ## Attribute 属性
126 127
examples/views/layout/component.vue
1 <template> 1 <template>
2 - <div id="app">  
3 - <el-container>  
4 - <layout-header></layout-header>  
5 - <el-container class="layout-container__component">  
6 - <el-aside class="layout-aside__component" width="200px">  
7 - <el-menu :default-active="activeMenu" class="layout-aside-menu__component" @select="handleSelect">  
8 - <h4 style="padding: 0 20px;">组件</h4>  
9 - <el-menu-item-group v-for="(component, idx) in components" :key="idx">  
10 - <template slot="title">{{ component.group }}</template>  
11 - <el-menu-item v-for="(data, index) in component.children" :key="index" :index="data.name">{{ data.meta.title }}</el-menu-item>  
12 - </el-menu-item-group>  
13 - </el-menu>  
14 - </el-aside>  
15 - <el-main class="layout-main__component">  
16 - <router-view></router-view>  
17 - </el-main>  
18 - </el-container> 2 + <el-container>
  3 + <layout-header></layout-header>
  4 + <el-container class="layout-container__component">
  5 + <el-aside class="layout-aside__component" width="200px">
  6 + <el-menu :default-active="activeMenu" class="layout-aside-menu__component" @select="handleSelect">
  7 + <h4 style="padding: 0 20px;">组件</h4>
  8 + <el-menu-item-group v-for="(component, idx) in componentList" :key="idx">
  9 + <template slot="title">{{ component.group }}</template>
  10 + <el-menu-item v-for="(data, index) in component.children" :key="index" :index="data.name">{{ data.meta.title }}</el-menu-item>
  11 + </el-menu-item-group>
  12 + </el-menu>
  13 + </el-aside>
  14 + <a class="target-fix"></a>
  15 + <el-main class="layout-main__component">
  16 + <router-view></router-view>
  17 + </el-main>
  18 + <el-aside class="layout-aside__preview" width="200px">
  19 + <a class="anchor" :class="{ 'active': item.hash === currentAnchor }" v-for="(item, index) in anchorList" :key="index" :href="item.hash">{{ item.text }}</a>
  20 + </el-aside>
19 </el-container> 21 </el-container>
20 - </div> 22 + </el-container>
21 </template> 23 </template>
22 24
23 <script> 25 <script>
@@ -30,14 +32,74 @@ export default { @@ -30,14 +32,74 @@ export default {
30 data() { 32 data() {
31 return { 33 return {
32 activeMenu: 'select', 34 activeMenu: 'select',
33 - components 35 + componentList: components,
  36 + anchorList: [],
  37 + currentAnchor: '',
34 } 38 }
35 }, 39 },
36 created() { 40 created() {
37 const { name } = this.$route || {}; 41 const { name } = this.$route || {};
38 this.activeMenu = name; 42 this.activeMenu = name;
39 }, 43 },
  44 + mounted() {
  45 + this.initAnchorList();
  46 + window.onscroll = ((e) => {
  47 + if (!this.isBottom()) {
  48 + for (let index in this.anchorList) {
  49 + let anchor = this.anchorList[index] || {};
  50 + if (window.pageYOffset <= anchor.offsetTop - 65) {
  51 + this.currentAnchor = (anchor || this.anchorList[0]).hash;
  52 + break;
  53 + }
  54 + }
  55 + }
  56 + });
  57 + },
  58 + watch:{
  59 + $route(to, from) {
  60 + this.currentAnchor = to.hash;
  61 + if (to.path !== from.path) {
  62 + this.$nextTick(this.initAnchorList);
  63 + }
  64 + if (!this.isBottom()) {
  65 + setTimeout(() => {
  66 + window.scrollBy(0, -65);
  67 + }, 1);
  68 + }
  69 + }
  70 + },
40 methods: { 71 methods: {
  72 + isBottom() {
  73 + // 变量scrollTop是滚动条滚动时,距离顶部的距离
  74 + const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  75 + // 变量windowHeight是可视区的高度
  76 + const windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
  77 + // 变量scrollHeight是滚动条的总高度
  78 + const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
  79 + // 滚动条到底部的条件
  80 + return scrollTop + windowHeight === scrollHeight;
  81 + },
  82 + initAnchorList() {
  83 + this.anchorList = [];
  84 + const domList = document.querySelectorAll('.header-anchor');
  85 + let anchorList = [];
  86 + for (let index in domList) {
  87 + let dom = domList[index] || {};
  88 + const text = `${dom.parentNode.innerHTML}`.replace(/<\/?.*[^>]*>/g, '').trim();
  89 + if (text === 'API') {
  90 + break;
  91 + } else {
  92 + anchorList.push({
  93 + text: `${dom.parentNode.innerHTML}`.replace(/<\/?.*[^>]*>/g, '').trim(),
  94 + href: dom.href,
  95 + hash: dom.hash,
  96 + offsetTop: dom.offsetTop,
  97 + });
  98 + }
  99 + }
  100 + this.anchorList = anchorList;
  101 + this.currentAnchor = anchorList[0].hash;
  102 + },
41 handleSelect(key) { 103 handleSelect(key) {
42 this.$router.push({ name: key }); 104 this.$router.push({ name: key });
43 } 105 }
@@ -61,6 +123,7 @@ export default { @@ -61,6 +123,7 @@ export default {
61 height: 90%; 123 height: 90%;
62 border-right: 1px solid #e6e6e6; 124 border-right: 1px solid #e6e6e6;
63 } 125 }
  126 + left: 0;
64 position: fixed; 127 position: fixed;
65 height: calc(100vh - 60px); 128 height: calc(100vh - 60px);
66 background: #fff; 129 background: #fff;
@@ -80,8 +143,30 @@ export default { @@ -80,8 +143,30 @@ export default {
80 border-right: 0; 143 border-right: 0;
81 } 144 }
82 } 145 }
  146 + .layout-aside__preview {
  147 + position: fixed;
  148 + right: 0;
  149 + height: calc(100vh - 60px);
  150 + width: 150px !important;
  151 + padding: 30px 0;
  152 + .anchor {
  153 + width: 100%;
  154 + display: inline-block;
  155 + font-size: 12px;
  156 + text-decoration: none;
  157 + padding: 5px 20px;
  158 + color: $text;
  159 + transition: all 300ms;
  160 + border-left: 1px solid $border;
  161 + }
  162 + .active {
  163 + color: $primary;
  164 + border-left: 1px solid $primary;
  165 + }
  166 + }
83 .layout-main__component { 167 .layout-main__component {
84 margin-left: 200px; 168 margin-left: 200px;
  169 + margin-right: 150px;
85 padding: 20px 40px; 170 padding: 20px 40px;
86 } 171 }
87 } 172 }
examples/views/layout/default.vue
1 <template> 1 <template>
2 - <div id="app">  
3 - <el-container>  
4 - <layout-header></layout-header>  
5 - <el-container class="layout-container__default">  
6 - <router-view></router-view>  
7 - </el-container> 2 + <el-container>
  3 + <layout-header></layout-header>
  4 + <el-container class="layout-container__default">
  5 + <router-view></router-view>
8 </el-container> 6 </el-container>
9 - </div> 7 + </el-container>
10 </template> 8 </template>
11 9
12 <script> 10 <script>