Reputation: 1132
I am trying to set up a vue app that makes a request to a backend and then displays the result on the page. I cooked up this example
new Vue({
data: {
message: '{}'
},
el: '.login-app',
});
Vue.component('message-section', {
template: '<div>Message Section</div>'
});
Vue.component('login-component', {
template: '<div><button v-on:click="login(\'[email protected]\', \'passwd\')">Login</button></div>',
methods: {
login: function (username, password) {
axios.post("http://192.168.1.10:8080/login", {username: username, password: password})
.then(response => {this.message = response.data})
}
}
});
and an index like:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Vue Test</title>
</head>
<body>
<div class="login-app">
{{ message }}
<message-section></message-section>
<login-component></login-component>
</div>
<script src="/static/testvue.bundle.js"></script>
</body>
</html>
The idea being a simple app that should send a username/password and get back something like "success" or whatever that it can display. But I am completely unfamiliar with vue and javascript so I am getting stuck. I am not sure how to make the response show up anywhere. I have a {{ message }} in there but it doesn't do anything. All I see is the {} from the "message" attribute of the Vue object getting rendered in I guess. And those user/pass is hard coded... I am not sure how to make it work with a form field.
I can see the data getting sent to the backend though so I know that's working...
Additionally, how can you structure a Vue project so it's broken into multiple "modules" or whatever?
Edit:
If I change it so there's only one component like so:
new Vue({
data: {
message: '{}'
},
el: '.login-app',
methods: {
login: function (username, password) {
axios.post("http://192.168.91.30:8080/login", {username: username, password: password})
.then(response => {this.message = response.data})
}
}
})
and
<div class="login-app">
{{ message }}
<button v-on:click="login(\'[email protected]\', \'passwd\')">Login</button>
</div>
Then nothing renders at all... This should have put them inside the same container or whatever, right?
Upvotes: 2
Views: 18353
Reputation: 4438
The problem is your component login-component
doesn't have access to the message
property, which belongs to the root Vue app.
One way to fix this is simply put the message
to the component instead:
Vue.component('login-component', {
template: '<div><button v-on:click="login(\'[email protected]\', \'passwd\')">Login</button></div>',
data() {
return { message: '' }
},
methods: {
login: function (username, password) {
axios.post("http://192.168.1.10:8080/login", {username: username, password: password})
.then(response => {this.message = response.data})
}
}
});
But if message
is not a property that you login-component
to have solely access to, you may have to consider Vuex
or emitting custom events (this and this).
Upvotes: 1
Reputation: 82439
Here is your edited code working.
console.clear()
new Vue({
data: {
message: '{}'
},
el: '#login-app',
methods: {
login: function(username, password) {
axios.post("https://httpbin.org/post", {username, password})
.then(response => this.message = response.data.json)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.17.1/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.min.js"></script>
<div id="login-app">
{{ message }}
<button v-on:click="login('[email protected]', 'passwd')">Login</button>
</div>
Here it is working from a component.
console.clear()
Vue.component('login-component', {
template: `
<div>
<button v-on:click="login('[email protected]', 'passwd')">Login</button>
</div>`,
methods: {
login: function(username, password) {
axios.post("https://httpbin.org/post", {username, password})
.then(response => this.$emit('login-success', response.data.json))
}
}
});
new Vue({
data: {
message: '{}'
},
el: '#login-app',
methods: {
onSuccess(message) { this.message = message }
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.17.1/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.min.js"></script>
<div id="login-app">
{{ message }}
<login-component @login-success="onSuccess"></login-component>
</div>
In this second example, note that message
is a data property of the parent; the root Vue. The login-component
does not have direct access to message
. That being the case, if the ajax call is made in the component, in order to set message
the value has to be emitted from the component. The code does that by emitting the custom event, login-success
with the success value passed as a parameter. The parent listens for that event with the following syntax:
<login-component @login-success="onSuccess"></login-component>
Upvotes: 4