23

Vue には、ウィンドウ サイズに合わせてスケーリングされたフレームであるコンポーネントがあり、フレームに合わせてスケーリングされ、その要素のパンとズームを有効に <slot>する要素 (通常は<img>または) が含まれています。<canvas>

コンポーネントは、要素が変更されたときに反応する必要があります。<slot>これを実行する唯一の方法は、親がコンポーネントをプロデュースすることですが、要素が変更されたときにコンポーネントが自動的に検出し、それに応じて反応できるようになれば、はるかに優れたものになります。これを行う方法はありますか?

4

4 に答える 4

17

私が Vue 2+ を理解している限り、スロットのコンテンツが変更されたときにコンポーネントを再レンダリングする必要があります。私の場合、error-message表示するスロット コンテンツが表示されるまで非表示にするコンポーネントがありました。最初に、このメソッドをv-ifコンポーネントのルート要素にアタッチしました (computedプロパティは機能しません。Vue には反応性がないようthis.$slotsです)。

checkForSlotContent() {
    let checkForContent = (hasContent, node) => {
        return hasContent || node.tag || (node.text && node.text.trim());
    }
    return this.$slots.default && this.$slots.default.reduce(checkForContent, false);
},

これは、DOM 要素の追加または削除を含め、99% の変更がスロットで発生する場合はいつでもうまく機能します。唯一のエッジケースは、次のような使用法でした:

<error-message> {{someErrorStringVariable}} </error-message>

ここで更新されているのはテキスト ノードのみです。理由はまだ不明ですが、メソッドは起動しません。beforeUpdate()このケースをandにフックして修正created()し、完全な解決策としてこれを残しました。

<script>
    export default {
        data() {
            return {
                hasSlotContent: false,
            }
        },
        methods: {
            checkForSlotContent() {
                let checkForContent = (hasContent, node) => {
                    return hasContent || node.tag || (node.text && node.text.trim());
                }
                return this.$slots.default && this.$slots.default.reduce(checkForContent, false);
            },
        },
        beforeUpdate() {
            this.hasSlotContent = this.checkForSlotContent();
        },
        created() {
            this.hasSlotContent = this.checkForSlotContent();
        }
    };
</script>
于 2019-04-19T14:23:51.413 に答える