iview级联选择组件源码阅读笔记
组件划分
cascader组件共划分成了三个组件:
- cascader.vue
- caspanel.vue
- casitem.vue
其中,cascader是最外层的组件,包括一个slot和caspanel。slot内部默认是一个input框。
caspanel则是弹出的面板,里面包括若干个casitem选项,和一个子caspanel面板(如果有)。
casitem则是简单的选项组件,存放选项。
DOM结构
大致的DOM结构如下:
1 | <Cascader> |
逻辑思路
在页面渲染时,通过computed中的querySelections方法对data进行遍历修改,添加__label __value属性
在点击slot中的内容时,调用toggleOpen方法,修改visible属性控制Caspanel的显隐:
1 | //以下三个函数用于控制this.visible,由此控制panel的显隐 |
然后在watch中监听visible属性的变化,当input中有值时,更新面板的内容,使面板展示选中的项:
1 | visible (val) { |
1 | updateSelected (init = false) { |
在updateSelected中,会广播on-find-selected事件,在处理该事件的函数中,还会触发on-clear事件,将Caspanel的子面板都清空,然后再渲染新的子面板(展示选中的项),并设置选中的value。
当用户点击最后要选择的选项时,Caspanel组件会调用一个方法先改变父组件Cascader的this.tmpSelected,然后触发on-result-change事件,驱使父组件更新this.selected和this.currentValue,从而更新DOM。
疑惑:
在Caspanel组件中,使用了this.$parent来调用父组件Cascader的方法,甚至用到了this.$parent.$parent,在其他组件中有看到直接通过this.$parent修改父组件中的属性值,不知这种方式与通过事件来通知父组件从而改变父组件中的属性,哪种更合适一些。
1 | emitUpdate (result) { |