demo-block.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <template>
  2. <div
  3. class="demo-block"
  4. :class="[blockClass, { 'hover': hovering }]"
  5. @mouseenter="hovering = true"
  6. @mouseleave="hovering = false">
  7. <slot></slot>
  8. <div class="demo-block-control" @click="isExpanded = !isExpanded">
  9. <i :class="iconClass"></i>
  10. <span v-show="hovering">{{ controlText }}</span>
  11. </div>
  12. </div>
  13. </template>
  14. <style>
  15. .demo-block {
  16. border: solid 1px #eaeefb;
  17. border-radius: 4px;
  18. transition: .2s;
  19. &.hover {
  20. box-shadow: 0 0 8px 0 rgba(232, 237, 250, .6), 0 2px 4px 0 rgba(232, 237, 250, .5);
  21. }
  22. code {
  23. font-family: Menlo, Monaco, Consolas, Courier, monospace;
  24. }
  25. .source {
  26. padding: 24px;
  27. }
  28. .meta {
  29. background-color: #f9fafc;
  30. border-top: solid 1px #eaeefb;
  31. clear: both;
  32. overflow: hidden;
  33. height: 0;
  34. transition: height .2s;
  35. }
  36. .description {
  37. padding: 18px 24px;
  38. width: 40%;
  39. box-sizing: border-box;
  40. border-left: solid 1px #eaeefb;
  41. float: right;
  42. font-size: 14px;
  43. line-height: 1.8;
  44. color: #5e6d82;
  45. word-break: break-word;
  46. p {
  47. margin: 0;
  48. }
  49. code {
  50. color: #5e6d82;
  51. background-color: #e6effb;
  52. margin: 0 4px;
  53. padding: 4px 8px;
  54. font-size: 12px;
  55. }
  56. }
  57. .highlight {
  58. width: 60%;
  59. border-right: solid 1px #eaeefb;
  60. pre {
  61. margin: 0;
  62. }
  63. code.hljs {
  64. font-size: 12px;
  65. padding: 18px 24px;
  66. margin: 0;
  67. line-height: 1.8;
  68. background-color: #f9fafc;
  69. border: none;
  70. max-height: none;
  71. border-radius: 0;
  72. &::before {
  73. content: none;
  74. }
  75. }
  76. }
  77. .demo-block-control {
  78. border-top: solid 1px #eaeefb;
  79. height: 36px;
  80. box-sizing: border-box;
  81. background-color: #fff;
  82. border-bottom-left-radius: 4px;
  83. border-bottom-right-radius: 4px;
  84. text-align: center;
  85. margin-top: -1px;
  86. color: #d3dce6;
  87. cursor: pointer;
  88. transition: .2s;
  89. i {
  90. font-size: 12px;
  91. line-height: 36px;
  92. }
  93. span {
  94. font-size: 14px;
  95. line-height: 36px;
  96. }
  97. &:hover {
  98. color: #20a0ff;
  99. background-color: #f9fafc;
  100. }
  101. }
  102. }
  103. </style>
  104. <script type="text/babel">
  105. export default {
  106. data() {
  107. return {
  108. hovering: false,
  109. isExpanded: false
  110. };
  111. },
  112. computed: {
  113. blockClass() {
  114. return `demo-${ this.$router.currentRoute.path.split('/').pop() }`;
  115. },
  116. iconClass() {
  117. return this.isExpanded ? 'el-icon-caret-top' : 'el-icon-caret-bottom';
  118. },
  119. controlText() {
  120. return this.isExpanded ? '隐藏代码' : '显示代码';
  121. },
  122. codeArea() {
  123. return this.$el.getElementsByClassName('meta')[0];
  124. },
  125. codeAreaHeight() {
  126. if (this.$el.getElementsByClassName('description').length > 0) {
  127. return Math.max(this.$el.getElementsByClassName('description')[0].clientHeight, this.$el.getElementsByClassName('highlight')[0].clientHeight);
  128. }
  129. return this.$el.getElementsByClassName('highlight')[0].clientHeight;
  130. }
  131. },
  132. watch: {
  133. isExpanded(val) {
  134. this.codeArea.style.height = val ? `${ this.codeAreaHeight + 1 }px` : '0';
  135. }
  136. },
  137. mounted() {
  138. this.$nextTick(() => {
  139. let highlight = this.$el.getElementsByClassName('highlight')[0];
  140. if (this.$el.getElementsByClassName('description').length === 0) {
  141. highlight.style.width = '100%';
  142. highlight.borderRight = 'none';
  143. }
  144. });
  145. }
  146. };
  147. </script>