简体   繁体   English

VueJS 扩展组件:删除父级的属性

[英]VueJS extend component: remove parent's property

I have two Vue components, one extends the other:我有两个 Vue 组件,一个扩展另一个:

// 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:文档中所述,CompB 的选项被合并到 CompA 中,结果是:

{
    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:但是我想要的结果是删除了属性value1

{
    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.但即使我返回nullundefined ,该属性也不会被删除。

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

Is it even possible to such thing?甚至有可能这样的事情吗? If yes, how?如果是,如何?

This is my own solution that finally worked for me: delete the property manually in beforeCreate() .这是我自己的最终对我有用的解决方案:在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.我不太清楚Vue.config.optionMergeStrategies是如何工作的,但这确实在测试环境中工作。

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.本质上,在扩展组件之前删除不需要的道具。

Don't know why you need it.不知道你为什么需要它。 But you could also do it like following:但你也可以这样做:

  • With Object.assign :使用Object.assign

     extends: Object.assign({}, compA, { props: { value4: Object } }),
  • With spread-operator ...compA :使用扩展运算符...compA

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

Please have a look at the demo below or this fiddle .请看下面的演示或这个小提琴

 const compA = { 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 compB = { name: 'CompB', extends: Object.assign({}, compA, { props: { value4: Object } }), /* // with spread operator { ...compA, props: { value4: Object } },*/ data: function() { return { value2: 'hello2 from B' } } } console.log('no prop value1', compB) new Vue({ el: '#app', components: { compA, compB } })
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script> <div id="app"> <comp-a :value1="{id: 2}"> </comp-a> <comp-b :value1="{id: 4}" :value4="{id: 9}"> </comp-b> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM