Alwaysblue
Alwaysblue

Reputation: 11830

Changing object from external file

I am learning Vue and before that I have some experience working with React.

As, I move on comprehending the basics of vue, I sort of compare things with JS

<template>
  <div id="app">
   <HelloWorld msg="Below This we will inclue our To-do task list"/>
    <p>{{msg}}</p>
    <Todos :toDoItem="todos"/>
  </div>
</template>

import Todos from "./components/todo.vue";
let todo = 
  {
    name: "Rohit",
    title: "Full Stack Developer",
    completed: true
  }

export default {
  name: "app",
  components: {
    HelloWorld,
    Todos
  },
  data() {
    return {
      msg: "hello",
      todos: todo
    };
  }
};

We are passing the props here to child component and changing it using method

 <template>
  <div>
    <div class="main-class">
      <p>{{toDoItem.title}}</p>
      <input type="checkbox" v-on:change="markComplete">
    </div>
  </div>
</template>

  <script>
export default {
  name: "toDoItem",
  props: {
    toDoItem: {
      type: Object
    }
  },
 method: {
  markComplete() {
   this.toDoItem.complete = !this.toDoItem.complete
   }

};
</script>

This is where I am unable to comprehend many things.

Question 1: Based on my understanding of this, shouldn't it point to a global space and hence this should be undefined?

 markComplete() {
   this.toDoItem.complete = !this.toDoItem.complete
   }

Question 2: In react we can't change props passed to a child object probably? but here we are changing the props? Also, In general, if we declare a object in another file (app.js), can we change it to in another file (someApp.js)?

Upvotes: 0

Views: 32

Answers (1)

Roy J
Roy J

Reputation: 43881

All methods in a Vue instance are bound to the instance so that this works properly.

You should not be changing props. Here, you are changing a member of a prop -- toDoItem is a prop, and complete is a member of it -- which is not controlled, but you still should not do it. You should instead emit an event that the parent handles.

Your markComplete should be in the parent, since it owns the data being manipulated. It would look like:

markComplete() {
  this.todos.complete = !this.todos.complete;
}

In the child, the method would be something like

toggleComplete() {
  this.$emit('toggle');
}

And the parent would use v-on to handle the toggle event:

<Todos :toDoItem="todos" v-on:toggle="markComplete"/>

This way all the code that manipulates data owned by a component happens within that component. Nobody calls anybody else's methods or modifies their data.

I think you intend for todos to be an array of items, and probably want to v-for over them, having one child component for each item, but that's another issue.

I cannot answer your last question about objects declared in different files, because I don't understand it. It is not unusual to import objects and modify them, generally. As I mentioned, though, Vue components should be the only ones to modify their own data.

Upvotes: 1

Related Questions