如何使用 Vue JS 在子组件中保留数字和增量?
How can I keep number and increment in child component with Vue JS?
练习使用 Vue JS 制作待办事项应用程序
输入项目保存在localStrage。
已更新
当您添加了一些列表并重新加载页面时,ID 编号从 1(默认)开始。
理想行为:
- 重新加载页面时,ID号继续递增。
- 如果删除了一些项目,然后添加新项目,ID号应该是数组中最大的ID号(如果是8)+1(应该是9)。
我的代码:Link
问题就在这里。
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)
}
},
你知道怎么做吗?
您可以避免直接使用 .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)
}
},
根据我对你问题的理解,你想更新子组件的道具值。
为此,您可能希望将更改从子组件发回到父组件。
下面是一种方法:
在您的子组件中:
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
}
希望对您有所帮助。祝你好运!
keyObject 和 this.todos 格式不一致(this.todos 实际上是嵌套的),你不应该改变 props。
另请注意 ID 递增以避免循环中的重复错误
我的建议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
}
}
孩子 2:
<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>
练习使用 Vue JS 制作待办事项应用程序
输入项目保存在localStrage。
已更新
当您添加了一些列表并重新加载页面时,ID 编号从 1(默认)开始。
理想行为:
- 重新加载页面时,ID号继续递增。
- 如果删除了一些项目,然后添加新项目,ID号应该是数组中最大的ID号(如果是8)+1(应该是9)。
我的代码:Link
问题就在这里。
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)
}
},
你知道怎么做吗?
您可以避免直接使用 .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)
}
},
根据我对你问题的理解,你想更新子组件的道具值。
为此,您可能希望将更改从子组件发回到父组件。
下面是一种方法:
在您的子组件中:
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
}
希望对您有所帮助。祝你好运!
keyObject 和 this.todos 格式不一致(this.todos 实际上是嵌套的),你不应该改变 props。
另请注意 ID 递增以避免循环中的重复错误
我的建议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
}
}
孩子 2:
<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>