admin管理员组

文章数量:1271756

I have two Vue ponents, 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?

I have two Vue ponents, 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?

Share Improve this question edited Jul 14, 2022 at 0:59 tony19 139k23 gold badges277 silver badges347 bronze badges asked Aug 14, 2017 at 17:43 balpingbalping 8,0283 gold badges27 silver badges36 bronze badges 2
  • Do you just want to remove all properties from the object that is being extended? – Bert Commented Aug 14, 2017 at 18:12
  • No, only specific ones – balping Commented Aug 14, 2017 at 18:21
Add a ment  | 

3 Answers 3

Reset to default 9

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');
    },
}

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 ponent.

Don't know why you need it. But you could also do it like following:

  • With Object.assign:

    extends: Object.assign({}, pA, {
        props: {
            value4: Object
        }
    }),
    
  • With spread-operator ...pA:

    extends: { 
        ...pA,
        props: {
            value4: Object
        }
    }
    

Please have a look at the demo below or this fiddle.

const pA = {
  name: 'CompA',
  template: `
  	<div>
    <h2>{{$options.name}}</h2>
    props: <br/> 
    <span v-if="$options.name === 'CompA'">1 - {{value1}}<br/></span>
    <span v-if="$options.name === 'CompB'">4 - {{value4}}<br/></span>
    {{value2}}<br/>
    {{value3}}
    </div>
  `,
  props: {
    value1: Object,
  },

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

const pB = {
  name: 'CompB',
  extends: Object.assign({}, pA, {
    props: {
      value4: Object
    }
  }),

  /*
  // with spread operator
  { 
  	...pA,
  	props: {
    	value4: Object
    }
  },*/
  data: function() {
    return {
      value2: 'hello2 from B'
    }
  }
}

console.log('no prop value1', pB)

new Vue({
  el: '#app',
  ponents: {
    pA,
    pB
  }
})
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.4.2/vue.js"></script>
<div id="app">
  <p-a :value1="{id: 2}">
  </p-a>
  <p-b :value1="{id: 4}" :value4="{id: 9}">
  </p-b>
</div>

本文标签: javascriptVueJS extend component remove parent39s propertyStack Overflow