【问题标题】:Bootstrap Popover Content not Reactive Vue2Bootstrap Popover 内容不响应 Vue2
【发布时间】:2021-08-30 17:57:57
【问题描述】:

我正在尝试在 Vue 中使用 Bootstrap4 为弹出框创建一个组件:

<template>
    <div>
        <div :id="uid + '_Content'" class="d-none">
            <slot name="content">

            </slot>
        </div>
        <div :class="'call' + uid">
            <slot name="caller">

            </slot>
        </div>
    </div>
</template>

<script>
module.exports = {
    data() {
        return {
            uid: this.genUID()
        }
    }, 
    props: {
        title: {
            type: String,
            required: false,
            default: ''
        }
    },
    mounted() {
        _this = this;
        // PopOver Definition
        const popover = new bootstrap.Popover(document.querySelector('.call' + this.uid), {
            container: 'body',
            title: this.title,
            html: true,
            placement: 'auto',
            sanitize: false,
            customClass: 'noselect',
            content: () => {
                return document.querySelector("#" + _this.uid + "_Content").innerHTML;
            }
        });
    },
    methods: {
        genUID() {
            return "Popover_" + Math.random().toString(16).slice(2);
        }
    }
}
</script>

但是,当从另一个组件向&lt;slot name="content"&gt; 传递内容时,数据不是反应性的。我是否缺少任何配置信息以使其具有反应性?使用 Vue 和(常规)Bootstrap(notBootstrap-Vue)是否可以做到这一点。

【问题讨论】:

    标签: vue.js bootstrap-4 vuejs2


    【解决方案1】:

    您正在失去反应性,因为 bootstrap.Popovercontent 选项正在返回元素的 HTML 字符串,而不是元素本身。弹出框只是复制打开时存在的 HTML。如果您传递元素,Bootstrap 会将元素本身重新设置为弹出框,因此应该反映对元素子项的更改。 (请注意,这仍然可能会被重写元素本身的虚拟 DOM 更改所破坏,这就是为什么 Bootstrap-Vue 在这里仍然会更好。)如果可以重用弹出框,您需要将元素重新设置为您的每次弹出窗口关闭时组件自己的树。您还需要将 _Content 元素设置为仅在未重新设置父级时隐藏。

    这就是它的样子:

    <template>
        <div ref="container" class="Popover__Container">
            <div ref="content" class="Popover__Content">
                <slot name="content">
    
                </slot>
            </div>
            <div ref="caller" class="Popover__Caller">
                <slot name="caller">
    
                </slot>
            </div>
        </div>
    </template>
    
    <script>
    module.exports = {
        props: {
            title: {
                type: String,
                required: false,
                default: ''
            }
        },
        mounted() {
            const content = this.$refs.content;
            // PopOver Definition
            const popover = new bootstrap.Popover(this.$refs.caller, {
                container: 'body',
                title: this.title,
                html: true,
                placement: 'auto',
                sanitize: false,
                customClass: 'noselect',
                content: content
            });
            $(this.$refs.caller).on('hidden.bs.popover', () =>
            {
              this.$refs.container.prepend(content);
            });
        }
    }
    </script>
    
    <style scoped>
    .Popover__Container > .Popover__Content {
        display: none;
    }
    </style>
    

    (我还用 refs 替换了 UID 方法,因为那是一种更像 Vue 的方法。)

    【讨论】:

    • 我认为它与 .innerHTML 有关,但我不知道如何修复它。你说的一切都很有道理,而且效果很好。谢谢!
    • 但是,当关闭弹窗时,它无法重新打开。有什么建议? (错误:“Uncaught TypeError: Cannot read property '0' of null”).. 看起来它将 Popover_XXX_Content 移过来但从不返回。
    • 啊,是的,看起来 Bootstrap 不适合你。我已经编辑了我的答案,以便在关闭弹出窗口时将内容重新添加到您的组件中。我还将代码扩展为原始代码的完整副本,并将 UID 位替换为 Vue refs。
    • 太棒了,谢谢!正如您所知道的,看起来(在转换到 refs 时) caller.on 是不必要的。
    猜你喜欢
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    相关资源
    最近更新 更多