I'm currently using a vue datepicker which, when a date is selected, shows pickedValue as the value for the selected date in vue developer tools:
<div v-cloak v-if="isScheduledTask">
<datepicker value="" name="pickedValue" id="pickedValue" ></datepicker>
</div>
Trying to set the pickedValue to a variable in my data return (i need the picked value to be submitted with other data here) as a $ref is breaking the page. If I change this to just datepicker.pickedValue then it's undefined. What am I doing wrong here?
data() {
return {
pickedValue: this.$refs.datepicker.pickedValue
}
}
It's very bad pattern, but you have no choice working with library that does not emit ANY events.
DON'T DO IT EVER AGAIN!!!
<datepicker ref="datepicker" #click.native="method"></datepicker>
data() {
return {
value: ''
}
},
methods: {
method() {
this.value = this.$refs.datepicker.pickedValue
},
},
Try to use v-model directive to bind your datepicker to that data property pickedValue as follows :
<div v-cloak v-if="isScheduledTask">
<datepicker value="" name="pickedValue" v-model="pickedValue" ></datepicker>
</div>
script :
data() {
return {
pickedValue: ''
}
}
Related
I have a Nuxt project with Buefy components. There is a form with some field component which should react on error according the message parameter for this component. But does not. I can see the correct value in debuger but component does not show the message. :message property should work like the in first email example from documentation
The code looks like:
<template #company>
<h2 class="title">{{ $t('general.login.create_company') }}</h2>
<b-field
:type="loginErrors.company_name ? 'is-danger' : ''"
:message="loginErrors.company_name ? loginErrors.company_name : ''"
>
<b-input
v-model="companyName"
name="company_name"
type="text"
autocomplete="off"
:placeholder="$t('general.login.create_company')"
></b-input>
</b-field>
<div class="buttons is-centered">
<b-button type="is-primary is-light" #click="createCompany">Save</b-button>
</div>
</template>
...
data() {
return {
...
loginErrors: {},
error: 'aaaaaa',
};
},
...
async createCompany() {
const result = await this.$api.users.createCompany({company_name: this.companyName});
if( result.error ) {
this.loginErrors.company_name = result.error; // This does not work although the variable has correct value set
this.error = result.error; // This works fine
return false;
}
},
I use this pattern in other components and it works. I dont understand it. thaks for any help.
change detection of data objects in Vue is shallow (top level only)
In vue.js, Dynamically added property to an object is not reactive. Instead we can assign a whole object so that change detection happen.
For a better understanding please go through this official documentation of Vue.
Demo :
new Vue({
el: '#app',
data() {
return {
loginErrors: {}
}
},
mounted() {
this.loginErrors = {
company_name: 'some value'
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<p>{{ loginErrors.company_name ? 'is-danger' : 'no-danger' }}</p>
</div>
I don't think Vue components react to object property changed in a direct way, you could try this.$set(this.loginErrors, 'company_name', result.error); instead of this.loginErrors.company_name = result.error;
FYI: https://v2.vuejs.org/v2/guide/reactivity.html?redirect=true#Change-Detection-Caveats
The solution in this case was to update Buefy version from 0.4.11 to 0.4.21. This fix the issue. Another thing is that is causes new issue with :type in combination with grouped param.
I'm having a problem that v-text-field with type="number" attr sets it's value to empty string after it's cleared manually. I need it to return null in such cases.
Is there an attribute like :clear-value="null" ?
I can't find anything in the docs: https://vuetifyjs.com/en/api/v-text-field/#props
Given that v-model is shorthand for combining v-bind:value & v-on:input, the best workaround I could come up with was splitting up v-model into separate v-bind:value and v-on:input properties.
For the v-on:input property, we can coerce the value to null.
So, given an existing field like this:
<v-text-field
type="number"
v-model="myValue"
></v-text-field>
It can be changed to this:
<v-text-field
type="number"
:value="myValue"
#input="myValue = $event !== '' ? $event : null"
></v-text-field>
You can use watch and watch for the value when it is changed to an empty string then replace it with null. However, this will always return null if you clear the textfield using the 'x' button, or when you empty the textfield manually.
<v-textfield v-model="myValue" ... />
// script
data() {
return {
myValue: 1
}
},
watch: {
myValue(newVal){
if(newVal === '') {
this.myValue = null;
}
}
}
You can use #click:clear event...
v-text-field
v-model="myValue"
clearable
#click:clear="setItNull()"
type="number">
</v-text-field>
Bind it to a method that set the value to null...
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
myValue: 1
}
},
methods: {
setItNull () {
this.myValue === null
},
},
})
Demo
I need to update my value which is in JSON thru v-model
{ class: "data.child",
"myform.input1": [true, "<input1 value>"]
}
<input type="text" v-model="<what to put here?>" > //so that directly value can be update in my vue data property JSON mentioned above
Cant do it directly with v-model, unless you want to change your input type to maybe multi select.
If you really want the exact output, can listen onchange event like below.
Or can just use v-model and enter your data as you want...but will need to convert to array.
const jsonData = { class: "data.child",
"myform.input1": [true, "<input1 value>"],
"myform.input2": [true, "<input1 value>"]
}
const App = {
template: `<div>
<input type="text" v-model="data['myform.input2']"/>
<input type="text" #change="update"/>
<p>{{JSON.stringify(data, null, 2)}}</p>
</div>`,
methods: {
update: function(event) {
this.data['myform.input1'] = [true, event.target.value];
}
}
,
data(){
return {data: jsonData}
}
}
new Vue({
render: h => h(App),
}).$mount("#app");
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
</div>
I'm trying to have my vue file accept an array of objects from the parent and create a multiselect with it but the vue template keeps rendering before my variables can initialize so I get a message saying the array that the multiselect is using is equal to null
I have tried creating using a computed, mounted, and created, component to the file but nothing seems to work
<template>
<div id="my-app">
<multiselect v-model="value" :options="prop2" :custom-label="FullName" placeholder="Select one" label="name" track-by="_id" #update="updateProp1()"></multiselect>
<pre class="language-json"><code>{{ value }}</code></pre>
</div>
</template>
<script>
import Multiselect from 'vue-multiselect'
export default {
name: "comp",
components: {
Multiselect
},
props: ['prop1', 'prop2'],
data: function() {
return {
value: null,
}
},
created: function(){
this.getProp1();
},
computed: {
prop2() {
return this.prop2;
}
},
methods: {
FullName ({ FirstName, LastName }) {
return FirstName + " " + LastName
},
getProp1(){
for(var p2 in this.prop2){
if(this.prop1 == p2._id){
this.value = prop1;
break;
}
}
},
updateProp1(newProp1){
this.prop1 = newProp1;
}
}
}
</script>
I'm expecting a multiselect with default values in the "value" variable and the all the available options in the "options" variable. Selecting anything with the multiselect will overwrite the "value" variable. Though what I'm actually getting is two empty arrays that sometimes works. I think this is happening because vue is asynchronous but even knowing that I'm not sure how I can prevent it.
I would like to call a function with a value when a user starts typing in an input box. I have tried two approaches.
The first approach is trying to use two-way binding to a model. However, after following the documentation I get an error.
Here is the example from the official docs:
<div id="app-6">
<p>{{ message }}</p>
<input v-model="message">
</div>
var app6 = new Vue({
el: '#app-6',
data: {
message: 'Hello Vue!'
}
})
And here's my example:
<template lang="html">
<input
type="text"
v-model="handle"
/>
</template>
<script>
export default {
data: {
handle: 'model',
}
};
</script>
I am writing this as part of an application so I chose not to recreate the Vue instance and I declared that elsewhere. However, I get this error:
Property or method "handle" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
A second approach I've tried is this calling a function directly from the view via an event handler. I'm coming from React so this is my preferable approach. However, the function has undefined as an input value meaning it's not picking up the value of the input.
<template lang="html">
<input
type="text"
v-on:keyup="handleInput()"
/>
</template>
<script>
export default {
methods: {
handleInput(input) {
// input -> undefined
},
},
};
</script>
I really can't see why neither of these works. Wouldn't the expected behavior of an input listener would be to pass the value?
Where am I going wrong?
It seems like you might have to do something like this: How to fire an event when v-model changes ? (vue js). What I don't understand is why you have to manually attach a watcher when you have assigned a v-model? Isn't that what a v-model is supposed to do?
What finally worked was this:
<template lang="html">
<input
type="text"
v-model="searchTerm"
#keyup.enter="handleInput"
/>
</template>
<script>
export default {
data() {
return { searchTerm: '' }
},
methods: {
handleInput(event) {/* handle input */},
},
};
</script>
Shouldn't data be a function on your first example? I think this is how it works for vue components.
<script>
export default {
data: function () {
return { handle: 'model' }
}
};
</script>
I think this was explained somewhere on vuecasts.com, but I might be wrong. :)