2

由于el-popover与reference元素是一对一的绑定关系,当一个页面内有多处需要弹出类似的popover框时,如使用现有官方方案,就得每个弹出点都做一个<el-popover>。如果有10个弹出点,就要有10个相同的el-popover。虽然能实现,但对于强迫症来说,实在有点难接受。

当然这里说的都是带指向箭头、自动定位的popover,而不是那种固定位置的。

期望是:一个组件内不管有多少地方需要弹出popover,popover组件也只需要有一个,大家都调用同一个就行了。于是研究了源码,找到一个方案如下:

点击预览效果

然后,可以进一步提取为组件,这样用起来就更方便了:
点击预览效果

<html class="full">
<head>
    <!-- 引入样式 -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <!-- 引入组件库 -->
    <script src="https://unpkg.com/vue@2.6.13/dist/vue.js"></script>
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<style>
    .full { height: 100%;width:100% }
</style>
<body class="full">
    <div id="app">
        <div>
            <popover-svc
                ref="pop1"
                placement="bottom-start"
                width="460">
                <div>当前:{{curObj}}</div>
            </popover-svc>
            <a v-for="(obj,index) in objs" :key="obj" style="cursor:pointer"
            @click="e=> showPop(e, obj)">
                <i class="el-icon-aim aim-icon"></i>
                Pop{{obj}} 
            </a>
        </div>
    </div>
    <script>
        var Popover = ELEMENT.Popover

        //组件方式
        var popoverSvc = {
            extends: Popover,
            methods: {
                popBy(el) {
                    //先隐藏并销毁之前显示的
                    this.close()
                    this.doDestroy(true)
                    this.$nextTick(() => {
                        //显示新的
                        this.referenceElm = this.$refs.reference = el
                        this.showPopper = true
                        this.$emit('input', true)
                    })
                },
                close() {
                    this.showPopper = false
                    this.$emit('input', false)
                }
            },
        }


        new Vue({
            el:'#app',
            data() {
                return {
                    objs: [1,2,3,4,5],
                    curObj: ''
                }
            },
            methods:{
                showPop(e, obj){
                    this.curObj = obj
                    this.$refs.pop1.popBy(e.target)
                }
            },
            components: {
                popoverSvc: popoverSvc
            }
        });
    </script>
</body>
</html>

用下来暂没发现什么副作用,如有问题欢迎指正。


okfine
512 声望29 粉丝

A front-end enthusiast!