【问题标题】:Merge Vue props with default values将 Vue 道具与默认值合并
【发布时间】:2017-06-20 12:37:36
【问题描述】:

我的 Vue 组件中有一个 options 属性,它有一个默认值。

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

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

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

【问题讨论】:

    标签: javascript vue.js vue-component


    【解决方案1】:

    我最近也遇到过类似的问题,用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 传递的属性。不知道这是否是最有效的方法,但它非常容易理解和整洁:)

    所以如果你作为 props :options={someOption:true} 传入,合并的选项将相当于:

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

    编辑:如果您需要您的数据是反应性的,您可能需要计算。

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

    【讨论】:

    【解决方案2】:

    您实际上永远不想修改组件中的道具。如果这样做,您会破坏父/子组件的单向数据流,并且您的代码将难以推断是什么影响了什么。

    从 Vue 文档中提取,正确的解决方案是 (1) 使用初始 prop 或 (2) 计算值,因此您的应用程序可以是响应式的并尊重父组件,并且您可以高枕无忧并踢您的站起来:)

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

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

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

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

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

    一个快速的思想实验将表明,如果父组件更改了您的输入道具,您的组件可以正确反应。

    【讨论】:

    • 据我了解,他并不打算更改传世属性,而是覆盖默认值。
    猜你喜欢
    • 2023-02-03
    • 2021-07-29
    • 2021-05-17
    • 2016-03-25
    • 2019-05-08
    • 2019-01-26
    • 2017-11-09
    • 1970-01-01
    • 2020-06-07
    相关资源
    最近更新 更多