Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VueJS extend component: remove parent's property

I have two Vue components, one extends the other:

// CompA.vue

export default {
    props: {
        value1: Object,
    },

    data: function () {
        return {
            value2: 'hello2 from A',
            value3: 'hello3 from A'
        }
    }
}

// CompB.vue

import CompA from './CompA.vue';

export default {
    extends: CompA,

    props: {
        value4: Object
    },

    data: function(){
        return {
            value2: 'hello2 from B'
        }
    }
}

As described in the docs, CompB's options are merged into CompA's, resulting:

{
    props: {
        value1: Object,
        value4: Object
    },

    data: function () {
        return {
            value2: 'hello2 from B',
            value3: 'hello3 from A'
        }
    }
}

However my desired result is having property value1 removed:

{
    props: {
        value4: Object
    },

    data: function () {
        return {
            value2: 'hello2 from B',
            value3: 'hello3 from A'
        }
    }
}

I think it should be possible using Custom Option Merge Strategies

But even if I return null or undefined, the property isn't removed.

Vue.config.optionMergeStrategies.data = function(parentVal, childVal) {
    return null;
};

Is it even possible to such thing? If yes, how?

like image 706
balping Avatar asked Jan 04 '23 14:01

balping


2 Answers

This is my own solution that finally worked for me: delete the property manually in beforeCreate().

This is very similar to Bert's answer.

// CompB.vue

import CompA from './CompA.vue';

export default {
    extends: CompA,

    props: {
        value4: Object
    },

    data: function(){
        return {
            value2: 'hello2 from B'
        }
    },

    beforeCreate: function(){
        Vue.delete(this.$options.props, 'value1');
    },
}
like image 165
balping Avatar answered Jan 06 '23 04:01

balping


It's not quite clear to me how Vue.config.optionMergeStrategies works but this does work in a test environment.

import CompA from './CompA.vue';
// make a deep clone copy of CompA. Here I'm just using a made up copy
// function but you could use lodash or some other library. Do NOT use
// JSON.parse(JSON.stringify(...)) because you will lose functions. Also
// Object.assign will not work because Object.assign performs a shallow
// copy (meaning if you delete from props, which is a nested object, you
// will still globally delete the property).
import copy from "./utils" 
//copy CompA
let newCompA = copy(CompA)    
// delete the desired props
delete newCompA.props.value1

export default {
    // extend the copy
    extends: newCompA,

    props: {
        value4: Object
    },

    data: function(){
        return {
            value2: 'hello2 from B'
        }
    }
}

Essentially, delete the props you do not want before you extend the component.

like image 40
Bert Avatar answered Jan 06 '23 05:01

Bert