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:
/*****************************/
/* 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>