Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

trigger reflow manually #15

Open
joernroeder opened this issue Dec 20, 2018 · 1 comment
Open

trigger reflow manually #15

joernroeder opened this issue Dec 20, 2018 · 1 comment

Comments

@joernroeder
Copy link

sometimes i'm having nested components inside a "Smooth Component" and one of them is toggling a value in it's internal state and the component inside the <slot /> never gets updated directly (which is actually fine). Is there a function (maybe a function returned from $smoothReflow()) which i can invoke manually to check and trigger a reflow?
thx

@guanzo
Copy link
Owner

guanzo commented Dec 20, 2018

That could work. There needs to be at least 2 functions, 1 to save the element's attribute values before a data update, and 1 to trigger the reflow after a data update.

Problem is the Smooth Component still needs to know when to call these functions, and only the child component knows when it's updated (thru the beforeUpdate and updated hooks). The child would need to hook into those events and emit the events to the parent. I'm looking for a way to do this automatically, and not force the user (you) to manually emit beforeUpdate and updated events to the Smooth Component.

According to this SO answer, you can dynamically add a lifecycle listener. Based on that, something like this should work (untested).

// SmoothReflow.vue
<template>
    <component :is="tag">
        <slot/>
    </component>
</template>

<script>
import smoothReflow from 'vue-smooth-reflow'
export default {
    name: 'SmoothReflow',
    mixins: [smoothReflow],
    props: {
        tag: {
            type: String,
            default: 'div'
        },
        selfUpdate: {
            type: Boolean,
            default: false
        },
        options: Object,
    },
    mounted () {
        const reflow = this.$smoothReflow(this.options)
        if (this.selfUpdate) {
            // Add lifecycle hooks to children
            this.$slots.default.forEach(vNode => {
                this.addUpdateHookListeners(vNode.componentInstance, reflow)
            });
        }
    },
    methods: {
        addUpdateHookListeners (component, reflow) {
            const { $options } = component
            if (!$options.beforeUpdate) {
                $options.beforeUpdate = [];
            }
            $options.beforeUpdate.push(() => reflow.save())
            if (!$options.updated) {
                $options.updated = [];
            }
            $options.updated.push(() => reflow.trigger())
        }
    }
}
</script>

// Component using the Smooth Component

<template>
    <SmoothReflow selfUpdate>
        <div v-for="n in children"/>
    </SmoothReflow>
</template>

I'll look into this, and if it works, I'll most likely export a SmoothReflow component from the vue-smooth-reflow module.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants