依赖注入
核心思想:让后代组件能够访问到祖先组件的内容。
<el-select v-model="value" placeholder="请选择"><el-optionv-for="item in options":key="item.value":label="item.label":value="item.value"></el-option></el-select>
el-select 中通过 provider 来提供变量,在子孙组件 el-option 中通过 inject 来注入变量
provide() {return {'select': this};}
select 组件直接将自己的实例 this 注入 option 组件,这样 option 组件则可以通过 this.select 来修改父组件属性
inject: ['select']
created() {this.select.options.push(this);}
option 组件的 created 生命周期中,将自己的实例 this 注入到 select 组件的 options 数组中
selectOptionClick() {if (this.disabled !== true && this.groupDisabled !== true) {// emitter.js 文件通过 mixins 传进来方法 dispatchthis.dispatch('ElSelect', 'handleOptionClick', [this, true]);}}
option 组件中通过 dispatch 把点击事件暴露给 select 组件
handleOptionSelect(option, byClick) {if (this.multiple) {const value = (this.value || []).slice();const optionIndex = this.getValueIndex(value, option.value);if (optionIndex > -1) {value.splice(optionIndex, 1);} else if (this.multipleLimit <= 0 || value.length < this.multipleLimit) {value.push(option.value);}this.$emit('input', value);this.emitChange(value);// ...} else {this.$emit('input', option.value);this.emitChange(option.value);this.visible = false;}// ...this.$nextTick(() => {this.scrollToOption(option);});}
在多选还是单选下进行不同的操作。this.$emit('input', value); 中传递改变的值就是 select 中绑定的 v-model 中的值 <el-select v-model="value">。
下拉框的定位
引入了第三方库 popper.js,同时写了个 vue-popper.vue 来控制
