Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
119 lines (102 sloc) 2.89 KB

do_action in Vue.js

Vue.js design pattern to mimic WordPress' do_action

This example is based on the file structure of wePOS plugin.

Bootstrap.js

// Added at the bottom of Bootstrap.js
// wepos.hooks comes from the @wordpress/hooks package 

wepos.addFilter = (hookName, namespace, component, priority = 10) => {
    wepos.hooks.addFilter(hookName, namespace, (components) => {
        components.push(component);
        return components;
    }, priority );
};

Anyfile.js

// This snippets must be included AFTER Bootstrap.js and BEFORE rendering Home.vue.
// For example this could be in frontend/main.js

import HomeSampleListOne from 'frontend/components/HomeSampleListOne.vue';
import HomeSampleListTwo from 'frontend/components/HomeSampleListTwo.vue';
import HomeBeforeItemsWrapper from 'frontend/components/HomeBeforeItemsWrapper.vue';

// the follwing `weposHomeSampleList` and `weposHomeBeforeItemsWrapper` hooknames are
// used in $data properties in Home.vue
wepos.addFilter('weposHomeSampleList', 'weposHome', HomeSampleListOne);
wepos.addFilter('weposHomeSampleList', 'weposHome', HomeSampleListTwo, 9); // Two will render before One
wepos.addFilter('weposHomeBeforeItemsWrapper', 'weposHome', HomeBeforeItemsWrapper);

Home.vue

<template>
    <div id="wepos-main" v-cloak v-hotkey="hotkeys">
        ...
        <ul>
            <li>One</li>
            <li>Two</li>
            <li>Three</li>

            <component
                v-for="(component, index) in sampleLists"
                :key="index"
                :is="component"
            />
        </ul>        

        <component
            v-for="(component, index) in beforeItemsWrapper"
            :key="index"
            :is="component"
            :products="getFilteredProduct"
        />        
        ...
    </div>
</template>

<scripts>
    export default {
        ...
        data() {
            return {
                // Add an empty array so that, by default Vue has nothing to render
                sampleLists: wepos.hooks.applyFilters( 'weposHomeSampleList', [] ),
                beforeItemsWrapper: wepos.hooks.applyFilters( 'weposHomeBeforeItemsWrapper', [] ),
            };
        },
        ...
    };
</scripts>

HomeSampleListOne.vue

<template>
    <li>From HomeSampleListOne.vue</li>
</template>

<script>
    export default {};
</script>

HomeSampleListTwo.vue

<template>
    <li>From HomeSampleListTwo.vue</li>
</template>

<script>
    export default {};
</script>

HomeBeforeItemsWrapper.vue

<template>
    <div>
        component with div wrapper root
        <pre>{{ products }}</pre>
    </div>
</template>

<script>
    export default {
        props: {
            products: {
                type: Array,
                required: true
            }
        }
    };
</script>
You can’t perform that action at this time.