如何用Vue JS在子组件中保持数字和增量?

问题描述 投票:0回答:1

练习用Vue JS做一个todo应用。

输入的项目保存在localStrage中。

已更新

当您添加了一些列表并重新加载页面时,ID号从1开始(defalut)。

理想的行为。

  • 当重新加载一个页面时,ID号继续递增。
  • 如果删除了一些项目,那么添加新项目时,ID号应该是数组中最大的ID号(如果是8)+1(应该是9)。

我的代码。链接

问题就在这附近。

Child2.vue

  created() {
    let keyObject = JSON.parse(localStorage.getItem(this.keyName));

    if (keyObject) {
      this.$emit("update:todos", keyObject);
    } else {
      return;
    }

    if (this.todos.length > 0) {
      console.log(this.todos.id);
      const setId = this.todos.reduce(function(a,b){ return a > b.id ? a : b.id} ,0)
      this.todos.id = setId + 1
      console.log(this.todos.id);

      this.$emit('update:todos', keyObject)
      // this.$emit('update:todos', this.todos.id)
    }
  },

你知道怎么做吗?

javascript vue.js vue-component vue-cli
1个回答
1
投票

你可以避免直接使用修改道具 .sync 修改器。

App.vue:

<Child2 :todos.sync="todos" :keyName="keyName"/>

Child2. vue:

if (keyObject) {
     this.$emit('update:todos', keyObject);
}

对于获取下一个id,你可以在从本地存储中获取数组时发出这个值。

App. vue:

<Child2 :todos.sync="todos" @setTargetId="setTargetId" :keyName="keyName"/>
methods: {
    // ...
    setTargetId(newTargetId){
        this.$set(this.target, 'id', newTargetId );
    }
}

Child2.vue:

// ...
created() {
    let keyObject = JSON.parse(localStorage.getItem(this.keyName));

    // Check keyObject 
    if (keyObject) {
        // update todo on App.vue
        this.$emit("update:todos", keyObject);

        // set target.id
        const setId = keyObject.reduce(function(a,b){ return a > b.id ? a : b.id} ,0)
        this.$emit('setTargetId', setId + 1)
    } 
},

参见这里。https:/codesandbox.ioskeen-gates-q7efo。


4
投票

在keyObject和this.todos中的格式不一致(this.todos实际上是嵌套的),而且你不应该突变道具。

同时注意ID的增量,以避免在LOOPS中出现重复错误。

我的建议是App.vue。

methods: {
    addBtn() {

      const todo = { id: this.target.id, name: this.target.name, done: false };
      this.todos.push(todo);
      localStorage.setItem(this.keyName, JSON.stringify(this.todos));
      this.target.name = "";
      //it is important to increment the id based on current length
      this.target.id = this.todos.length + 1;
    },
    onInputChange(val) {
      this.target.name = val;
    }
  },
  created() {
     let todosObject  = JSON.parse(localStorage.getItem(this.keyName));
     if(todosObject){
       this.todos = todosObject
       //again base the id on the current length, to avoid duplicate error in loops later 
       this.target.id = this.todos.length+1
     }

  }

Child2:

<template>
  <div>
    <ul>
      <li v-for="todo in todos" :key="todo.id">
        ID: {{ todo.id }} / Name: {{ todo.name }}
        <input
          type="checkbox"
          v-model="todo.done"
          @click="status(todo)"
        >
        <button @click="removeBtn(todo)">Remove item</button>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  props: {
    todos: {
      type: Array,
      required: true
    },
    keyName: {
      type: String,
      required: true
    }
  },

  methods: {
    removeBtn(item) {
      const index = this.todos.indexOf(item);
      this.todos.splice(index, 1);
      localStorage.setItem(this.keyName, JSON.stringify(this.todos));
      if (this.todos.length === 0) {
        console.log("no item");
      }
    },
    status(todo) {
      todo.done = !todo.done;
      localStorage.setItem(this.keyName, JSON.stringify(this.todos));
    }
  }
};
</script>

2
投票

根据我对你的问题的理解,你想更新子组件中道具的值。

要做到这一点,你可能想把子组件的变化发射回父组件。

下面是一种方法。

在你的子组件中,

this.todosArray = this.todosArray.concat(keyObject); //concat with an existing array
this.$emit("updateTodos", this.todosArray); //emit new array back to parent

在你的父组件中,在你注册你的子组件的地方,

<Child2 :todos="todos" :keyName="keyName" @updateTodos="updateTodos"/>

然后添加一个方法来更新原来的数组 用来自于子组件的值。

updateTodos(value) {
 this.todos = value
}

希望能帮到你。祝大家好运!

© www.soinside.com 2019 - 2024. All rights reserved.