【问题标题】:Vue computed methods can't change data using setter in templateVue计算方法无法使用模板中的setter更改数据
【发布时间】:2020-01-16 10:42:14
【问题描述】:

我需要使用计算更改数据:

<template>
    <div>{{ userDataTest }}</div>
</template>

props: {
    exampleData: {
        type: Object,
        required: true,
    },
},

computed: {
    userDataTest: {
        get: function() {
            return this.exampleData;
        },
        set: function(newValue) {
            console.log(newValue);
            return newValue;
        },
    },
}

mounted () {
    setTimeout(() => {
        console.log('Change now to null!');
        this.userDataTest = null;
    }, 5000);
},

我使用 props 获取数据,接下来我使用 getter 和 setter 创建计算方法。我在&lt;template&gt; 中添加了userDataTest。我使用setter将this.userDataTest中的数据(使用mounted)更改为null。 在 setter 中的 console.log(newValue); 中,我看到 newValuenull,但在 &lt;template&gt; 中没有任何变化,我仍然有来自 getter 的数据。

为什么 setter 不将 &lt;template&gt; 中的数据更改为 null

【问题讨论】:

  • 您的设置器除了返回输入值之外什么也没做。仅此一项不会有任何影响。
  • this.userDataTest总是指get方法返回的值,就是this.exampleData的值。
  • 你不能改变一个道具

标签: vue.js get set


【解决方案1】:

您似乎正试图通过返回一个新值来设置计算属性的值,但 Vue 实际上并没有检查设置器的返回值。也许您正试图通过计算属性代理 data 变量。如果是这样,setter 应该在 setter 主体中设置 data 变量。

例如,您的组件可以声明一个名为userDatadata variable,它始终通过watcher 具有exampleData 属性的最新值:

export default {
  props: {
    exampleData: Object
  },
  data() {
    return {
      userData: {}
    }
  },
  watch: {
    exampleData(exampleData) {
      this.userData = exampleData
    }
  },
}

然后,您的模板和计算属性将使用 userData 代替:

<template>
  <div>{{ userData }}</div>
</template>

<script>
export default {
  //...
  computed: {
    userDataTest: {
      get() {
        return this.userData
      },
      set(newValue) {
        this.userData = newValue
      }
    }
  }
}
</script>

【讨论】:

    【解决方案2】:

    Mutating a prop 本地被认为是一种反模式

    但是,您可以使用.sync modifier,如下所示,但您不能将属性设置为null,因为您指定它必须是Object 类型。

    Vue.component('my-component', {
      template: `<div>{{ userDataTest }}</div>`,
      props: {
        exampleData: {
          type: Object,
          required: true
        }
      },
    
      computed: {
        userDataTest: {
          get: function() {
            return this.exampleData
          },
          set: function(newValue) {
            this.$emit('update:exampleData', newValue)
          }
        }
      },
    
      mounted() {
        setTimeout(() => {
          console.log('Change now!')
          this.userDataTest = {}
        }, 2500)
      }
    })
    
    new Vue({
      el: '#app',
    
      data() {
        return {
          exampleData: {
            foo: 'bar'
          }
        }
      }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
    
    <div id="app">
      <my-component :example-data.sync="exampleData"></my-component>
    </div>

    【讨论】:

      猜你喜欢
      • 2019-09-02
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      • 2020-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-05
      相关资源
      最近更新 更多