【问题标题】:$set is not working for updating my array in vue.js$set 无法在 vue.js 中更新我的数组
【发布时间】:2019-10-18 12:55:33
【问题描述】:

在 vue.js 应用程序中,我正在尝试使用 axios 使用来自 java/postgresql 后端的内容填充数组。我知道除非您使用 $set 关键字,否则 vue 不会跟踪对数组的更改。当我使用 $set 关键字时,我遇到了以下错误消息:

ManageTools.vue?45c2:109 Uncaught (in promise) TypeError: >_this2.userToolsIds.$set is not a function 在 eval (ManageTools.vue?45c2:109)

我已尝试在函数的开头设置 vm=this,详见此处... TypeError: this.$set is not a function 这没有帮助。

我必须改变什么?

<template>
<div class="card">
  <div class="card-header">
      <h3 class="card-title">
        Tools                    
      </h3>
  </div>
  <div class="card-body">
      <div class="row row-eq-height">
          <div class="col">
            <FormDropdown
            :field-content="selectedTool"
            field-label="Tools"
            field-name="tool"
            :field-choices="tools"
            field-description="Select a tool and click 'install' to install."
            @updateValue="updateValue"                                                                   
            ></FormDropdown>
            <div class="row mt-2 mb-2">
              <div class="col">        
               <button class="btn btn-primary" @click.prevent="installTool">Install Tool</button>
              </div>
            </div>            
          </div>
          {{finishedFetchingToolIds}} {{finishedFetchingToolsInfo}}
          <div class="col col-md-6" v-if="finishedFetchingToolsInfo">
            Installed Tools
            {{userTools}}
            <ul>
              <li v-for="tool in userTools" :key="tool">
                toolname
                {{tool.toolname}}
              </li>
            </ul>
          </div>
      </div>
  </div>
  <div v-if="showTool">
    <foo>
    </foo>
  </div>
</div>
</template>

<style>
</style>

<script>
import axios from 'axios';
import store from "../store.js";
import FormDropdown from "@/components/FormDropdown";
export default {
  name: "ManageTools",
  components: {  
    foo: () => import('../test-plugin.js'),
    FormDropdown
  },

  data() {
    return {
      showTool: false,
      tools: ['mass-emailer', 'auto-text-messenger'],
      selectedTool: 'mass-emailer',
      userToolsIds: [],
      userTools: [],
      user_id: 2,
      finishedFetchingToolIds: false,
      finishedFetchingToolsInfo: false
    }

  },

  methods: {
    installTool() {
      this.showTool = true;
      console.log("showing tool");
    },
    updateValue() {
      console.log("updating value");
    }
  },
  watch: {
    finishedFetchingToolIds() {
      console.log("in watch for finishedFetchingToolIds")
      for (var i = 0; i < this.userToolsIds.length; i++) {
        axios.get("/tools/"+this.userToolsIds[i]).then(
          response => {
            console.log("tool info: "+response.data.toolname);
            this.userTools.$set(i, response.data);
            console.log("userTools[i]: "+this.userTools[i]);
            console.log("finishedFetchingToolsInfo: "+this.finishedFetchingToolsInfo);
          },
          error => {
            store.setAxiosErrorMessage("Failed to display tool info", error);
          }
        );
      }
      this.finishedFetchingToolsInfo = true;
    }
  },
  mounted() {
    console.log("mounted");
    axios.get("/tools/installed_tools").then(
      response => {
        console.log("response.data[0] "+response.data[0].tool_id);
        for (var i = 0; i< response.data.length; i++) {
          console.log("iter = "+ i);
          console.log("tool id: "+response.data[i].tool_id);
          this.userToolsIds.$set(i, response.data[i].tool_id);
        }
        console.log("userToolsIds length: "+this.userToolsIds.length);  
        this.finishedFetchingToolIds = true;
      },
      error => {
        store.setAxiosErrorMessage("Failed to display user tools info", error);
      }
    );
  }
};
</script>

这里可以使用数组还是对象更合适?

【问题讨论】:

    标签: arrays vue.js


    【解决方案1】:
    this.userToolsIds.$set(i, response.data[i].tool_id);
    

    ...应该是:

    this.$set(this.userToolsIds, i, response.data[i].tool_id);
    

    ...,用response.data[i].tool_id 填充this.userToolsIds[i]


    ViewModel 有一个$set 方法,而不是你的数据。

    documentation

    【讨论】:

    • 谢谢。当我在 for 循环内调用 this.$set(this.userTools, i, response.data) 时, this.userTools 的第 0 和第 1 索引不会更新。每次循环时只有索引 2 更新并被覆盖。为什么是这样?也许是在 for 循环中调用异步函数的结果?
    • 没有检查能力,我帮不了你。我猜,这在很大程度上取决于您的回应内容。提供minimal reproducible example,我会看看。确保它包含问题。
    【解决方案2】:

    我的后续问题的解决方案是将 async/await 关键字添加到 for 循环内的 axios 调用中。

    watch: {
        async finishedFetchingToolIds() {
          for (var j = 0; j < this.userToolsIds.length; j++) {
            await axios.get("/tools/"+this.userToolsIds[j]).then(
              response => {
                this.$set(this.userTools, j, response.data);
    
    
     },
          error => {
            store.setAxiosErrorMessage("Failed to display tool info", error);
          }
        );
      }
      this.finishedFetchingToolsInfo = true;
    }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-07
      • 2019-07-06
      • 2018-12-07
      • 1970-01-01
      • 2017-02-09
      • 1970-01-01
      • 2018-01-25
      • 2017-12-01
      相关资源
      最近更新 更多