简体   繁体   中英

Vue.js checkbox bound via v-model to false value is checked

I am trying to make a todo list with like Eisenhower matrix, and i have a problem because v-bind and v-model is triggered on a false

How can i fix this bug? 在此处输入图像描述 Code is inspired by Vue.js Todo App - Basics - Part 1

 <div class="todoList" v-for="(task, index) in todo" :key="task.id">
                    <div>
                        <div v-if="task.type == 'notimportant'">
                            <input v-model="task.completed" type="checkbox" name="" id="" @change="completeTask(task)" />
                            <div class="task" v-bind:class="{ completed: task.completed }">
                                {{ task.title }}
                            </div>
                            <button class="removeTask" @click="removeTask(index)">X</button>
                        </div>
                    </div>
                </div>
export default {
    name: "app",
    data() {
        return {
            newTodo: "",
            type: "",
            important: "",
            id: 3,
            todo: [
                {
                    id: 1,
                    title: "Fist Task",
                    completed: "false",
                    editing: "false",
                    type: "urgent",
                },
                {
                    id: 2,
                    title: "Second Task",
                    completed: "false",
                    editing: "false",
                    type: "important",
                },
            ],
        };
    },

full code

<template>
    <div id="app">
        <div class="conteiner">
            <input placeholder="what we do ?" type="text" v-model="newTodo" />
            <button @click="addTask()">Add</button>
            <select v-model="type">
                <option disabled value="">Select</option>
                <option value="urgent">Urgent</option>
                <option value="noturgent">Not Urgent</option>
                <option value="important">Important</option>
                <option value="notimportant">Not Important</option>
            </select>
            <div class="todoBox">
                <h2>Urgent</h2>
                <div class="todoList" v-for="(task, index) in todo">
                    <div>
                        <div v-if="task.type == 'urgent'">
                            <input v-model="task.completed" type="checkbox" name="" id="" @change="completeTask(task)" />
                            <div class="task" v-bind:class="{ completed: task.completed }">
                                {{ task.title }}
                            </div>
                            <button class="removeTask" @click="removeTask(index)">X</button>
                        </div>
                    </div>
                </div>
            </div>
            <div class="todoBox">
                <h2>Not Urgent</h2>
                <div class="todoList" v-for="(task, index) in todo" :key="task.id">
                    <div>
                        <div v-if="task.type == 'noturgent'">
                            <input v-model="task.completed" type="checkbox" name="" id="" @change="completeTask(task)" />
                            <div class="task" v-bind:class="{ completed: task.completed }">
                                {{ task.title }}
                            </div>
                            <button class="removeTask" @click="removeTask(index)">X</button>
                        </div>
                    </div>
                </div>
            </div>

            <div class="todoBox">
                <h2>Important</h2>
                <div class="todoList" v-for="(task, index) in todo" :key="task.id">
                    <div>
                        <div v-if="task.type == 'important'">
                            <input v-model="task.completed" type="checkbox" name="" id="" @change="completeTask(task)" />
                            <div class="task" v-bind:class="{ completed: task.completed }">
                                {{ task.title }}
                            </div>
                            <button class="removeTask" @click="removeTask(index)">X</button>
                        </div>
                    </div>
                </div>
            </div>
            <div class="todoBox">
                <h2>Not Important</h2>
                <div class="todoList" v-for="(task, index) in todo" :key="task.id">
                    <div>
                        <div v-if="task.type == 'notimportant'">
                            <input v-model="task.completed" type="checkbox" name="" id="" @change="completeTask(task)" />
                            <div class="task" v-bind:class="{ completed: task.completed }">
                                {{ task.title }}
                            </div>
                            <button class="removeTask" @click="removeTask(index)">X</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    name: "app",
    data() {
        return {
            newTodo: "",
            type: "",
            important: "",
            id: 3,
            todo: [
                {
                    id: 1,
                    title: "Fist Task",
                    completed: "false",
                    editing: "false",
                    type: "urgent",
                },
                {
                    id: 2,
                    title: "Second Task",
                    completed: "false",
                    editing: "false",
                    type: "important",
                },
            ],
        };
    },
    methods: {
        addTask() {
            if (this.newTodo.trim().length == 0) {
                return;
            }
            this.todo.push({
                id: this.id,
                title: this.newTodo,
                completed: "false",
                editing: "false",
                type: this.type,
            });
            this.id++;
            this.newTodo = "";
        },
        removeTask(index) {
            this.todo.splice(index, 1);
        },
        completeTask(task) {
            task.completed = event.target.checked;
        },
    },
    directives: {
        focus: {
            inserted: function (el) {
                el.focus();
            },
        },
    },
};
</script>

<style>
* {
    margin: 0px;
    box-sizing: border-box;
}
.removeTask {
}
.completed {
    text-decoration: line-through;
}
.task {
    text-decoration: 0;
}

/*
.conteiner {
    display: flex;
} /*
.todoBox {
    width: 50%;
    height: 50vh;
    border: 1px solid black;
    text-align: center;
}
.todoList {
    width: 100%;
    height: 100%;
    border: 1px solid red;
}
*/
</style>

The issue is that you're writing false as string such "false" which is evaluated to true , you should know that empty string '' , 0 value, null and undefined are evaluated as false and vice-versa

learn more about type coercion here

 let app = new Vue({ el: "#app", data() { return { newTodo: "", type: "", important: "", id: 3, todo: [{ id: 1, title: "Fist Task", completed: false, editing: "false", type: "urgent", }, { id: 2, title: "Second Task", completed: false, editing: "false", type: "important", }, ], }; }, methods: { addTask() { if (this.newTodo.trim().length == 0) { return; } this.todo.push({ id: this.id, title: this.newTodo, completed: "false", editing: "false", type: this.type, }); this.id++; this.newTodo = ""; }, removeTask(index) { this.todo.splice(index, 1); }, completeTask(task) { task.completed = event.target.checked; }, }, directives: { focus: { inserted: function(el) { el.focus(); }, }, }, })
 * { margin: 0px; box-sizing: border-box; }.removeTask {}.completed { text-decoration: line-through; }.task { text-decoration: 0; } /*.conteiner { display: flex; } /*.todoBox { width: 50%; height: 50vh; border: 1px solid black; text-align: center; }.todoList { width: 100%; height: 100%; border: 1px solid red; } */
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <div class="conteiner"> <input placeholder="what we do?" type="text" v-model="newTodo" /> <button @click="addTask()">Add</button> <select v-model="type"> <option disabled value="">Select</option> <option value="urgent">Urgent</option> <option value="noturgent">Not Urgent</option> <option value="important">Important</option> <option value="notimportant">Not Important</option> </select> <div class="todoBox"> <h2>Urgent</h2> <div class="todoList" v-for="(task, index) in todo"> <div> <div v-if="task.type == 'urgent'"> <input v-model="task.completed" type="checkbox" name="" id="" @change="completeTask(task)" /> <div class="task" v-bind:class="{ completed: task.completed }"> {{ task.title }} </div> <button class="removeTask" @click="removeTask(index)">X</button> </div> </div> </div> </div> <div class="todoBox"> <h2>Not Urgent</h2> <div class="todoList" v-for="(task, index) in todo":key="task.id"> <div> <div v-if="task.type == 'noturgent'"> <input v-model="task.completed" type="checkbox" name="" id="" @change="completeTask(task)" /> <div class="task" v-bind:class="{ completed: task.completed }"> {{ task.title }} </div> <button class="removeTask" @click="removeTask(index)">X</button> </div> </div> </div> </div> <div class="todoBox"> <h2>Important</h2> <div class="todoList" v-for="(task, index) in todo":key="task.id"> <div> <div v-if="task.type == 'important'"> <input v-model="task.completed" type="checkbox" name="" id="" @change="completeTask(task)" /> <div class="task" v-bind:class="{ completed: task.completed }"> {{ task.title }} </div> <button class="removeTask" @click="removeTask(index)">X</button> </div> </div> </div> </div> <div class="todoBox"> <h2>Not Important</h2> <div class="todoList" v-for="(task, index) in todo":key="task.id"> <div> <div v-if="task.type == 'notimportant'"> <input v-model="task.completed" type="checkbox" name="" id="" @change="completeTask(task)" /> <div class="task" v-bind:class="{ completed: task.completed }"> {{ task.title }} </div> <button class="removeTask" @click="removeTask(index)">X</button> </div> </div> </div> </div> </div> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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