1. 點擊出現下劃線的問題
// tabs-item.vue
methods: {
xxx() {
this.eventBus.$emit('update:selected', this.name, this)
}
}
// tabs.vue
mounted(){
this.eventBus.$emit('update:selected', this.selected)
}
// tabs-head
created(){
this.eventBus.$on('update:selected', (item, vm) => {
console.log(item)
console.log(vm) // 初始化的時候打印出的值爲undefined
})
}
// 爲了解決初始化打印出爲undefined的問題
// tabs.vue 通過兩層循環解決找到item
mounted(){
this.$children.forEach((vm)=>{
if(vm.$options.name === 'GuluTabsHead'){ // 找兒子
vm.$children.forEach((childVm)=>{ // 找孫子
if(childVm.$options.name === 'GuluTabsItem' && childVm.name === this.selected){
this.eventBus.$emit('update:selected', this.selected,childVm)
}
})
}
})
}
2. 找到item之後開始做動畫
mounted(){
this.eventBus.$on('update:selected', (item, vm) => {
let {width, height, top, left} = vm.$el.getBoundingClientRect()
this.$refs.line.style.width = `${width}px` // 寬度就會跟着我們點的元素的寬度變,
// this.$refs.line.style.left = `${left}px` // 寬度變了我們再修改位置
this.$refs.line.style.transform = `translateX(${left}px)`
// 可以這樣優化寫來實現硬件3d加速
// 但是這樣寫有個bug一開始會從左往右滑
})
}
3. 嘗試解決一開始從走往右滑動的bug
// tabs-head.vue
<template>
<div class="tabs-head">
<slot></slot>
<div class="line" ref="line" v-if="x"></div>
</div>
</div>
</template>
data(){
return {
x: false
}
},
mounted(){
this.eventBus.$on('update:selected', (item, vm) => {
this.x = true
// 新增一個[更新UI任務]到任務隊列裏面,
// 會先把下面js執行完了再更新,所以 this.$refs.line.style.width會報錯
// 我們只要把代碼放到[更新UI任務]的後面就能解決
this.$nextTick(()=>{
// 新增一個函數,放到任務隊列裏面,由於[更新UI任務]是先放進去那麼就會先執行
// 但是這樣做還是沒解決從左往右滑的bug,所以還是改回left
let {width, height, top, left} = vm.$el.getBoundingClientRect()
this.$refs.line.style.width = `${width}px`
this.$refs.line.style.transform = `translateX(${left}px)`
})
})
}
4.增加禁用功能和禁用樣式
// 增加disabled樣式
computed: {
classes() { // classes是一個計算屬性
return {
active: this.active,
disabled: this.disabled,
}
}
},
// 增加disabled行爲
methods: {
onClick() {
if (this.disabled) {
return
}
this.eventBus.$emit('update:selected', this.name, this)
}
}
最後,歡迎交流!