Components are meant to be reused, it would not be necessary to use mixin , which is reuse of component fragments.
You have two problems there:
Mixin Injects values into components, but their values are not shared
Mixin is meant for you not to need to repeat codes on distinct components that have some common function / data, but they are not shared with each other, one, does not change that of the other, Vue does not allow this¹.
Since you are using mixin within the login
component that < > userform
, you are only replicating the userform
value within login
(you can check out the VueDevTools ).
Butthisisnotthecauseofyourproblem,solet'sgotoit...
Call
userform
directly,causesyoutoselectthe
userform
Login
andnotthe
userform
componentitself.
I'mnotsureifthisisthebehavior,butcallinguserform
you'recallingtheinstantiatedobjectwithincomponents:{userform}
,sothinktome,andifyouhad2<userform>
tags,whichonewouldyouaccess?Reactivityisinherenttoeachcomponent,independently.
[tl;dr]Soittakesthevalueoftheuserform
object,whichiswiththedefaultvalues,whichwillonlychangeifyoumovetheobject,buteventhen,withoutchangethevalueofthecomponents,whicharealreadyotherobjects.
Solution: Reference
One way to work around this problem is to use the references.
To use them, you must add ref
property to the component and access it using
this.$refs.nome_da_ref.nome_do_dado
.
Ex (component myComponent.vue):
<template>
<input v-model='x'>
</template>
<script>
export default {
data (){
return {
x: 10
}
}
}
<script>
Ex (Test.vue component):
<template>
<my-component ref='meuComponent'>
</template>
<script>
import myComponent from './myComponent'
export default {
components: { myComponent }
methods: {
showData() {
console.log(this.$refs.x);
}
}
}
<script>
As soon as you change the input value of <my-component>
the reactivity works and the showData()
method will print the value entered.
Result
Some changes need to be trade shows in the login component:
Remove mixin
Add the reference
Change your method to use the reference instead of the object
Code:
<template>
<section class="col-md-4 col-md-offset-4">
<userform ref='meuForm'></userform>
<button @click="sendLogin()">
Logar
</button>
</section>
</template>
<script>
import userform from './../../forms/userform.vue'
export default {
name: "login",
components: {userform},
methods: {
sendLogin() {
console.log( "Usuario " + this.$refs.meuForm.login )
console.log( "Senha " + this.$refs.meuForm.password )
}
}
}
</script>
This should resolve.
Recommendations and Conventions
-
If you want to use the same data globally, for several components in the same view, I suggest you take a look at Vuex .
-
Use some prefix in your components, this may prevent later headaches (third-party components with the same name, components already in HTML, etc.).
Ex: <lvcsUserForm>
or <lvcs-user-form>
.
-
Treat components as objects that are by using camelCase in their names during import
, and repeat them in the files.
This even helps you, since you do not need the name
attribute in the component, and it can have your tag written in two ways, with PascalCase or kebab-case , but this is defined by the name used in import
, as import MeuForm from './../../forms/userform'
can be used as <MeuForm>
or <meu-form>
.
* Note: The same does not work for props
, they must be named in camelCase and will always be written in kebab-case in the component, eg. <meu-form my-prop="10">
.