amitavroy / learning-vuejs

Code for Tutorial on Series Learning VueJS
30 stars 8 forks source link

cannot split TODO in components #2

Open schel4ok opened 8 years ago

schel4ok commented 8 years ago

I like your vue tutorial. But I am stuck on the topic of splitting ToDoApp in separate components. Please help me to understand what's wrong with the code.

I have Laravel 5.3 + vuejs 2.0.5

This way ToDoApp is working \resources\assets\js\app.js

require('./bootstrap');
const app = new Vue({
    el: '#app',
    data: {
        todos: [],
        newTodo: {id: null, title: '', completed: false},
    },
    computed: {
        todoCount() {
            return this.todos.length
        }
    },
    methods: {
        addNewTodo(newTodo) {
            this.todos.push(newTodo)
            this.newTodo = {id: null, title: '', completed: false}
        },

        deleteTodo(todo) {
            var index = this.todos.indexOf(todo);
            this.todos.splice(index, 1);
        },

        todoCompleted(todo) {
            todo.completed = !todo.completed
        },
    }
});

blade.php

        <div class="col-sm-12">
            <div class="panel panel-default">
                <div class="panel-heading" >Мои задачи @{{todoCount}}</div>

                <div class="panel-body">
                    <ul class="list-group" v-if="todos.length > 0">
                        <li class="list-group-item" v-for="todo in todos" v-bind:class="{ 'completed' : todo.completed }">
                            @{{ todo.title }}
                            <button class="btn btn-warning btn-xs pull-right" v-on:click="deleteTodo(todo)">Удалить</button>
                            <button class="btn btn-xs pull-right margin-right-10" 
                                v-bind:class="{'btn-success' : todo.completed, 'btn-danger' : !todo.completed}"
                                v-on:click="todoCompleted(todo)">@{{ todo.completed ? 'Завершено' : 'В работе' }}</button>
                        </li>
                    </ul>
                    <div v-else>Задач нету</div>
                    <form v-on:submit.prevent="addNewTodo(newTodo)">
                            <input v-model="newTodo.title" type="text" class="form-control margin-right-10" placeholder="добавь новую задачу">
                            <button class="btn btn-success">Добавить</button>
                    </form>

                </div>
            </div>
        </div>

but when I try to split the code into components I get the error in console \resources\assets\js\app.js

require('./bootstrap');

Vue.component('TodoItems', require('./components/TodoItems.vue'));
Vue.component('TodoAddForm', require('./components/TodoAddForm.vue'));

const app = new Vue({
    el: '#app',
    data: {
        todos: [],
        newTodo: {id: null, title: '', completed: false},
    },
});

\resources\assets\js\components\TodoItems.vue

<template>
    <ul class="list-group" v-if="todos.length > 0">
        <li class="list-group-item" v-for="todo in todos" v-bind:class="{ 'completed' : todo.completed }">
            {{ todo.title }}
            <button class="btn btn-warning btn-xs pull-right" v-on:click="deleteTodo(todo)">Удалить</button>
            <button class="btn btn-xs pull-right margin-right-10" 
                v-bind:class="{'btn-success' : todo.completed, 'btn-danger' : !todo.completed}"
                v-on:click="todoCompleted(todo)">{{ todo.completed ? 'Завершено' : 'В работе' }}</button>
        </li>
    </ul>
    <div v-else>Задач нету</div>
</template>

<script>
    export default {
        props: ['todos'],

        computed: {
            todoCount() {
                return this.todos.length
            }
        },

        methods: {
            todoCompleted(todo) {
                todo.completed = !todo.completed
            },

            deleteTodo(todo) {
                var index = this.todos.indexOf(todo);
                this.todos.splice(index, 1);
            },

        }

    }
</script>

\resources\assets\js\components\TodoAddForm.vue

<template>
        <form class="form-group" v-on:submit.prevent="addNewTodo(newTodo)">
            <input v-model="newTodo.title" type="text" class="form-control margin-right-10" placeholder="добавь новую задачу">
            <button class="btn btn-success">Добавить</button>
        </form>
</template>

<script>
    export default {
      props: ['newtodo'],

      data() {
        return {
            todo: {id: null, title: '', completed: false}
        }
      },

      methods: {
        addTodo() {
          this.newtodo = this.todo;
          this.todo = {id: null, title: '', completed: false};
        }
      }

    }
</script>

blade.php

                <div class="panel-body">
                    <TodoItems>  </TodoItems> 
                    <TodoAddForm>  </TodoAddForm>
                </div>

error in console

[Vue warn]: Property or method "todoCount" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. 
(found in root instance)app-1a9b4db40d.js%20line%20108%20%3E%20eval:2643:7

[Vue warn]: Unknown custom element: <todoitems> - did you register the component correctly? For recursive components, make sure to provide the "name" option. 
(found in root instance)app-1a9b4db40d.js%20line%20108%20%3E%20eval:2643:7

[Vue warn]: Unknown custom element: <todoaddform> - did you register the component correctly? For recursive components, make sure to provide the "name" option. 
(found in root instance)
amitavroy commented 8 years ago

Change the tags TodoItems - it should be and TodoAddForm - it should be

Try and let me know because both the error seems to be mainly because your component is not available. And I think this is the problem.

schel4ok commented 8 years ago

Sorry. I don't understand what do you mean. Replace TodoItems with what? Replace TodoAddForm with what?

I was thinking that most likely it is filename issue. And I tried to make everything in lowercase without Uppercase letters, but it is not working anyway.