Use Vue prop as part of function declaration - vue.js

I use vue-select in my Vue app. I created a component as a wrapper for v-select. To return only a specific column of the options array, I use the :reduce prop of vue-select.
<template>
<span>
<label v-if="title">{{title}}</label>
<v-select
:options="options"
:label="label"
:placeholder="placeholderText"
:close-on-select="closeOnSelectValue"
:disabled="isDisabled"
:multiple="multiple"
:value="value"
#input="handleInput($event)"
:loading="isLoading"
:reduce="option=> option.val"
></v-select>
</span>
This code works, but I would like to have the static val string to be the dynamic prop returnKey. This would be passed to the component as a prop.
props: {
returnKey: {
type: String,
default: null,
},
}
What syntax should I use to make a combination of the 'option' string and the dynamic value of 'returnKey' in the function passed to :reduce to get this working?

You can use the bracket notation and do option => option[returnKey].
And as what Richard has suggested, in order to avoid runtime error you might want to provide some kind of fallback, or enforce that returnKey must be a required prop.

You can try something like this
<template>
<span>
<label v-if="title">{{title}}</label>
<v-select
:options="options"
:label="label"
:placeholder="placeholderText"
:close-on-select="closeOnSelectValue"
:disabled="isDisabled"
:multiple="multiple"
:value="value"
#input="handleInput($event)"
:loading="isLoading"
:reduce="reduceKey"
></v-select>
</span>
</template>
<script>
export default
{
props: {
returnKey: {
type: String,
default: null,
},
},
methods:
{
reduceKey(option)
{
return option[this.returnKey] || option;
}
}
}

Related

Vue onEnable/onDisable event

In my vue application I need to observe an element getting enabled/disabled (It binds to a function) and by looking that I need to trigger an onEnabled/onDisabled event which will clean up some other data nodes.
So is there a listener like #click, #enabled or something?
Eg:
<v-checkbox :value="getValue(layout.responseNode)" #change="setValue(layout.responseNode, $event)" :label="expression(layout.label)" :disabled="expression(layout.enableIf)" ></v-checkbox>
This is the code so far with me. here enableIf will be a dynamic expression from server.
Its properly working now.
Now I need to run some more expression like
<v-checkbox :value="getValue(layout.responseNode)" #change="setValue(layout.responseNode, $event)" :label="expression(layout.label)" :disabled="expression(layout.enableIf)" #onDisabled="expression(layout.disableCommand)" ></v-checkbox>
Is there an event matching onDisabled?
i would recommend watchers you can bind a variable/computed to :disabled of the checkbox and watch the value changing
exp.
<template>
<div>
<p>{{ checkboxState }}</p>
<input type="checkbox" :disabled="checkboxState" />
<button #click="checkboxChanged()">Disable Checkbox!</button>
</div>
</template>
<script>
export default {
name: "App",
data: () => {
return {
checkboxState: true,
};
},
methods: {
checkboxChanged() {
this.checkboxState = !this.checkboxState;
},
},
watch: {
checkboxState() {
// this is fired when the checkboxState changes
console.log("fired when checkboxState changes");
},
},
};
</script>
note: the function name and the variable must have the same name for watchers to work.
Like this Sandbox

How to return date format from Bootstrap-vue's b-form-timepicker component from HH:mm:ss to HH:mm

Bootstrap-vue b-form-timepicker returns the value as with the format HH:mm:ss. I need its return value as HH:m', but I cannot find any way to change it.
Is there any way to change the return value format into HH:mm? If there is, please help.
You can remove the seconds by removing the property show-seconds as described in the component table properties. Then we'll format the date using vanilla JavaScript inside a Vue's watcher like so:
<template>
<div>
<label for="example-input">Choose a time</label>
<b-input-group class="mb-3">
<b-form-input
id="example-input"
v-model="value"
type="text"
placeholder="HH:mm"
></b-form-input>
<b-input-group-append>
<b-form-timepicker
v-model="value"
button-only
right
locale="en"
aria-controls="example-input"
></b-form-timepicker>
</b-input-group-append>
</b-input-group>
<p>Value: '{{ value }}'</p>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
value: "",
};
},
watch: {
value() {
this.value = this.value.split(':').slice(0,2).join(':');
},
},
};
</script>
You can check this working code playground example.

Problem with watching prop changes Vue.js

What's the problem
I wanted to assign a local component variable to prop. I constantly get Vue alert Invalid watch handler specified by key "undefined". Maybe the case is that the prop is passed from another component, where I use v-model, but I don't really know. I would really appreciate your help, because my small exercise project really depends on this mechanic.
Parent Component
Here I have some HTML select, this is where I actually model my state.selectedPhysicsModule
<template>
<div>
<div>
<h1>Some header</h1>
</div>
<form class="choosePhysicsModule">
<label for="selectedPhysicsModule"></label>
<select class="select_Module" id="selectedPhysicsModule" v-model="state.selectedPhysicsModule">
<option :value="option.value" v-for="(option, index) in importedListToSelect" :key="index">
{{option.name}}
</option>
</select>
</form>
<list_of_exercises v-if="state.selectedPhysicsModule" :what_exercises="state.selectedPhysicsModule"/>
</div>
</template>
<script>
export default {
name: 'ChoosePhysicsModule',
components: {list_of_exercises},
setup() {
const state = reactive({
selectedPhysicsModule: null,
})
return {
state,
importedListToSelect
}
}
}
Child Component
</script>
export default {
name: "list_of_exercises",
props: {
whatExercises: {
type: String,
required: true
}
},
data() {
return {
exercises: this.what_exercises,
}
},
watch: {
whatExercises: function () {
this.exercises = this.whatExercises
}
}
In the parent component where you are passing the prop you need to add a setter for the prop passed. Here is an example:
<template>
<div id="app">
<label>
<input name="whatExercises" v-model="whatExercises">
</label>
<ListOfExercises v-if="whatExercises" :what_exercises="whatExercises" />
</div>
</template>
<script>
export default {
data() {
return {
whatExercises: null,
}
}
}
</script>
P.S: as a side note, I recommend using camelCase for prop names. It's more in-line with the rest of the community. If you have time feel free to check out the style guide on the official website.

Vue + Vuetify submitting form with GET method passes empty values

I have a problem with my code. I can't find a reason why my GET parameters are empty when the form is submitted.
What I'm trying to achieve is to submit the form after validation and be redirected to http://someurl.com/?service=3&propert_type=2. Is it even possible? Or do I need to stringify it and then use window.location?
I'm a newbie at Vue, but can't find the internet for a solution so I guess it's something to do with my code.
<template>
<ValidationObserver v-slot="{ valid }" ref="getanoffer">
<v-form
class="form form--getanoffer"
ref="form"
>
<ValidationProvider
rules="required"
v-slot="{ errors }"
name="service"
>
<v-select
v-model="service"
name="service"
:items="services"
placeholder="Select Service"
:error-messages="errors"
solo
></v-select>
</ValidationProvider>
<ValidationProvider
rules="required"
v-slot="{ errors }"
name="property_type"
>
<v-select
v-model="property_type"
:items="property_types"
name="property_types"
item-text="name"
item-value="id"
placeholder="Select Property Type"
:error-messages="errors"
solo
></v-select>
</ValidationProvider>
<v-btn
color="primary"
width="100%"
#click="validate"
class="v-btn--submit v-btn--no-gutter"
:loading="loading"
:disabled=" ! valid"
>
Continue
</v-btn>
</v-form>
</ValidationObserver>
</template>
<script>
import {ValidationProvider, ValidationObserver} from "vee-validate";
export default {
components: {
ValidationProvider,
ValidationObserver,
},
data() {
return {
service: null,
property_type: null,
form: {
},
loading: false,
}
},
props: {
services: {
type: Array,
},
property_types: {
type: Array,
}
},
methods: {
async validate() {
let form = await this.$refs.getanoffer.validate();
if (form) {
this.loading = true;
this.submit();
this.$refs.form.$el.submit();
}
},
submit() {
}
}
}
</script>
Lets simplify your code
Instead of calling validate() on button click, you can add type="submit" to your button and in your form you can add #submit:prevent="validate". This doesn't solve the problem but allows you to submit with Enter and every submit button will trigger the validation.
Now for the solution
1- To navigate to external scope you can use windows.open(). Vuetify lets you navigate to an url but you had to put href on your button and control it manually
windows.open('http://someurl.com/')
CodePen
Vuetify vee-validate docs
Javacript standards say that you should use camelCase for js variables (this.propertyType)
JS standard
ESlint Rules

Vuetify Form Data Undefined

i'm trying my form data submit. when i try my code
form.append('subject',"hello"),
It is good working. but form.append('subject', 'this.subject') => return 'undefined'. how do i solve it?
form.append('subject',"hello"), it is good working. but form.append('subject', 'this.subject') => return 'undefined'.
My Write.vue is :
<template>
<v-form #submit.prevent="sendPost" id="WriteForm" method="post">
<v-btn icon type="submit" form="WriteForm"><v-icon>send</v-icon></v-btn>
<v-text-field name="subject"></v-text-field>
<v-textarea name="context"></v-textarea>
</v-form>
</template>
<script>
export default {
data(){
return{}
},
methods: {
sendPost: function(){
console.log(this.subject); //==> undefined :(
console.log(this.context); //==> undefined :(
}
}
</script>
You should add that properties to your data object and bind them to the v-text-field as follows :
data(){
return{
subject:'',
context:''
}
}
and bind them using v-model directive in your template fields like :
<v-text-field name="subject" v-model="subject"></v-text-field>
<v-textarea name="context" v-model="context"></v-textarea>