使用默认值合并Vue props

时间:2017-02-03 07:44:25

标签: javascript vue.js vue-component

我的Vue组件中有一个选项prop,它有一个默认值。

export default {
  props: {
    options: {
      required: false,
      type: Object,
      default: () => ({
        someOption: false,
        someOtherOption: {
          a: true,
          b: false,
        },
      }),
    },
  },
};

如果将选项对象作为prop传递给组件,则替换默认值。例如,当传递{ someOption: true }时,现在选项对象仅包含该值。

如何传递部分对象并使用给定值覆盖默认值而不是替换整个对象?

2 个答案:

答案 0 :(得分:11)

我最近遇到过类似的问题并使用了Object.assign 以下是来自mozilla https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

的文档

您的案例的具体用法是这样的:

props: {
 options: {
  required: false,
  type: Object,
  default: () => ({}),
 },
},
data(){
  mergedOptions:{},
  defaultOptions:{
    someOption: false,
    someOtherOption: {
      a: true,
      b: false,
    },
  }
},
mounted(){
  //you will have the combined options inside mergedOptions
  Object.assign(this.mergedOptions,this.defaultOptions,this.options)
}

通过执行此操作,您将仅覆盖通过props传递的属性。不知道它是否是最有效的方式,但它是非常容易理解和整洁的:)

因此,如果您作为道具:options={someOption:true}传入,则合并的选项将等同于:

{
 someOption: true,
 someOtherOption: {
  a: true,
  b: false,
 },
}

编辑:如果您需要数据被动,您可能想要计算。

  computed: {
    mergedOptions(){
      return {
       ...this.defaultOptions,
       ...this.options
      }
    }
  }

答案 1 :(得分:2)

您实际上永远不会想要修改组件中的道具。如果这样做,则会破坏父/子组件的单向数据流,并且您的代码很难理解影响内容的因素。

从Vue文档中解除,正确的解决方案是(1)使用初始道具或(2)计算值,因此您的应用程序可以被动反应并尊重父组件,您可以轻松休息并踢你的脚起来:)

两种解决方案都假设您的模板将使用 opts 作为选项......

解决方案1:使用初始道具(默认值和选项):

props: ['options', 'defaults'],
data: function () {
  var opts = {}
  Object.assign(opts, this.defaults, this.options)
  return { 
    opts: opts
  }
}

解决方案2:定义计算属性,以便您的组件可以对道具更改做出反应:

props: ['options', 'defaults'],
computed: {
  opts: function () {
    let opts = {}
    Object.assign(opts, this.defaults, this.options)
    return opts
  }
}

快速思考体验将显示,如果父组件更改了您的输入道具,您的组件可以正确反应。