The changes are not reflected in DOM, even when the data is changing properly. Here is a very basic example to demonstrate the issue -
<template>
<input type="text" v-model="username" />
<p>{{error}}</p>
<button #click="saveData">Save</button>
</template>
<script>
export default {
data () {
model.error = ''; // adding a new property
return model; // 'model' is a global variable
}
methods: {
saveData() {
if (!this.username) {
this.error = 'Please enter the username!';
return;
}
// ... other code
}
}
};
</script>
After calling saveData() the error variable contains the message if username is not filled. But it's not showing up in the paragraph.
There is a trick. If I also change the username property when the error variable is changed, the changes are reflected.
You need to return error or Vue doesn't have access to it.
data () {
return {
error: '',
model: model,
};
}
You should be able to achieve what you're trying to do, as long as error and username properties are defined on model for data. I've included a simple snippet below, showing it working. Take a look at Declaring Reactive Properties in the documentation.
var model = {
username: "Default"
};
new Vue({
el: "#app",
data: () => {
model.error = model.error || "";
return model;
},
methods: {
updateError() {
this.error = "Test";
},
updateUsername() {
this.username = "Hello, World!";
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button type="button" #click="updateError">Update Error</button>
<button type="button" #click="updateUsername">Update Username</button>
<div>Error: {{error}}</div>
<div>UserName: {{username}}</div>
</div>
Related
I'm wondering if I am able to get a components data, the count property in this instance and console.log it into normal javascript, is this possible? I'm wanting to do console.log(btn.data.count) in this case
<div id="app" v-cloak>
<h1>{{greeting}}</h1>
<button-counter></button-counter>
</div>
<script src="https://unpkg.com/vue#next"></script>
<script>
let app = Vue.createApp({
data: function(){
return {
greeting: "hi"
}
}
})
let btn = app.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
console.log(btn.data.count) // doesn't work
app.mount("#app")
</script>
There might be multiple instances of the button-counter component, so you cannot ask for the count.
You can only access the data from within the component itself. For example from within a method that handles the click event:
let btn = app.component('button-counter', {
data: function () {
return {
count: 0
}
},
methods: {
onClick() {
console.log(this.count)
this.count++
}
},
template: '<button v-on:click="onClick">You clicked me {{ count }} times.</button>'
})
You can use console.log normally you just need to use it where it makes sense. It does not make sense using it before #app is mounted.
Try writing a method for your count++ and add console log there you will see that it gets executed every time.
How can I set a value input that uses the v-model?
I Googled for this problem but not solved
I have an input like this:
<input type="text" name="customer_email" v-model="form.customer_email" id="email">
I need to set this input value to {{ auth()->user()->email }}
TRY THIS :)
data() {
return {
form: {
customer_email: "",
}
}
},methods:{
user(){
axios.get("api/profile").then(({data})=>{
(this.user = data)
this.form.customer_emeail = this.user.email
})
},
},created(){
this.user();
}
In your controller add this
public function profile()
{
return auth('api')->user();
}
then put this in your api.php
Route::get('profile','YourController#profile');
As you are using two way data binding v-model, you can simply set this value in the vue end.
let app = new Vue({
el:"#app",
data() {
return {
form: {
customer_email: "{{ auth()->user()->email }}",
......
......
}
}
},
......
......
});
new Vue({
el: "#app",
data: {
msg: "hello world"
},
methods: {
trigger: function() {
var fileLoader = document.getElementById('fileLoader');
//clear file value
if(fileLoader.files.length > 0) {
fileLoader.value == null;
alert(fileLoader.files[0].name);
}
fileLoader.click();
},
fetchData: function() {
console.log('hello');
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
<button #click="trigger">upload image</button>
<input type="file" id="fileLoader" v-show="false" #change="fetchData">
</div>
as you know in chrome, when you first time choose a file, input will trigger onchange event, but second time you choose the same file , input won't trigger onchange event,so i want to set input's value to null,before choose the same file, which works using jquery or plain javascript. but in vuejs, it dosen't work. what's the problem?
You are doing a comparison instead of an assignment:
fileLoader.value == null;
This should be:
fileLoader.value = null;
Also this means you won't be able to alert the filename after you have done this, because the value has already been cleared by then. So this line should come before you clear it:
alert(fileLoader.files[0].name);
new Vue({
el: "#app",
data: {
msg: "hello world"
},
methods: {
trigger: function() {
var fileLoader = document.getElementById('fileLoader');
//clear file value
if(fileLoader.files.length > 0) {
alert(fileLoader.files[0].name);
fileLoader.value = null;
}
fileLoader.click();
},
fetchData: function() {
console.log('hello');
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
<button #click="trigger">upload image</button>
<input type="file" id="fileLoader" v-show="false" #change="fetchData">
</div>
I am learning Vuejs and I am stuck. Why can I see the messages get added to the object (in Chrome Vue debugger) yet it is not added to the div that contains the list?
My Vue Component:
<template>
<div id="round-status-message" class="round-status-message">
<div class="row">
<div class="col-xs-12" v-for="sysmessage in sysmessages" v-html="sysmessage.message"></div>
</div>
</div>
</template>
<script>
export default {
props: ['sysmessages'],
methods: {
scrollToTop () {
this.$el.scrollTop = 0
}
}
};
</script>
My Vue instance:
$(document).ready(function()
{
Vue.component('chat-system', require('../components/chat-system.vue'));
var chatSystem = new Vue({
el: '#system-chat',
data: function () {
return {
sysmessages: []
};
},
created() {
this.fetchMessages();
Echo.private(sys_channel)
.listen('SystemMessageSent', (e) => {
this.sysmessages.unshift({
sysmessage: e.message.message,
});
this.processMessage(e);
});
},
methods: {
fetchMessages() {
axios.get(sys_get_route)
.then(response => {
this.sysmessages = response.data;
});
},
processMessage(message) {
this.$nextTick(() => {
this.$refs.sysmessages.scrollToTop();
});
// updateGame();
}
}
});
});
My template call in HTML:
<div id="system-chat">
<chat-system ref="sysmessages" v-on:systemmessagesent="processMessage" :sysmessages="sysmessages" :player="{{ Auth::user() }}"></chat-system>
</div>
There are no compile or run time errors and I can see records added to the props in the vue chrome tool. I can also see empty HTML elements added to the div.
What have I missed?
UPDATE: My record structures:
response.data is an array of objects, each like this:
{"data":[
{"id":100,
"progress_id":5,
"message":"start message",
"action":"welcome"
},
{"id"....
e.message.message contains the text message entry, so just a string.
I am trying to access the message variable in each object during the fetchMessages method.
You're adding objects with sysmessage as the property.
this.sysmessages.unshift({
sysmessage: e.message.message,
});
But you are trying to view
v-for="sysmessage in sysmessages" v-html="sysmessage.message"
Based on your update, the code should be:
this.sysmessages.unshift({
message: e.message.message,
});
And you can leave the template as
v-html="sysmessage.message"
I'm having my practice in VueJS 1.0 and I am learning about Components.
in this example, there is an input element and has to supply coupon or some kind of a code from an API. and I have to validate. I have my <coupon > component and has props of when-applied. The when-applied must call the parent function setCoupon but it won't.
I only got this error this.whenApplied is not a function.
<div id="demo" class="list-group">
<script id="coupon-template" type="x-template">
<input type="text" v-model="coupon" v-on:blur="whenCouponHasBeenEntered">
<div v-text="text"></div>
</script>
<coupon when-applied="setCoupon"></coupon>
</div>
Here is my app.js file
Vue.component('coupon', {
template: '#coupon-template',
props: ['whenApplied'],
data: function() {
return {
coupon: '',
invalid: false,
text: ''
}
},
methods: {
whenCouponHasBeenEntered: function() {
this.validate();
},
validate: function() {
if( this.coupon == 'FOOBAR') {
this.whenApplied(this.coupon);
return this.text = '20% OFF!!';
}
return this.text = 'that coupon doesn`t exists';
}
}
});
new Vue({
el: '#demo',
methods: {
setCoupon: function(coupon) {
alert('set coupon'+ coupon);
}
}
});
Someone pls help. Suggestions pretty much appreciated.
You should bind the property:
<coupon v-bind:when-applied="setCoupon"></coupon>
or you could use the shorthand syntax for v-bind:
<coupon :when-applied="setCoupon"></coupon>
Read more about the props here.