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

时间:2017-08-14 17:43:04

标签: javascript merge vue.js vuejs2 vue-component

我有两个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'
        }
    }
}

正如in the docs所述,CompB的选项已合并到CompA中,从而产生:

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

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

但是我想要的结果是删除了属性value1

{
    props: {
        value4: Object
    },

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

我认为应该可以使用Custom Option Merge Strategies

但即使我退回nullundefined,该财产也不会被删除。

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

这样的事情甚至可能吗?如果是,怎么样?

3 个答案:

答案 0 :(得分:4)

这是我自己的解决方案,最终对我有用:在beforeCreate()中手动删除属性。

这与伯特的答案非常相似。

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

答案 1 :(得分:2)

我不太清楚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'
        }
    }
}

基本上,在扩展组件之前删除不需要的道具。

答案 2 :(得分:1)

不知道为什么需要它。 但你也可以这样做:

  • 使用Object.assign

    extends: Object.assign({}, compA, {
        props: {
            value4: Object
        }
    }),
    
  • 使用spread-operator ...compA

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

请查看下面的演示或此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
  }
})
&#13;
<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>
&#13;
&#13;
&#13;