【问题标题】:Handling unexpected side effect in computed properties - VueJS处理计算属性中的意外副作用 - VueJS
【发布时间】:2023-03-28 14:44:01
【问题描述】:

在下面的代码中,我尝试使用getTranslation 对象来映射originalKeys 数组中存在的值,并将这些值推送到新数组allKeys 中。

但是 ESLint 给了我这个错误,Unexpected side effect in "getkeys" computed property.

我尝试将 getkeys 函数转换为方法,但我认为每次都调用一个方法来完成翻译是没有意义的。 我该如何解决这个问题?

<template>
    <select v-model="selected">
    <option v-for="key in getkeys" v-bind:key="key"> {{ key }}</option
    </select>
</template>

data(){
    return{
    selected: '',
    allKeys: [],
    originalKeys: [],  //e.g. ["ALPHA_MIKE]
    getTranslation: {} //e.g. {"ALPHA_MIKE": "ALPHA MIKE"}
    }
},
computed: {
    getkeys(){
        let tableHeaders = [];
        for( var i=0; i<this.originalKeys.length; i++){
            let translation = this.getTranslation[this.originalKeys[i]];
            tableHeaders.push(translation);
        }
        this.selected = tableHeaders[0]; //unexpected side effect here
        this.allKeys = tableHeaders; //unexpected side effect here.
        return this.allKeys;
    }
}

【问题讨论】:

  • 你不应该编辑computed中的其他数据,你应该改用watch
  • 所以你的意思是我应该在watch 中写getkeys

标签: javascript vue.js vuejs2


【解决方案1】:

正如我上面的评论,你不应该编辑computed属性中的其他数据,你应该改用watch

computed: {
    getkeys(){
        let tableHeaders = [];
        for( var i=0; i<this.originalKeys.length; i++){
            let translation = this.getTranslation[this.originalKeys[i]];
            tableHeaders.push(translation);
        }
        return tableHeaders;
    }
},
watch: {
  getkeys: {
    deep: true,
    handler: function (newVal) {
      this.selected = newVal[0]
      this.allKeys = newVal
    }
  }
}

【讨论】:

  • 为什么?为什么这是个好主意?我知道它缩小了错误的来源,但它非常令人愤怒,因为这些怪癖在文档中都没有提及。
【解决方案2】:

ESLint 显示此错误是因为您正在更改计算属性中的原始数据。建议您从计算属性返回新的引用或数据。点击此链接获取详细说明。 https://github.com/vuejs/eslint-plugin-vue/blob/master/docs/rules/no-side-effects-in-computed-properties.md

【讨论】:

    【解决方案3】:

    正如其他答案所提到的,这是因为您正在改变计算属性中的原始数据。您应该使用一种方法来完成这部分工作。

    methods:{
        changes(tableHeaders){
            this.selected = tableHeaders[0];
            this.allKeys = tableHeaders;
        }
    },
    computed:{
        getkeys(){
            // Your code...
            this.changes(tableHeaders);
        }
    },
    data: function(){
        return{
            // Your data...
        }
    }
    

    【讨论】:

      【解决方案4】:

      我建议您将 allKeys 数组移动到计算并摆脱不必要的 tableHeadersgetKeys

      <template>
          <select v-model="selected">
          <option v-for="key in allKeys" v-bind:key="key"> {{ key }}</option
          </select>
      </template>
      
      data(){
          return{
          selected: '',
          originalKeys: [],  //e.g. ["ALPHA_MIKE]
          getTranslation: {} //e.g. {"ALPHA_MIKE": "ALPHA MIKE"}
          }
      },
      computed: {
          allkeys() {
              return this.originalKeys.map(key => this.getTranslation[key])
          }
      }
      

      我不确定您是否需要分配 this.selected = tableHeaders[0],因为默认情况下会自动选择第一个选项。

      【讨论】:

        猜你喜欢
        • 2021-02-08
        • 1970-01-01
        • 1970-01-01
        • 2019-10-03
        • 2020-09-20
        • 2021-06-20
        • 2017-08-23
        • 2020-02-05
        • 1970-01-01
        相关资源
        最近更新 更多