【问题标题】:Vue - Change computed property value without changing parent property valueVue - 在不更改父属性值的情况下更改计算属性值
【发布时间】:2020-11-24 20:38:27
【问题描述】:

这个问题可能看起来很基本(可能是因为它是),但由于某种原因,我很难弄清楚如何处理它。基本上,我有一个属性传递给我的 Vue 组件,它规定了组件中的一些样式差异。话虽如此,我在组件中有一个按钮,我想更改此属性。显然,使用 Vue,我无法直接更改父属性值(Vue 变得疯狂),但我无法弄清楚如何在不使用初始属性值的情况下计算动态属性,这将使其无法更改。我确信有一个简单的解决方案,所以希望有人能指出我的愚蠢。

(为了简单起见,我已经删除了组件的其余部分,因为这个问题只涉及几个部分

这是组件:

<template>
    <div>
      <button type="button" :style="{
           backgroundColor: isSaved ? 'gray' : '#68AEFA',
      }" v-on:click="savePost()">
         {{ isSaved ? 'Unsave' : 'Save' }} 
      </button>
    </div>
</template>
<script>
   export default {
      props: ['saved'],
      methods:{
        savePost: function() {
           // Want to change value of isSaved here
        },
      },
      computed: {
         isSaved: function () {
             if (this.saved == '0') {
                return false
             } else {
                return true
             }
         }
      },
   }
</script>

希望上面的代码能更好地显示我所描述的内容。本质上,isSaved 取决于属性“已保存”的初始值,它从中推断出其值。由于 Vue 不允许我直接更改已保存的值,我初始化了另一个变量 isSaved,它是根据初始保存的属性值计算得出的,但是如果 isSaved 的值基于“已保存”的值,我该如何更改它?

再次,抱歉这个问题很愚蠢,但我在 Vue 文档中看不到任何关于我将如何做到这一点的内容,因为它依赖于页面加载计算属性,而没有太多描述你将如何处理调整值。

【问题讨论】:

标签: vue.js


【解决方案1】:

当使用计算属性时,你有 2 个内部方法,getset,但在这种情况下,你的计算属性反映了 props,所以如果你重新渲染父组件,它将被设置回父值,在本案"0".

您可以从父级发送一个方法来使用道具更改值。

<template>
    <ChildComponent  :save="save" :isSaved="isSaved"/>
</template>

<script>

export default {
   name: "ParentComponent"
   data() {
      return {
         isSaved: false
      }
   }
    methods: {
       save() {
          this.isSaved = true;
       }
    }
};
</script>

你只需要在子组件中将 save 属性设置为函数并调用它。

<template>
    <button
        type="button"
        :style="{
           backgroundColor: isSaved ? 'gray' : '#68AEFA',
      }"
        @click="save()"
    >{{ isSaved ? 'Unsave' : 'Save' }}</button>
</template>

<script>

export default {
   name: "ChildComponent",
   data() {
      return {
         saved: false
      }
   }
   computed: {
      uniqueSaveStatus: {
         get() {
            return this.saved
         },
         set(v) {
            this.saved = v
         }
      }
   }
   props: {
      isSaved: Boolean,
      save: { type: Function }
   }
};
</script>

因此,如果您确实需要 isSaved 变量是唯一的,则需要在 childComponent 中定义它,例如 uniqueSaveStatus

【讨论】:

    【解决方案2】:

    我知道这已经有一个公认的答案,但我个人认为添加一个函数作为道具应该是一种反模式。它会起作用,但它会以错误的方式摩擦我。

    你以前是在正确的道路上。根据 Vue documentation 的说法,有两种情况会让人很想改变道具

    通常有两种情况很容易改变 prop:

    • prop 用于传入一个初始值;子组件 之后想将其用作本地数据属性。在这种情况下, 最好定义一个使用 prop 作为它的本地数据属性 初始值:

    props: ['initialCounter'],
    data: function () {
      return {
        counter: this.initialCounter
      }
    }
    • prop 作为需要转换的原始值传入。在 在这种情况下,最好使用 prop 定义一个计算属性 价值:

    props: ['size'],
    computed: {
      normalizedSize: function () {
        return this.size.trim().toLowerCase()
      }
    }

    我认为你最好使用你之前的方法。在我看来,将函数作为道具传递有点混乱。

    编辑 --- 这个article 证实了我关于将函数作为道具传递的预感。这是个坏主意。文章提供了替代方案。我建议你读一读。

    【讨论】:

    • 感谢您的回答,我已将解决方案切换为您的回答,因为它更简单。出于某种奇怪的原因,我从不知道数据返回可以使用属性,我认为它们必须被赋予一个固化的、预定的值,所以仅仅定义一个返回的数据属性关闭初始属性要简单得多,而且,正如你所附的文章解释,更安全。感谢您简洁的回答,代码现在按预期工作。
    • 不客气,@Nathan。我很高兴能提供帮助:)
    猜你喜欢
    • 1970-01-01
    • 2021-10-31
    • 2017-12-26
    • 2019-10-25
    • 2018-05-22
    • 2018-05-09
    • 2021-11-24
    • 1970-01-01
    • 2020-09-13
    相关资源
    最近更新 更多