[Vuejs]-Switching from Knockout to VueJs : missing concept

3👍

You’re asking a rather loaded question (or questions, I should say).. At a basic level, these answers should suffice – as well as the example provided, which covers many of your questions. Please let me know if you have any questions.

If you want to track certain properties, you can either use computed properties, or watch properties. Computed properties vs Watched properties

If you want to skip the first change in a watch property, you’ll have to integrate some sort of logic, like setting a bool flag. More on that here

There are a couple different ways to use an "external" js file in a component – you could just import it and use the necessary functions, etc.. Or you could use a mixin. More on mixins here

Child components emit data to parent components, parent components pass data to children via props. The example below displays this.


EDIT: you are asking about mixins and how to add "third" party modules to a component.. This CodePen does produces the same result as the original I provided below, only that it uses a mixin. This demonstrates how you can do "whatever you want" in any component via a mixin.. (or I hope it does, at least)…


Example code:

[CodePen mirror]

[CodePen using mixin]


/*****************************/
/* User VM Factory Component */
/*****************************/
const userVmFactoryComponent = {
  name: "userVmFactoryComponent",
  template: "#userVmFactoryComponent",
  props: {
    id: [String, Number],
    name: String,
    lastName: String,
    city: String,
  },
  data() {
    return {
      user: {
        id: "",
        name: "",
        lastName: "",
        city: "",
      }
    }
  },
  methods: {
    emitNameChanged(){
      this.$emit('name-changed', this.fullName);
    }
  },
  computed: {
    fullName() { // using fullName vs nameAndFirstName
      return this.user.name + " " + this.user.lastName;
    }
  },
  mounted(){
    this.user.id = this.id;
    this.user.name = this.name;
    this.user.lastName = this.lastName;
    this.user.city = this.city;
  }
}

/****************/
/* Main Vue App */
/****************/
new Vue({
  el: "#app",
  components: {
    userVmFactoryComponent,
  },
  data: {
    users: [],
  },
  methods: {
    handleNameChange(info) {
      alert("You changed the name! (alerted from parent) " + "'" + info + "'")
    }
  },
  mounted() {
    // pretend you're getting this data from an API
    let firstUser = {
      id: 100,
      name: 'John',
      lastName: 'Smith',
      city: 'Paris',
    };
    
    let secondUser = {
      id: 200,
      name: "Jane",
      lastName: "Doe",
      city: "New York",
    }
    
    this.users.push(firstUser);
    this.users.push(secondUser);
  }
})
.user-input {
  margin-bottom: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>


<!-- MAIN VUE APP -->
<div id="app">
  <div>
  <div>
    <div>Without Looping</div>
    <user-vm-factory-component 
      @name-changed="handleNameChange"
      :id="users[0].id" 
      :name="users[0].name" 
      :last-name="users[0].lastName" 
      :city="users[0].city"
    ></user-vm-factory-component>
    <br/>
    <user-vm-factory-component 
      @name-changed="handleNameChange"
      :id="users[1].id" 
      :name="users[1].name" 
      :last-name="users[1].lastName" 
      :city="users[1].city"
    ></user-vm-factory-component>
  </div>
    <br/><hr/><br/>
    <div>
      <div>With Looping</div>
      <div>
        <div v-for="(user, index) in users">
          <user-vm-factory-component
            @name-changed="handleNameChange"
            :id="user.id"
            :name="user.name"
            :last-name="user.lastName"
            :city="user.city"
          ></user-vm-factory-component>
          <br/>
        </div>
      </div>
    </div>
  </div>
</div>

<!-- ===================================== -->
<!-- THIS SIMULATES userVmFactoryComponent -->
<!-- ===================================== -->
<script type="text/x-template" id="userVmFactoryComponent">
  <div>
    Id
    <div class="user-input">
      <input type="text" v-model="user.id" />
    </div>
    Name (alerts when changed)
    <div class="user-input">
      <input type="text" @input="emitNameChanged" v-model="user.name" />
    </div>
    LastName
    <div class="user-input">
      <input type="text" v-model="user.lastName" />
    </div>
    FullName
    <div class="user-input">
      <input type="text" v-model="fullName" />
    </div>
    City
    <div class="user-input">
      <input type="text" v-model="user.city" />
    </div>
  </div>
</script>

Leave a comment