vue 手风琴组件_Vue造轮子-手风琴组件

一. 大致的使用方法

内容1

内容2

内容3

二. 完成最外部的样式

//collapse

$grey: #ddd;

$border-radius: 4px;

.collapse {

border: 1px solid $grey;

border-radius: $border-radius;

}

//collapse-item.vue

$grey: #ddd;

$border-radius: 4px;

.collapseItem {

> .title {

border: 1px solid $grey;

margin-top: -1px;

margin-left: -1px;

margin-right: -1px;

}

&:first-child {

> .title {

border-top-left-radius: $border-radius;

border-top-right-radius: $border-radius;

}

}

}

三. 进一步调节样式

// collapse-item

$grey: #ddd;

$border-radius: 4px;

.collapseItem {

> .title {

border: 1px solid $grey;

margin-top: -1px;

margin-left: -1px;

margin-right: -1px;

min-height: 32px;

display: flex;

align-items: center;

padding: 0 8px;

}

&:first-child {

> .title {

border-top-left-radius: $border-radius;

border-top-right-radius: $border-radius;

}

}

> .content{

padding: 8px;

}

}

四. 默认内容折叠起来和点击切换,基本样式和基本功能完成

// collapse-item

data (){

return {

open: false

}

}

五. 完善功能第一个点开,第二个就关闭

因为结构比较简单,就父子两个组件,可以用父子通信来做。

mounted(){

this.eventBus.$on('update:selected', (vm)=>{

if (vm !== this){

this.close()

}

})

},

methods:{

toggle(){

if(this.open) {

this.open = false

}else{

this.open = true

this.eventBus.$emit('update:selected', this)

}

},

close(){

this.close()

}

}

六. 增加功能是否可以选择多个

方案一.用 single 变量是否需要控制 eventBus

// 添加single选项,有single就注入,没有就不注入

// 但是这种方式不太完美会有警告

props: {

single: {

type: Boolean,

default: false

}

},

provide() {

if(this.single){

return {

eventBus: this.eventBus

}

}

}

七. 可以设置默认 selected

// index.html

内容1

内容2

内容3

// collapse-item.vue

mounted(){

this.eventBus && this.eventBus.$on('update:selected', (name)=>{

if (name !== this.name){

this.close()

}else{

this.show()

}

})

},

八. 回头解决子元素是否可以多个打开

通过 collapse.vue 传给 collapse-item

// index.js

内容1 Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus consequatur

内容2 Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquid cupiditate dolore d!

内容3 Lorem ipsum dolor sit amet, consectetur adipisicing elit. Excepturi, magnam.

{{selectedTab}}

// collapse.vue

mounted(){

this.eventBus.$emit('update:selected',this.selected)

this.eventBus.$on('update:selected', (name)=>{

this.$emit('update:selected',name)

})

this.$children.forEach((vm)=>{

vm.single = this.single

console.log(vm)

})

}

// collapse-item.vue

mounted(){

this.eventBus && this.eventBus.$on('update:selected', (name)=>{

if (name !== this.name){

if(this.single){

this.close()

}

}else{

this.show()

}

})

},

9.进一步修改,把选中的值改为数组

// collapse.vue

mounted(){

this.eventBus.$emit('update:selected',this.selected)

this.eventBus.$on('update:addSelected', (name)=>{

this.selected.push(name)

this.eventBus.$emit('update:selected',this.selected) // 通知儿子

this.$emit('update:selected',this.selected) // 通知外面

})

this.eventBus.$on('update:removeSelected', (name)=>{

let index = this.selected.indexOf(name)

this.selected.splice(index,1)

this.eventBus.$emit('update:selected',this.selected)

this.$emit('update:selected',this.selected)

})

this.$children.forEach((vm)=>{

vm.single = this.single

console.log(vm)

})

}

// collapse-item.vue

methods:{

toggle(){

if(this.open) {

this.open = false

this.eventBus && this.eventBus.$emit('update:removeSelected', this.name)

// 移除一个被选中的东西

}else{

this.eventBus && this.eventBus.$emit('update:addSelected', this.name)

}

},

}

10. 将所有数据流让父组件统一管理。

不能直接操作 props 要先深拷贝

// collapse.vue

mounted(){

this.eventBus.$emit('update:selected',this.selected)

this.eventBus.$on('update:addSelected', (name)=>{

let selectedCopy = JSON.parse(JSON.stringify(this.selected))

if(this.single){

selectedCopy = [name]

}else{

selectedCopy.push(name)

}

this.eventBus.$emit('update:selected',selectedCopy) // 通知儿子

this.$emit('update:selected',selectedCopy) // 通知外面

})

this.eventBus.$on('update:removeSelected', (name)=>{

let selectedCopy = JSON.parse(JSON.stringify(this.selected))

let index = selectedCopy.indexOf(name)

selectedCopy.splice(index,1)

this.eventBus.$emit('update:selected',selectedCopy)

this.$emit('update:selected',selectedCopy)

})

this.$children.forEach((vm)=>{

vm.single = this.single

console.log(vm)

})

}

11. 数据流的核心

不要出现两个东西互相让对方更新的状态

// collapse.vue 爸爸

mounted(){

this.eventBus.$emit('update:selected',this.selected) // 一开始就通知所有儿子,该选中就选中

this.eventBus.$on('update:addSelected', (name)=>{

let selectedCopy = JSON.parse(JSON.stringify(this.selected))

// 如果用户添加一个我就把selected拷贝一份,因为vue不支持直接修改props

if(this.single){

selectedCopy = [name]

}else{

selectedCopy.push(name)

}

this.eventBus.$emit('update:selected',selectedCopy) // 得到最新被选中的item之后,通知儿子

this.$emit('update:selected',selectedCopy) // 通知外面

})

this.eventBus.$on('update:removeSelected', (name)=>{

let selectedCopy = JSON.parse(JSON.stringify(this.selected))

let index = selectedCopy.indexOf(name)

selectedCopy.splice(index,1)

this.eventBus.$emit('update:selected',selectedCopy) // 如果用户想移除,也通知他儿子该移除就移除

this.$emit('update:selected',selectedCopy)

})

this.$children.forEach((vm)=>{

vm.single = this.single

console.log(vm)

})

// collapse-item.vue 儿子

mounted(){

this.eventBus && this.eventBus.$on('update:selected', (names)=>{

// 监听eventBus,只要他爸爸要说更新,他就更新

console.log(names)

if (names.indexOf(this.name )>= 0){

this.open = true

}else{

this.open = false

}

})

},

methods:{

toggle(){

if(this.open) {

// 这里也没有修改自己的OPEN,而是在mounted中等爸爸通知我们修改open,所以他的open永远是爸爸在操作,儿子不操作

this.eventBus &&this.eventBus.$emit('update:removeSelected', this.name)

// 他自己触发一个意图,打算移除一个更新

// 移除一个被选中的东西

}else{

this.eventBus && this.eventBus.$emit('update:addSelected', this.name)

// 他自己触发一个意图,打算添加一个更新

}

},

}

最后,个人微信,欢迎交流!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值