简体   繁体   English

从数组中删除的元素但 v-for 不更新 VUEJS

[英]Element deleted from the array but v-for doesn't update VUEJS

Guys so I'm trying to develop this rule component which can be spawned by my main component as many times as he wants but the problem is that when I delete an index from the list that tracks the number of rules, the vuejs layout doesn't update accordingly.伙计们,所以我正在尝试开发这个规则组件,它可以由我的主要组件任意多次生成,但问题是当我从跟踪规则数量的列表中删除一个索引时,vuejs 布局不会t 相应更新。 What I mean by this is that if I check the array it self it deleted the correct item but when I look at the vue page (HTML) it either doesn't delete anything or only deletes the last item, and this may be caused by the v-for not updating on list change but I don't know how to solve this.我的意思是,如果我检查它自己的数组,它会删除正确的项目,但是当我查看 vue 页面(HTML)时,它要么不删除任何内容,要么只删除最后一项,这可能是由v-for不更新列表更改,但我不知道如何解决这个问题。

NewTask.vue (Parent) NewTask.vue(父)

<template>
  <div class="mt-4">
      <div class="container">
          <div class="if-condition container-fluid d-flex flex-row ps-0">
              <span class="text-center me-2 condition rounded">IF</span>
              <select class="form-select form-select-sm me-2 if-select" v-model="if_condition">
                <option value="ALL">ALL</option>
                <option value="ANY">ANY</option>
                <option value="NONE">NONE</option>
              </select>
              <span>of these filters match</span>
          </div>
          <div class="mt-2 ps-3 pt-3 pb-3 border">
            <new-rule v-for="(item, index) in rules"
                      :key="JSON.stringify(index)" v-on:remove-rule="removeRule(index)"
                      :data="item" :index="index" v-on:data-changed="dataChanged"
                      class="mb-2"/>
            <div class="mt-2 add-rule-div">
              <button class="btn add-rule-btn" v-on:click="addRule">+</button>
            </div>
          </div>
      </div>
  </div>
</template>

<script>
import Rule from '@/components/rule'

export default {
    name: "NewTask",
    components: {
      'new-rule': Rule
    },
    data: function () {
      return {
        if_condition: 'ALL',
        rules: []
      }
    },
  methods: {
      dataChanged(data) {
        const rules = this.rules;
        const index = data.index;
        delete data['index'];
        rules.splice(index, 1, data)
        this.rules = rules;
      },
      removeRule(index) {
        const rules = this.rules;
        rules.splice(index, 1)
        this.rules = rules
      },
      addRule() {
        const new_rule = {
          type_input_text: null,
          type_input_show: null,
          rule_input_text: null,
          rule_input_show: null,
        }
        this.rules.push(new_rule)
        console.log(this.rules)
      }
    }
  }
</script>

rule.vue (Child) rule.vue (子)

<template>
    <div class="if-condition d-flex flex-row">
      <select class="form-select form-select-sm me-2"
              v-on:change="checkTypeSelect" v-model="type_select">
        <option value="HTML">HTML</option>
        <option value="XPATH">XPATH</option>
        <option value="ID">ID</option>
        <option value="CLASS">CLASS</option>
      </select>
      <input v-if="type_input_show" type="text" class="form-control me-2" v-model="type_input_text" v-on:change="dataChanged">
      <select class="form-select form-select-sm me-2"
              v-on:change="checkRuleSelect" v-model="rule_select">
        <option value="CONTAINS">CONTAINS</option>
        <option value="EXISTS">EXISTS</option>
      </select>
      <input v-if="rule_input_show" type="text" class="form-control me-2" v-model="rule_input_text" v-on:change="dataChanged">
      <button class="btn remove-rule-btn pb-0 pt-0 ps-2 pe-2" v-on:click="this.$emit('remove-rule')">-</button>
    </div>
</template>

<script>
export default {
  name: "rule",
  props: {
    data: {
      type: Object,
      required: true
    },
    index: {
      type: Number,
      required: true
    }
  },
  data: function () {
    return {
      type_select: 'HTML',
      type_input_text: '',
      rule_select: 'CONTAINS',
      rule_input_text: '',
      //
      type_input_show: false,
      rule_input_show: true,
    }
  },
  beforeMount() {
    if (this.data.type_select) {
      this.type_select = this.data.type_select
      this.checkTypeSelect()
    }
    if (this.data.type_input_text) {
      this.type_input_text = this.data.type_input_text
    }
    if (this.data.rule_select) {
      this.rule_select = this.data.rule_select
      this.checkRuleSelect()
    }
    if (this.data.rule_input_text) {
      this.rule_input_text = this.data.rule_input_text
    }
  },
  methods: {
    dataChanged() {
      const new_data = {
        index: this.index,
        type_select: this.type_select,
        type_input_text: this.type_input_text,
        rule_select: this.rule_select,
        rule_input_text: this.rule_input_text
      }
      this.$emit('data-changed', new_data)
    },
    checkTypeSelect() {
      const type_select = this.type_select;
      this.type_input_show = type_select !== 'HTML';
      this.dataChanged()
    },
    checkRuleSelect() {
      const rule_select = this.rule_select;
      this.rule_input_show = rule_select !== 'EXISTS';
      this.dataChanged()
    }
  }
}
</script>

Some images to demonstrate the issue:一些图像来证明这个问题:

Array Before Index delete:索引删除前的数组: 在此处输入图像描述 在此处输入图像描述

Array After Index delete:索引删除后的数组: 在此处输入图像描述 在此处输入图像描述

For further investigation feel free to visit the repo: https://github.com/DEADSEC-SECURITY/Easy-Scraper如需进一步调查,请随时访问 repo: https://github.com/DEADSEC-SECURITY/Easy-Scraper

THIS IS NOT PUBLICITY, I TRULY NEED HELP这不是宣传,我真的需要帮助

You are using the index as a key.您正在使用索引作为键。 VueJS updates the DOM based on the change in key. VueJS 根据 key 的变化更新 DOM。 So you have two options:所以你有两个选择:

  • Use some distinct data from each entry or combination as a key.使用每个条目或组合中的一些不同数据作为键。
  • Provide no key because as per Vuejs docs you need not provide a key anymore.不提供密钥,因为根据 Vuejs 文档,您不再需要提供密钥。

Currently, your rules value in NewTask.vue is under data .目前,您的rules在价值NewTask.vue正在data If you move it into computed , it will become reactive and the list should update properly.如果您将其移动到computed ,它将变得被动,并且列表应该正确更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM