vue js, перечеркнутая линия изчезает после нажатия на кнопку "ДОБАВИТЬ"
если нажать на чекбокс, то текст зачеркнется - но появляется ошибка : Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "complited"
и еще после нажатия на кнопку "добавить" зачеркнутые тексты вдруг превращаются в обычный текст(не зачеркнутый)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>планировщик задач</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<style>
.todo-list-example{
padding: 20px
}
.crossed{
text-decoration: line-through;
}
</style>
<body>
<div id="todo-list-example">
<form v-on:submit.prevent="addNewTodo">
<label for="new-todo">Добавить задачу</label>
<input
v-model="newtodotext"
id="new-todo"
placeholder="Например, покормить кота"
>
<button>Добавить</button>
</form>
<ul>
<li
is="todo-item"
v-for="(todo, index) in todos"
v-bind:key="todo.id"
v-bind:title="todo.title"
v-on:remove="todos.splice(index, 1)"
></li><!-- is="todo-item" всеравно что использовать todo-item, но поволяет обходить проблемы парсинга -->
{{newtodotext}}
</ul>
</div>
<script>
Vue.component('todo-item', {
template: `
<li v-bind:class="{crossed: complited}">
<input type="checkbox" v-on:change="complited = !complited" >
{{ title }}
<button v-on:click="$emit('remove')">Удалить</button>
</li>
`,
props: ['title','complited']
})
new Vue({
el: '#todo-list-example',
data: {
newtodotext: '',
todos: [
{
id: 1,
title: 'Помыть посуду',
complited: false
},
{
id: 2,
title: 'Вынести мусор',
complited:false
},
{
id: 3,
title: 'Подстричь газон',
complited:false
}
],
nextTodoId: 4
},
methods: {
addNewTodo: function () {
this.todos.push({
id: this.nextTodoId++,
title: this.newtodotext,
complited: false
})
this.newtodotext = ''
}
}
})
```
</script>
</body>
</html>
Ответы (2 шт):
Автор решения: MoloF
→ Ссылка
Ваша проблема заключается в том, что вы пытаетесь изменить состояние Props'а, ошибка об этом и намекает. Нужно протягивать ивент до родительского компонента чтобы все заработало.
Vue.component('todo-item', {
template: `
<li :class="{ crossed: status }">
<input type="checkbox" @change="toggleStatus">
{{ title }}
<button @click="remove">Удалить</button>
</li>
`,
props: ['title', 'status'],
methods: {
toggleStatus() {
this.$emit('toggle-status');
},
remove() {
this.$emit('remove');
}
}
});
new Vue({
el: '#todo-list-example',
data: {
title: '',
todos: [
{
id: 1,
title: 'Помыть посуду',
status: false
},
{
id: 2,
title: 'Вынести мусор',
status: false
},
{
id: 3,
title: 'Подстричь газон',
status: false
}
],
lastInsertId: 3
},
methods: {
addNewTodo: function() {
this.todos.push({
id: ++this.lastInsertId,
title: this.title,
status: false
});
this.title = '';
},
removeTodo(index) {
this.todos.splice(index, 1);
},
toggleStatus(index) {
this.todos[index].status = !this.todos[index].status;
}
}
});
.todo-list-example {
padding: 20px
}
.crossed {
text-decoration: line-through;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="todo-list-example">
<form @submit.prevent="addNewTodo">
<label for="new-todo">Добавить задачу</label>
<input v-model="title" id="new-todo" placeholder="Например, покормить кота">
<button>Добавить</button>
</form>
<ul>
<todo-item
v-for="(todo, index) in todos"
:key="todo.id"
:title="todo.title"
:status="todo.status"
@toggle-status="toggleStatus(index)"
@remove="removeTodo(index)"
>
</todo-item>
{{ title }}
</ul>
</div>
Автор решения: MoloF
Вариант с помощью
→ Ссылка
Вариант с помощью VUEX
const store = new Vuex.Store({
state: {
todos: [
{ name: "Learn JavaScript", status: false },
{ name: "Learn Vue", status: false },
{ name: "Play around in JSFiddle", status: true },
{ name: "Build something awesome", status: true }
],
lastInsertId: 5
},
actions: {
add: ({ commit }, todo) => commit('add', todo),
toggle:({ commit }, index) => commit('toggle', index),
removeByIndex: ({ commit }, index) => commit('removeByIndex', index),
removeAll: ({ commit }, index) => commit('removeAll', index)
},
mutations: {
add(state, todo) {
state.todos.push({
id: state.lastInsertId++,
name: todo['name'] || '',
status: todo['status'] || false
});
},
toggle(state, index) {
state.todos[index].status = !state.todos[index].status;
},
removeByIndex(state, index) {
state.todos.splice(index, 1);
},
removeAll(state) {
state.todos = [];
}
},
getters: {
todos: ({ todos }) => todos,
todosCompleted: ({ todos }) => todos.filter(todo => todo.status).length
}
});
Vue.config.productionTip = false;
Vue.config.devtools = false;
new Vue({
el: '#app',
store,
data: {
name: ''
},
computed: {
todos() {
return this.$store.getters['todos'];
},
todosCompleted() {
return this.$store.getters['todosCompleted'];
}
},
methods: {
remove(index) {
this.$store.dispatch('removeByIndex', index);
},
toggle(index) {
this.$store.dispatch('toggle', index);
},
add() {
this.$store.dispatch('add', { name: this.name });
this.name = '';
}
}
});
body {
background: #20262e;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
del {
color: rgba(0, 0, 0, 0.3);
}
<script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Задачник:</h2>
<form @submit.prevent="add">
<input type="text" placeholder="Название задачи" v-model="name">
<button>Добавить</button>
</form>
<p>Всего задач: {{ todos.length }}</p>
<p>Количество выполненных: {{ todosCompleted }}</p>
<br>
<ol>
<li v-for="(todo, index) in todos" :key="index">
<label>
<input type="checkbox" @change="toggle(index)" :checked="todo.status">
<del v-if="todo.status">
{{ todo.name }}
</del>
<span v-else>
{{ todo.name }}
</span>
<button @click="remove(index)">x</button>
</label>
</li>
</ol>
</div>