Vue Component prop in vuetify component - vue.js

I am not able to pass data to my custom component, my component uses vuetify, currently I dont get any message:
MY component:
<template>
<v-layout>
<v-flex xs12 sm6 offset-sm3>
<v-card>
<v-img
src="https://cdn.vuetifyjs.com/images/cards/desert.jpg"
aspect-ratio="2.75"
></v-img>
<v-card-title primary-title>
<div>
<h3 class="headline mb-0">{{ tenantName }}</h3>
<div>{{ tenantDescription }}</div>
</div>
</v-card-title>
</v-card>
</v-flex>
</v-layout>
</template>
<script>
export default {
data () {
return {
// ...
}
},
props: ['tenantImage', 'tenantName', 'tenantDescription']
}
</script>
And this is how I call in my view:
<tenant-card
imgSrc="https://fuckoffgoogle.de/wp-content/uploads/2017/12/cropped-logo_midres-1.png"
:tenantName="my Name is"
:tenantDescription="this is a description"
></tenant-card>
The component is registered I see it on my view just without any data.
I get this outside in the page source
<div class="layout" tenantimage="https://fuckoffgoogle.de/wp-content/uploads/2017/12/cropped-logo_midres-1.png" tenantname="my Name is" tenantdescription="this is a description">
...

The names of your properties are wrong:
<tenant-card
tenant-image="'https://fuckoffgoogle.de/wp-content/uploads/2017/12/cropped-logo_midres-1.png'"
:tenant-name="'my Name is'"
:tenant-description="'this is a description'">
</tenant-card>
HTML attribute names are case-insensitive. Any uppercase character will be interpreted as lowercase. So camelCased prop names need to use their kebab-cased equivalents.
Edit:
And as already mentioned by #Sergeon you have to add the extra '' to pass an string as a property value

Related

How to use router-link in vue js?

I am a beginner to laravel-vue and I have a problem with router-link when I get data from the database to view, all things work correctly, but when I set the path to router link, it does not work.
The error is like:
Invalid prop: type check failed for prop β€œto”. Expected String, Object, got Undefined found in ---> RouterLink
Here is my template code:-
<template>
<v-card>
<v-card-title primary-title>
<div>
<h3 class="headline mb-0">
<router-link :to="data.path">{{data.title}}</router-link>
</h3>
<div class="grey--text">
{{data.created_at}}
</div>
</div>
</v-card-title>
<v-card-text>
{{data.body}}
</v-card-text>
</v-card>
</template>
This is my script:-
<script>
export default {
props:['data']
}
This is the form template view that I read questions inside it:-
<template>
<v-container fluid grid-list-md>
<v-layout row wrap>
<v-flex xs8>
<question v-for="question in questions"
:key="question.path"
:data=question
>
</question>
</v-flex>
sidebar
</v-layout>
</v-container>
</template>
And this is forum script:-
<script>
import question from './question'
export default {
data(){
return{
questions:{}
}
},
components:{question},
created(){
axios.get('/api/question')
.then(res=> this.questions = res.data.data)
.catch(error=>console.log(error.response.data))
}
}
</script>
Hello is says its expcting a string or an object ,, but it received an undefinded .
how to debug this ?
you should go back in steps
1. check the item you accessing maybe console log it : here it looks fine :to="data.path" but data could be empty or undefined
2 . check the prop for changes :it didnt change
3 . check prop passing :data=question aha !: here is the problem i think you are missing quotes here
it should be :data="question"
<question v-for="question in questions"
:key="question.path"
:data="question"
>
4. this would be where you check your request ... so always check your data with console log , how it is formatted what it contains and then use it ,, if its alright than you probably have soime syntax issue

Property or method X is not defined on the instance but referenced during render

In console I see following messages:
Property or method Id is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property
How to get rid of it?
<template>
<v-content>
<v-container grid-list-md text-xs-center>
<v-layout v-for="person in people" :key="person.Id" row wrap>
<v-flex :key="Id" sm1 hidden-xs-only>
<v-card-text class="px-0">{{ person.Id }}</v-card-text>
</v-flex>
</v-layout>
</v-container>
</v-content>
<template>
<script>
export default {
data: function() {
return {
people: null
}
},
mounted() {
axiosInstance.get("person").then(response => {
this.people = response.data.persons;
});
}
}
</script>
<v-flex :key="Id" sm1 hidden-xs-only>
:key is another syntax for v-bind:key, which is supposed to contain javascript code. In your case, Id is not defined. You probably wanted to use 'Id' string literal.
Use either
<v-flex :key="'Id'" sm1 hidden-xs-only>
or
<v-flex key="Id" sm1 hidden-xs-only>
or define an Id data in your vue instance.

Vuetify timepicker return value to model

I'm using Vuetify timepicker within my project, however after selecting a time it doesn't appear to be updating my model, how can I get it to do this?
This is my component which is using the timepicker:
time-select.vue
<template>
<v-layout row wrap>
<v-flex>
<v-menu
ref="menu"
v-model="menu2"
:close-on-content-click="false"
:nudge-right="40"
:return-value.sync="time"
lazy
transition="scale-transition"
offset-y
full-width
max-width="290px"
min-width="290px">
<v-text-field
slot="activator"
v-model="time"
:label="this.label"
:name="this.name"
prepend-icon="access_time"
readonly></v-text-field>
<v-time-picker
v-if="menu2"
v-model="time"
full-width
#click:minute="$refs.menu.save(time)"
></v-time-picker>
</v-menu>
</v-flex>
</v-layout>
</template>
<script>
export default {
props: [ 'label', 'name', 'value' ],
data () {
return {
time: this.value,
menu2: false,
modal2: false
}
}
}
</script>
And this is how I'm adding the timepicker to my page, as you can see I'm using v-model so the value is updated.
<time-select v-model="hours.open_time"
name="businessHoursTimeFrom[]"
label="Open Time"></time-select>
Don't forget that v-model="someVar" used with custom components is just a shortcut for:
:value="someVar" #input="someVar = $event"
Thus, this:
<time-select v-model="hours.open_time" />
Under the hood is:
<time-select :value="hours.open_time" #input="hours.open_time = $event" />
That means that your custom component should trigger input event itself.
Like this:
<v-time-picker
v-if="menu2"
:value="time"
#input="$emit('input', $event)"
full-width
#click:minute="$refs.menu.save(time)" />
Useful link: Vue.js β†’ Using v-model on components

Using Vuelidate with v-for and props

How are you all using Vuelidate with v-for. I can't seem to get it to work correctly. It either validates each of the text-fields in my form, or it throws an error. I only want it to validate the field that is being entered, and not other fields that are created from v-for.
In the below template you can see the creds in amazonCredsArray are props passed in from the parent component. Depending on the number of hashes in the amazonCredsArray is the number of forms that are created. With the below setup, the text-field below is created multiple times, and Vuelidate validates ALL these fields when just 1 is entered. I have :key defined on the field but it doesn't help.
Template
<template>
<v-container fluid grid-list-lg class="come_closer">
<v-layout row wrap>
<v-flex xs12 v-for="creds in amazonCredsArray" :key="creds.id" class="pb-4">
<v-card class="lightpurple">
<v-card-title>
<v-icon class="my_dark_purple_text">language</v-icon>
<h1 class="title oswald my_dark_purple_text pl-2 pr-5">ENTER YOUR AMAZON CREDENTIALS BELOW</h1>
</v-card-title>
<v-form>
<v-layout xs12 row wrap class="mx-auto" >
<v-flex xs12>
<v-text-field
:error-messages="sellerIdErrors"
required
:key="creds.seller_id"
color="indigo"
label="Amazon Seller Id"
v-model="creds.seller_id"
prepend-icon="person"
#input="$v.seller_id.$touch()"
#blur="$v.seller_id.$touch()"
></v-text-field>
</v-flex>
And my offending script:
Script
import { validationMixin } from 'vuelidate';
import { required } from 'vuelidate/lib/validators';
var url = "https://bc-only-rates-trimakas.c9users.io";
export default {
mixins: [validationMixin],
validations: {
seller_id: { required }
},
props: ["amazonCredsArray"],
computed:{
sellerIdErrors () {
const errors = []
if (!this.$v.seller_id.$dirty) return errors
!this.$v.seller_id.checked && errors.push('Please provide us your seller id')
return errors
},
},

How to trigger a method at component opening in vuejs?

I have a main component that is used to display items using a loop:
<v-list-tile v-for="(item, index) in items" :key="item.title">
...
<report type="item.type"> </report>
</v-list>
The report component is used to report abuse on the system, and report type may vary depending on the item from the parent loop.
As users are very unlikely to use report on a regular basis I would like to only load v-select elements when the Dialog (modal) is opened.
Using created or mounted triggers the loading method everytime the report component is generated and not when the report component is opened.
Is there a smart way to prevent this and only have the loading method within report being triggered only when the component is opened.
=== Report.vue file ===
=== This file is loaded in the parent component
<template lang="html">
<v-dialog v-model="dialog" persistent max-width="800px" lazy>
<v-btn icon slot="activator">
<v-icon>error_outline</v-icon>
</v-btn>
<v-card>
<v-card-title>
<div class="headline"><v-icon large>error_outline</v-icon> Reporting</div>
</v-card-title>
<v-card-text>You are about to report the following {{ reportType }}: "<i>{{ reportContent.title }}</i>"
<v-container v-if="this.$store.getters['report/getLoadedState']" grid-list-md >
<v-layout wrap>
<v-flex xs12 sm12>
<v-select
label="Select a reason"
required
cache-items
:items="items"
item-text="title"
item-value="id"
></v-select>
</v-flex>
<v-flex xs12 sm12>
<v-text-field
label="Please provide additional information here"
multi-line></v-text-field>
</v-flex>
</v-layout>
</v-container>
<v-container v-else grid-list-md>
<v-layout>
<v-flex xs12 sm12>
Loading
</v-flex>
</v-layout>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="green darken-1" flat="flat" #click.native="cancel">Cancel</v-btn>
<v-btn color="green darken-1" flat="flat" #click.native="report">Report</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
export default {
name: 'report',
data () {
return {
dialog: false,
items: this.$store.getters['report/getItems']
}
},
props: ['reportType', 'reportContent'],
methods: {
cancel () {
this.dialog = false
},
report () {
this.dialog = false
},
loadReasons (type) {
if (!this.$store.getters['report/getLoadedState']) {
this.$store.dispatch('report/setItems', type)
}
}
}
}
</script>
<style lang="css" scoped>
</style>
PS 1: I'm not using JQuery and do not intend to use it
PS 2: Calling the method outside of the report component is not an option as I want to maximize reusability of this compenent and only pass arguments to it using props
How I have done this in the past is to use a "dynamic component." Vue uses a special syntax for dynamic components <component v-bind:is="currentView"></component> see: Vue dynamic components
You can set the "currentView" property to null and then on a button click another event set the currentView to report. Doing it this way will allow you to use the mounted method as the component is not rendered or created until it is dynamically called.
<component :is="myComponent"></component>
<v-btn #click="loadComponent">Show Report</v-btn>
then...
data:{
myComponent: null;
},
methods: {
loadComponent: function(){
this.myComponent = 'report';
}
}
P.S. You can of course use this method to render any other components in the same place. i.e. you can set the 'currentView' to the name of any available component and it will be instantly rendered in its place.
I ended up using a watch on the boolean managing the dialog...
Make a function which loads the v-select. Don't initialize it just create it. Now whenever user clicks the report model you can initialize multiple functions using v-on:click or #click.
For example :
<div v-on:click="return function() { fn1('foo');fn2('bar'); }()"> </div>
This solution can also be found on :
Stackoverflow Link