1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| <template> <div class="slide-btn" ref="wrap" :style="{minWidth}"> <div class="btns"> <button v-for="(e, i) in options" :key="e + i" :ref="`btn${i}`" @click="changeCur(i)">{{ e }}</button> </div> <div class="slide" :style="{width: slideWidth + 'px', left: slideLeft + 'px', background: slideBgColor}"></div> </div> </template> <script>
export default { props: { options: { type: Array, default: () => [] }, slideBgColor: { type: String, default: '#1A5493' } }, data () { return { slideWidth: 0, slideLeft: 0, current: 0, minWidth: 0 } },
watch: { current (val, old) { if (val !== old) { this.getSlideWidth() } }, options: { handler (val, old) { this.getMinWidth() }, deep: true } }, mounted () { this.getSlideWidth() this.getMinWidth() }, methods: { getMinWidth() { this.$nextTick(() => { let w = 0 this.options.forEach((e, i) => { const styles = this.$refs[`btn${i}`][0].getBoundingClientRect() w += styles.width }) this.minWidth = w + 'px' }) }, getSlideWidth () { this.$nextTick(() => { const wrapStyles = this.$refs.wrap.getBoundingClientRect() const styles = this.$refs[`btn${this.current}`][0].getBoundingClientRect() this.slideWidth = styles.width this.slideLeft = styles.left - wrapStyles.left }) }, changeCur(idx) { this.current = idx this.$emit('click', idx) } } } </script>
<style scoped> .slide-btn { box-sizing: border-box; display: flex; flex-wrap: nowrap; align-items: center; position: relative; width: fit-content; border: 1px solid #118899; border-radius: 20px; height: 32px; padding: 3px 3px 3px 1px; background: #121212; } .btns { box-sizing: border-box; position: relative; z-index: 1; display: flex; flex-wrap: nowrap; align-items: center; } .slide { box-sizing: border-box; position: absolute; height: 100%; border-radius: 20px; transition: all .3s; height: 26px; } button { box-sizing: border-box; border: none; outline: none; color: #fff; background: none; padding: 0 15px; cursor: pointer; font-size: 12px; white-space: nowrap; } </style>
|