index.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <script>
  2. import LinearText from "../LinearText";
  3. export default {
  4. name: "ButtonBlock",
  5. components: {
  6. LinearText,
  7. },
  8. props: {
  9. items: {
  10. type: Array,
  11. default: () => ["本日", "本周", "本月"],
  12. },
  13. valueField: {
  14. type: String,
  15. default: "",
  16. },
  17. defaultIndex: {
  18. type: Number,
  19. default: 0,
  20. },
  21. },
  22. data() {
  23. return {
  24. currentItemIndex: 0,
  25. height: 0,
  26. width: 0,
  27. };
  28. },
  29. emits: ["select-item"],
  30. created() {
  31. this.currentItemIndex = this.defaultIndex;
  32. },
  33. computed: {
  34. buttonBlockStyle() {
  35. return {
  36. "--height": `${this.height}px`,
  37. "--width": `${this.width}px`,
  38. };
  39. },
  40. },
  41. mounted() {
  42. const dom = this.$refs.buttonBlock;
  43. this.height = dom.clientHeight;
  44. this.width = dom.clientWidth;
  45. },
  46. methods: {
  47. /**
  48. * 渲染当前节点的颜色
  49. * @param {*} index 当前选项索引
  50. * @param {*} color 选择时的颜色
  51. */
  52. renderCurrentItemColor(index, color) {
  53. return this.currentItemIndex === index ? color : `${color}88`;
  54. },
  55. /**
  56. * 渲染文本内容
  57. * @param {*} item 节点数据
  58. */
  59. renderText(item) {
  60. if (this.valueField === "") {
  61. return item;
  62. } else {
  63. return item[this.valueField];
  64. }
  65. },
  66. /**
  67. * 点击节点处理器
  68. * @param {*} index 当前点击的选项索引
  69. */
  70. onClickBlockItemHandler(index) {
  71. this.currentItemIndex = index;
  72. this.$emit("select-item", index);
  73. },
  74. },
  75. };
  76. </script>
  77. <template>
  78. <div class="button-block" ref="buttonBlock" :style="buttonBlockStyle">
  79. <div class="button-block_item" v-for="(item, index) in items"
  80. @click="onClickBlockItemHandler(index)" :key="index">
  81. <linear-text
  82. :text="renderText(item)"
  83. :startColor="renderCurrentItemColor(index, '#95CCFF')"
  84. :endColor="renderCurrentItemColor(index, '#FFFFFF')"
  85. fontSize="16px"
  86. :ext-class="{
  87. textShadow: `0 1px 1px ${renderCurrentItemColor(index, '#0057FF')}`,
  88. }"
  89. />
  90. </div>
  91. </div>
  92. </template>
  93. <style scoped lang="less">
  94. .button-block {
  95. display: flex;
  96. position: relative;
  97. border-radius: 5px;
  98. box-sizing: border-box;
  99. background: linear-gradient(360deg, #0094ff90 0%, #0094ff10 100%);
  100. .button-block_item {
  101. padding: 0px 8.5px 0px 8.5px;
  102. cursor: pointer;
  103. }
  104. &::after {
  105. content: "";
  106. position: absolute;
  107. top: 0px;
  108. left: 0px;
  109. padding: 1px;
  110. box-sizing: border-box;
  111. border-radius: 5px;
  112. width: var(--width);
  113. height: var(--height);
  114. background: linear-gradient(360deg, rgba(0, 163, 255, 0) 0%, #0c5a87 100%);
  115. /* 随便定义颜色 */
  116. --mask-bg: linear-gradient(red, red);
  117. --m-o: content-box, padding-box;
  118. /* mask允许使用者通过遮罩或者裁切特定区域的图片的方式来隐藏一个元素的部分或者全部可见区域 */
  119. /* 设置了用作元素蒙版层的图像,默认值为none,值为透明图片,或透明渐变 */
  120. -webkit-mask-image: var(--mask-bg), var(--mask-bg);
  121. /* 默认值为border-box,可选值与background-origin相同 */
  122. -webkit-mask-origin: var(--m-o);
  123. /* 默认值为border-box,可选值与background-clip相同 */
  124. -webkit-mask-clip: var(--m-o);
  125. /* exclude排除,只显示不重合的地方,Firefox支持4个属性 */
  126. mask-composite: exclude;
  127. /*只显示下方遮罩,重合的地方不显示*/
  128. -webkit-mask-composite: destination-out;
  129. pointer-events: none;
  130. }
  131. }
  132. </style>