el-input触发 el-popover银行弹窗封装

样式:主要是使用  el-popover和el-tabs

html:由于业务需求,我所使用的是input作为触发组件,所以在在触发条件这里要使用自定义trigger="manual"

<el-popover :ref="obj.display_field"
:key="index"     
placement="bottom"         
 width="500"                                                
size="medium"                                               
trigger="manual"                                              
 @show="afterEnter"                                               
:popper-options="{ boundariesElement: '.el-form', removeOnDestroy: true }">
                                            <el-input v-model="basic[obj.display_field+'CN']" size="medium"
                                                      readonly="true"
                                                      :placeholder="'请选择'+obj.field_name"
                                                      slot="reference"
                                                      @focus="iptFocus(obj.display_field)"
                                                      :title="basic[obj.display_field]">
                                                <template slot="">
                                                    <span>{{basic[obj.display_field+index]}}</span>
                                                </template>
                                            </el-input>
                                            <template>
                                                <el-tabs v-model="selectBank" class="select_bank_list" v-if="isShow">
                                                    <el-tab-pane label="常用" name="tab1">
                                                        <el-row>
                                                            <el-col v-for="(item) in commonBanks" :span="7"
                                                                    style="padding: 5px">
                                                                <a :class="'BK'+ item.def_bankcode"
                                                                   class="bankIcon"></a>
                                                                <el-link @click="getbank(item,obj,index)">
                                                                    <span v-if="item.simp_name!='中国银行'">中国</span>{{item.simp_name}}
                                                                </el-link>
                                                            </el-col>
                                                        </el-row>
                                                    </el-tab-pane>
                                                    <el-tab-pane :label="item" v-for="(item) in bankCapitalName"
                                                    >
                                                        <el-row v-for="(v,k) in otherBanks[item]">
                                                            <el-row :span="1">{{k}}</el-row>
                                                            <el-row style="padding: 5px">
                                                                <el-col v-for="b in v" :span="8">
                                                                    <el-link @click.native="getbank(b,obj,index)" :title="b.simp_name">
                                                                       <span style="display:inline-block;max-width: 150px; overflow: hidden; white-space: nowrap;text-overflow: ellipsis;">
                                                                            {{b.simp_name}}
                                                                       </span>
                                                                    </el-link>
                                                                </el-col>
                                                            </el-row>
                                                        </el-row>
                                                    </el-tab-pane>
                                                </el-tabs>
                                            </template>
                                        </el-popover>

数据格式:一般的json格式

数据处理:

//data :   数据            
isShow: false,          //选择银行
                // visible: false,
                selectBank: 'tab1',//某人选择的tab
                commonBanks: [],//常用银行
                otherBanks: {},//其他银行
                bankCapitalName: ['ABCDEF', 'GHJK', 'LMNPQRS', 'TWXYZ'],


//methods:数据处理
  this.banks = resp.objectMap.banks || [];
                    this.commonBanks = []

                    this.otherBanks = []
                    this.banks.forEach(item => {
                        if (item.is_hot == 1) {
                            this.commonBanks.push(item)
                        } else {
                            let bankStr = item.simp_code != undefined ? item.simp_code.split('') : [];
                            this.bankCapitalName.forEach(i => {
                                this.otherBanks[i] = {...this.otherBanks[i]}
                                if (i.indexOf(bankStr[0]) != -1) {
                                    if (this.otherBanks[i][bankStr[0]] === undefined)
                                        this.otherBanks[i][bankStr[0]] = []
                                    this.otherBanks[i][bankStr[0]].push(item)
                                }
                            })
                        }
                    })
    

点击空白关掉弹窗:为了做成el-select的效果,单击空白时弹出框会关闭的效果,我写了一个全局的点击事件监听器,当点击的dom不是弹出框的内容区域就调取的el-popover的关闭函数,然后使用ref拿到弹出框的dom,这里要注意,如果是通过for循环生成的弹出框,ref拿到的会是一个数组,并且想要使用contains函数,一定要是dom节点,这里就突出了ref 和 id的不同了。ref拿到的是节点对象,而id拿到的直接就是dom节点。所以要想使用contains函数,我们需要拿到ref的el属性,进行判断。

 mounted() {
            document.addEventListener("click", this.bodyCloseMenus);
        },
        beforeDestroy() {
            document.removeEventListener('click', this.bodyCloseMenus);
        },
        methods: {
            bodyCloseMenus(event) {
              
                    let that = this
                    if (that.$refs['a8'][0]) {
                        let el = (that.$refs['a8'][0].$el == 'undefined' ? '' : that.$refs['a8'][0].$el)
                        if (!el.contains(event.target)) {
                            this.$refs['account_bank'][0].doClose()
                        }
                    }
                    if (that.$refs['a10'][0]) {
                        let el = that.$refs['a10'][0].$el == 'undefined' ? '' : that.$refs['a10'][0].$el
                        if (!el.contains(event.target)) {
                            this.$refs['account_bank2'][0].doClose()
                        }
                    }
                    if (that.$refs['a12'][0]) {
                        let el = that.$refs['a12'][0].$el == 'undefined' ? '' : that.$refs['a12'][0].$el
                        if (!el.contains(event.target)) {
                            this.$refs['account_bank3'][0].doClose()
                        }
                    }
                
            },
}

可能会遇到的问题:el-tabs刚打开默认的第一个选项下滑线显示不完整。如下图:

 原因:是因为该功能是由两个组件同时使用的,也就是el-popover嵌套着el-tabs。出现上述的问题主要原因是因为外层的el-popover的节点未加载完成,el-tabs组件就开始渲染了。

解决方法:

使用el-popover的after-enter方法,在该方法中在让el-tabs进行节点的渲染。el-tab可以使用v-if控制一下。