本次需求:
实现每次点击折叠面板重新拿到高度
// 效果如下图:
所用框架:
antd+vue
难点:
- 折叠面板点击之后,直接调用获取高度的方法,高度是滞后的,每次拿到的都是点击之前的高度;
- 递归组件子向父传值,如果利用之前的 e m i t , emit, emit,on传值,子组件里又同时包含子和父,无法使用
解决办法:
- 高度滞后,设置一个定时器
- 使用eventBus传值
核心代码:
1. 在src目录下新加bus.js作为一个公共的实例
import Vue from 'vue'
export var bus = new Vue()
2. 父组件在created里面定义$on监听事件
import {bus} from '../../bus.js'
created() {
bus.$on( 'getH', (res) => {
this.getHeight()
})
}
3. 在子组件中定义点击事件,调用父组件方法通过$emit将相应值传给父组件
import {bus} from '../../bus.js'
methods: {
changeActive () {
bus.$emit('getH', true)
}
}
完整代码:
bus.js:
import Vue from 'vue'
export var bus = new Vue()
父组件:
<template>
<div ref="colH">
<a-row :gutter="24">
<a-col :md="24">
<a-card title="递归实验">
<a-steps :current="current">
<a-step v-for="(item, index) in dataSteps" :key="index" :title="item.name">
<template slot="description" class="des-style">
<div v-if="item.children.length === 0">
{{ item.name }}
div>
<div v-if="item.children.length > 0">
<a-collapse :bordered="false" @change="changeFatherH">
<a-collapse-panel>
<template slot="header">
{{ item.name }}
template>
<RecursionCom :children="item.children">RecursionCom>
a-collapse-panel>
a-collapse>
div>
template>
a-step>
a-steps>
a-card>
a-col>
a-row>
div>
template>
<script>
import RecursionCom from '@/components/RecursionCom'
import {bus} from '../../bus.js'
export default {
name: 'DraggableTest',
components: { RecursionCom },
data () {
return {
current: 1,
dataSteps: [
{
id: 'as',
name: 'Amy',
age: 12,
children: [
{
id: 'aqs',
name: 'Amy1',
age: 11,
children: []
},
{
id: 'aqsq',
name: 'Amy2',
age: 10,
children: [
{
id: 'aqs1',
name: 'Amy22',
age: 17,
children: []
},
{
id: 'aqs2',
name: 'Amy23',
age: 10,
children: []
}
]
},
{
id: 'sq',
name: 'Amy3',
age: 13,
children: []
}
]
},
{
id: 'bs',
name: 'Bill',
age: 18,
children: [
{
id: 'bs1',
name: 'Bill1',
age: 17,
children: []
},
{
id: 'bs2',
name: 'Bill2',
age: 10,
children: []
}
]
},
{
id: 'cs',
name: 'Claire',
age: 34,
children: [
{
id: 'cs1',
name: 'Claire1',
age: 14,
children: []
},
{
id: 'cs2',
name: 'Claire2',
age: 45,
children: [
{
id: 'cs22',
name: 'Claire22',
age: 14,
children: []
},
{
id: 'cs23',
name: 'Claire23',
age: 14,
children: [
{
id: 'cs233',
name: 'Claire233',
age: 19,
children: []
},
{
id: 'cs234',
name: 'Claire234',
age: 10,
children: []
}
]
}
]
}
]
},
{
id: 'a5s',
name: 'Damon',
age: 12,
children: [
{
id: 'dd3',
name: 'Damon1',
age: 11,
children: []
},
{
id: 'e4',
name: 'Damon2',
age: 10,
children: [
{
id: '3e',
name: 'Damon22',
age: 17,
children: []
},
{
id: 'r4',
name: 'Damon23',
age: 10,
children: []
}
]
},
{
id: 't5',
name: 'Damon3',
age: 13,
children: []
}
]
}
]
}
},
created() {
bus.$on( 'getH', (res) => {
this.getHeight()
})
},
methods: {
changeFatherH () {
this.getHeight()
},
getHeight () {
const _this = this
setTimeout(() => {
console.log('height:' + _this.$refs.colH.offsetHeight)
}, 500)
}
}
}
script>
<style>
.ant-card-body .ant-steps-horizontal .ant-steps-item-description {
max-width: 225px;
min-width: 223px;
}
.ant-collapse-item {
border-bottom: none;
}
style>
递归子组件:
在components文件夹里新建一个文件夹:RecursionCom
新建RecursionCom.vue
代码如下:
<template>
<ul style="padding-left: 20px;" class="des1-style">
<li v-for="(item, index) in children" :key="index">
{{ item.name }}
<div v-if="item.children.length > 0">
<a-collapse :bordered="false" @change="changeActive">
<a-collapse-panel>
<template slot="header">
{{ item.name }}
template>
<RecursionCom :children="item.children">RecursionCom>
a-collapse-panel>
a-collapse>
div>
li>
ul>
template>
<script>
import {bus} from '../../bus.js'
export default {
name: 'RecursionCom',
props: {
children: {
type: Array,
default: () => {
return []
}
}
},
methods: {
changeActive () {
bus.$emit('getH', true)
}
}
}
script>
<style scoped>
.ant-card-body .ant-steps-horizontal .ant-steps-item-description {
max-width: 225px;
min-width: 223px;
}
.ant-collapse-item {
border-bottom: none;
}
style>
RecursionCom文件夹里新建index.js
代码如下:
import RecursionCom from './RecursionCom'
export default RecursionCom
参考:
Vue 实现的递归组件如何向外传递事件和数据
vue递归组件如何传递事件给父组件