开发一个UI框架项目[8]-Collapse

本文最后更新于:2020年10月15日 晚上

设计细节

  1. 展示模式。默认可以同时展示多个折叠面板,也可以通过设置single属性来开启手风琴模式,即每次只能展示一个折叠面板。
  2. 控制打开与关闭采用单向数据流。关于折叠面板的开关控制方式,在多次试错后,决定采用单向数据流的方式:新建一个事件总线eventBus,点击折叠面板后,该子组件不直接操控自身的开启或关闭,而是通过eventBus去通知父组件,然后由父组件进行某些逻辑处理后,再通过eventBus向子组件传递事件,子组件收到事件后,再判断是开启还是关闭。

功能细节

  1. 绑定值的使用。这里的绑定值会加上.sync修饰符,然后在collapse组件里通过提交update:selected事件来更新绑定值:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <script>
    export default {
    mounted() {
    // 处理值的逻辑
    // ...
    this.$emit('update:selected', this.selectedArray)
    }
    }
    </script>
  2. 处理选中值。区分手风琴多面板展示两种模式:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <script>
    export default {
    mounted() {
    // 一开始就广播事件
    this.eventBus.$emit('update:selected', this.selected)
    // 监听添加选中事件
    this.eventBus.$on('update:addSelected', (name) => {
    // 对selected做深拷贝处理
    this.selectedArray = JSON.parse(JSON.stringify(this.selected))
    if (this.single) {
    this.selectedArray = [name]
    } else {
    this.selectedArray.push(name)
    }
    // 通过eventBus广播事件,子组件监听该事件
    this.eventBus.$emit('update:selected', this.selectedArray)
    // 上面第1点讲到的,更新selected值
    this.$emit('update:selected', this.selectedArray)
    })
    }
    }
    </script>

    判断single值是否为真,为真则将name值设置为数组的唯一值,否则将name值push进数组。

  3. 移除非选中值。无需区分模式:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <script>
    export default {
    mounted() {
    // 一开始就广播事件
    this.eventBus.$emit('update:selected', this.selected)
    // 监听添加选中事件
    // ...

    // 监听选中移除事件
    this.eventBus.$on('update:removeSelected', (name) => {
    this.selectedArray = JSON.parse(JSON.stringify(this.selected))
    // 找到当前移除值的索引值
    let index = this.selectedArray.indexOf(name)
    // 移除
    this.selectedArray.splice(index, 1)
    // 通过eventBus广播事件,子组件监听该事件
    this.eventBus.$emit('update:selected', this.selectedArray)
    // 上面第1点讲到的,更新selected值
    this.$emit('update:selected', this.selectedArray)
    })
    }
    }
    </script>
  4. 处理子组件点击事件。设计细节里面有说到,子组件点击时,不直接处理自身的开启/关闭事件,而是通过eventBus广播addSelectedremoveSelected事件,而父组件监听事件并做逻辑处理(第2、3点)后再广播update:selected事件,子组件监听事件拿到选中的值后判断是否有自己,有则打开。这样就完成了一个单向数据流。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <script>
    export default {
    mounted() {
    // 监听事件 看选中的值中是否有自己 有则打开
    this.eventBus && this.eventBus.$on('update:selected', (names) => {
    this.open = names.indexOf(this.name) >= 0
    })
    },
    methods: {
    toggle() {
    if (this.open) {
    this.eventBus && this.eventBus.$emit('update:removeSelected', this.name)
    } else {
    this.eventBus && this.eventBus.$emit('update:addSelected', this.name)
    }
    }
    }
    }
    </script>

vuepress配置

docs/.vuepress/components文件夹下增加collapse-basiccollapse-singlevue文件,内容就是我们要展示的collapse示例,然后在docs/components文件夹下增加collapse的md文件,内容就是放置整个collapse组件说明。

具体内容请访问这里