如何定义vue组件prop结构而不覆盖它

时间:2016-02-20 09:56:13

标签: vue.js

我有多个组件实例,其状态由父级管理,所以我想通过组件上的props传递此状态。 如果我在组件中定义prop的默认对象属性,那么当我将空对象传递给它时它们将被克服。

HTML:

<div id="app">
  <my-component :state="state1"></my-component>
  <my-component :state="state2"></my-component>
  <my-component :state="state3"></my-component>
</div>

JS:

var MyComponent = Vue.extend({
  template: '<pre>{{ state | json }}</pre>',
  props: {
    state: {
        type: Object,
      default: function() {
        return {
          a: null,
          b: [],
          c: {}
        }
      }
    }
  }
})

Vue.component('my-component', MyComponent)

new Vue({
  el: '#app',
  data: {
    state1: {
        a: 1
    },
        state2: {},
        state3: {
        b: 2
    },

  }
})

参见示例:https://jsfiddle.net/pfmfdg8x/2/

那么如何在不定义父级中所有潜在属性的情况下操纵子组件的属性?如果从一开始就不存在该属性,则不会观察到更改。

1 个答案:

答案 0 :(得分:0)

在这个问题的后期,你的小提琴已经完成你所期望的(根据问题)。

我有一个类似的问题,道具不按我的意图工作,想法是使用组件允许用户在几个地方选择某些选择。父进程需要显示值并在发生更改时将其读回。我将组件状态与父prop状态分开,如:

Vue.extend({
    replace: true,
    template: '<span v-for="element in fromComponent"' +
            '<label>' +
                '<input type="checkbox" v-model="element.checked" /> {{ element.label }}' +
            '</label>' +
        '</span>',
    data: function () {
        return {
            fromComponent: [
                { label: 'First', checked: false },
                { label: 'Second', checked: false }
            ],
            busy: false
        };
    },
    props: {
        fromParent: {
            twoWay: true
        }
    },
    watch: {
        fromComponent: {
            handler: 'updateParent',
            deep: true
        },
        fromParent: {
            handler: 'updateComponent',
            deep: true
        }
    },
    methods: {
        updateParent: function () {
            var index, element;

            // Avoid an update loop
            this.busy = true;

            for (index in this.fromComponent) {
                element = this.fromComponent[index];

                // Map the component value to the proper prop value
                this.$set(['fromParent[', index, '].checked'].join(''), !!element.checked);
            }

            this.busy = false;
        },
        updateComponent: function () {
            var index, element;

            if (this.busy) {
                return;
            }

            for (index in this.fromParent) {
                element = this.fromParent[indicator];
                this.$set(['fromComponent[', index, '].checked'].join(''), !!element.checked);
            }
        }
    },
    ready: function () {
        // Set the component data to match the values from the parent
        this.updateComponent();
    }
});