vuetify autocomplete preload - javascript

i'm learning vuetify framework, i managed to use most of the components but i have a problem with autocomplete component.
Using it from scratch works fine, bug if i try to set value during creation it doesn't work at all.
I tried to extend one of the vuetify example but without success.
i would like to load first value from the API during creation but it stays empty.
Thanks for your help.
new Vue({
el: '#app',
data: () => ({
descriptionLimit: 60,
entries: [],
isLoading: false,
model: null,
search: "Cats"
}),
created :function() {
model={"API":"Cats","Description":"Pictures of cats from Tumblr","Auth":"","HTTPS":true,"Cors":"unknown","Link":"https://thecatapi.com/docs.html","Category":"Animals"},
search="Cats"
},
computed: {
fields () {
if (!this.model) return []
return Object.keys(this.model).map(key => {
return {
key: key,
value: this.model[key] || 'n/a'
}
})
},
items () {
return this.entries.map(entry => {
const Description = entry.Description.length > this.descriptionLimit
? entry.Description.slice(0, this.descriptionLimit) + '...'
: entry.Description
return Object.assign({}, entry, { Description })
})
}
},
watch: {
search (val) {
// Items have already been loaded
if (this.items.length > 0) return
this.isLoading = true
console.log("loadgin data")
// Lazily load input items
axios.get('https://api.publicapis.org/entries')
.then(res => {
const { count, entries } = res.data
this.count = count
this.entries = entries
})
.catch(err => {
console.log(err)
})
.finally(() => (this.isLoading = false))
}
}
})
<div id="app">
<v-app id="inspire">
<v-card
color="red lighten-2"
dark
>
<v-card-title class="headline red lighten-3">
Search for Public APIs
</v-card-title>
<v-card-text>
Explore hundreds of free API's ready for consumption! For more information visit
<a
class="grey--text text--lighten-3"
href="https://github.com/toddmotto/public-apis"
target="_blank"
>the Github repository</a>.
</v-card-text>
<v-card-text>
<v-autocomplete
v-model="model"
:items="items"
:loading="isLoading"
:search-input.sync="search"
color="white"
hide-no-data
hide-selected
item-text="Description"
item-value="API"
label="Public APIs"
placeholder="Start typing to Search"
prepend-icon="mdi-database-search"
return-object
></v-autocomplete>
</v-card-text>
<v-divider></v-divider>
<v-expand-transition>
<v-list v-if="model" class="red lighten-3">
<v-list-tile
v-for="(field, i) in fields"
:key="i"
>
<v-list-tile-content>
<v-list-tile-title v-text="field.value"></v-list-tile-title>
<v-list-tile-sub-title v-text="field.key"></v-list-tile-sub-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-expand-transition>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
:disabled="!model"
color="grey darken-3"
#click="model = null"
>
Clear
<v-icon right>mdi-close-circle</v-icon>
</v-btn>
</v-card-actions>
</v-card>
</v-app>
</div>

If this is the code you are trying to use then you are missing a ',' at the end of the "model".
created :function() {
model={...}, <----
search="Cats"
},

blalan05 on the discrod channel just give me the reply : my created function was garbled.
new Vue({
el: '#app',
data: () => ({
descriptionLimit: 60,
entries: [],
isLoading: false,
model: null,
search: "Cats"
}),
created () {
this.model = {"API":"Cats","Description":"Pictures of cats from Tumblr","Auth":"","HTTPS":true,"Cors":"unknown","Link":"https://thecatapi.com/docs.html","Category":"Animals"},
this.search = "Cats"
},
computed: {
fields () {
if (!this.model) return []
return Object.keys(this.model).map(key => {
return {
key: key,
value: this.model[key] || 'n/a'
}
})
},
items () {
return this.entries.map(entry => {
const Description = entry.Description.length > this.descriptionLimit
? entry.Description.slice(0, this.descriptionLimit) + '...'
: entry.Description
return Object.assign({}, entry, { Description })
})
}
},
watch: {
search (val) {
// Items have already been loaded
if (this.items.length > 0) return
this.isLoading = true
console.log("loadgin data")
// Lazily load input items
axios.get('https://api.publicapis.org/entries')
.then(res => {
const { count, entries } = res.data
this.count = count
this.entries = entries
})
.catch(err => {
console.log(err)
})
.finally(() => (this.isLoading = false))
}
}
})
<div id="app">
<v-app id="inspire">
<v-card
color="red lighten-2"
dark
>
<v-card-title class="headline red lighten-3">
Search for Public APIssss
</v-card-title>
<v-card-text>
Explore hundreds of free API's ready for consumption! For more information visit
<a
class="grey--text text--lighten-3"
href="https://github.com/toddmotto/public-apis"
target="_blank"
>the Github repositoryyy</a>.
</v-card-text>
<v-card-text>
<v-autocomplete
v-model="model"
:items="items"
:loading="isLoading"
:search-input.sync="search"
color="white"
hide-no-data
hide-selected
item-text="Description"
item-value="API"
label="Public APIs"
placeholder="Start typing to Search"
prepend-icon="mdi-database-search"
return-object
></v-autocomplete>
</v-card-text>
<v-divider></v-divider>
<v-expand-transition>
<v-list v-if="model" class="red lighten-3">
<v-list-tile
v-for="(field, i) in fields"
:key="i"
>
<v-list-tile-content>
<v-list-tile-title v-text="field.value"></v-list-tile-title>
<v-list-tile-sub-title v-text="field.key"></v-list-tile-sub-title>
</v-list-tile-content>
</v-list-tile>
</v-list>
</v-expand-transition>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
:disabled="!model"
color="grey darken-3"
#click="model = null"
>
Clear
<v-icon right>mdi-close-circle</v-icon>
</v-btn>
</v-card-actions>
</v-card>
</v-app>
</div>

Related

Vue warn: Avoid mutating a prop directly when use vuetify <v-dialog>

Vue v2. Can't fix this warn, i'm use v-dialog in child element.Child element have prop - dialog for toggle v-dialog. Try to use for v-dialog v-bind:value and #input instead of v-model but with this don't open dialog. Try to use computed dialogLocal - dialog can't open with computed prop.
Parent
<template>
<div>
<p class='subtitle_text'>Поставщик</p>
<v-autocomplete
clearable
dense
v-model='supplier'
:items='suppliers'
:item-text='item => item.supplierName'
return-object
>
<template v-slot:item="{ item }">
<v-list-item-content>
<v-list-item-title v-text="item.supplierName"></v-list-item-title>
</v-list-item-content>
<v-list-item-action>
<v-btn
fab
x-small
dark
color='primary'
#click="openEditDialog(item)"
>
<v-icon
x-small
dark
>
mdi-pencil
</v-icon>
</v-btn>
</v-list-item-action>
<v-list-item-action>
<v-btn
style='margin-left: 15px'
fab
x-small
dark
color='red'
#click="openDeleteDialog(item)"
>
<v-icon
x-small
dark
>
mdi-delete
</v-icon>
</v-btn>
</v-list-item-action>
<DeleteDialog
message = 'Удалить поставщика'
v-bind:info = currentSupplier.supplierName
v-bind:id = currentSupplier.id
v-bind:isActive = 'isDeleteDialogActive'
#confirmAction = 'confirmDeleteSupplier'
#cancelAction = 'cancelDeleteSupplier'
ref='deleteDialog'
/>
</template>
<template v-slot:append-item>
<div style="padding-left: 0px; max-height: 2rem">
<v-btn
#click='openCreateDialog'
block
text
large
style='font-size: 1em'
>
<v-icon
left
large
color='green'
>
mdi-plus-circle
</v-icon>
Создать
</v-btn>
</div>
<SupplierDialog
v-bind:dialog='isSupplierDialogActive'
v-bind:title='supplierDialogTitle'
v-model:supplier='currentSupplier'
#save='confirmSupplierDialog()'
#cancel='cancelSupplierDialog'
/>
</template>
</v-autocomplete>
</div>
</template>
<script>
imports ...
export default {
components: {
DeleteDialog,
SupplierDialog
},
data() {
return {
suppliers: null,
currentSupplier: {id: null, name: null},
supplier: {id: null, name: null},
supplierDialogTitle: null,
isSupplierDialogActive: false,
isDeleteDialogActive: false
}
},
methods: {
getAllSuppliers() {
...
},
openEditDialog(supplier) {
this.isSupplierDialogActive = true
this.currentSupplier = supplier
this.supplierDialogTitle = 'Редактирование поставщика'
},
openDeleteDialog(supplier) {
...
},
confirmDeleteSupplier(id) {
...
},
cancelDeleteSupplier() {
...
},
openCreateDialog() {
this.currentSupplier = {id: null, name: null}
this.isSupplierDialogActive = true
this.supplierDialogTitle = 'Создание поставщика'
},
cancelSupplierDialog() {
this.currentSupplier = {id: null, name: null}
this.getAllSuppliers()
this.isSupplierDialogActive = false
},
confirmSupplierDialog(supplier) {
this.getAllSuppliers()
this.supplier = supplier
this.isSupplierDialogActive = false
}
},
mounted() {
this.getAllSuppliers()
}
}
</script>
<style>
...
</style>
Child
<template>
<div>
<v-dialog
v-model='dialog'
max-width="50vw"
persistent
>
<v-card class='dialog_card'>
<v-card-title class="text-h5">
{{ title }}
</v-card-title>
<v-form
>
<v-text-field
label='Наименование поставщика'
required
v-model='supplier.supplierName'
></v-text-field>
</v-form>
<v-card-actions>
<v-btn
#click='addSupplier'
>
Сохранить
</v-btn>
<v-spacer></v-spacer>
<v-btn
#click='cancelDialog'
>
Отмена
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<script>
import ...
export default {
props: ['dialog','title', 'supplier'],
model: {
prop: 'supplier',
event: 'change'
},
computed: {
supplierLocal: {
get: function () {
return this.supplier
},
set: function (value) {
this.$emit('change', value)
}
},
},
methods: {
cancelDialog() {
this.supplierLocal = {id: null, supplierName: null}
this.$emit('cancel')
},
addSupplier() {
if (this.supplierLocal.supplierName != null && this.supplierLocal.supplierName != '') {
if(this.supplierLocal.id == null) {
RestService.postSuppliers(this.supplierLocal).then((response) =>
{
this.$emit('save', response.data)
},
error => {
this.content =
(error.response && error.response.data && error.response.data.message) ||
error.message ||
error.toString();
this.isLoading = false;
if (error.response && error.response.status === 403) {
EventBus.dispatch("logout");
}
}
)
} else {
RestService.putSuppliers(this.supplierLocal).then((response) =>
{
this.$emit('save', response.data)
},
error => {
this.content =
(error.response && error.response.data && error.response.data.message) ||
error.message ||
error.toString();
this.isLoading = false;
if (error.response && error.response.status === 403) {
EventBus.dispatch("logout");
}
}
)
}
}
}
}
}
</script>
<style>
.dialog_card {
padding: 4% 10%;
}
</style>
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "dialog"
found in
---> <SupplierDialog> at src/components/main_container/letter_of_authorization/SupplierDialog.vue
<VList>
<VSelectList>
<VThemeProvider>
<VMenu>
<VAutocomplete>
<SupplierForm>
<VCard>
<CreateLetterOfAuthorization> at src/views/app/CreateLetterOfAuthorization.vue
<MainContainer> at src/components/main_container/MainContainer.vue
<VApp>
<Application> at src/views/app/Application.vue
<App> at src/App.vue
<Root>

Use SnackBar as a Global component in Vue + Vuetify

I'm trying to create SnackBarComponent.vue so I can implement it in my BaseTemplate.vue where I have my main menu that references the other router-view components.
This would be my BaseComponent.Vue
<template>
<v-app id="inspire">
<v-navigation-drawer
v-model="drawer"
app
clipped
>
<v-list dense>
<v-list-item
v-for="item in items"
:key="item.title"
:to="item.to"
:active-class="`primary white--text`"
link
>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
<v-app-bar
app
clipped-left
color="blue"
dark
>
<v-app-bar-nav-icon #click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-toolbar-title>Title</v-toolbar-title>
</v-app-bar>
<v-main>
<v-container fluid style="padding:30px">
<transition name="component-fade" mode="out-in">
<router-view></router-view>
</transition>
</v-container>
</v-main>
<template>
<v-snackbar
v-model="snackbar"
:timeout="timeoutSnackBar"
>
{{ textSnackBar }}
</v-snackbar>
</template>
</v-app>
</template>
<script>
export default {
data: () => ({
snackbar: false,
timeoutSnackBar: -1,
textSnackBar: '',
methods:{
SnackNotification(time,text){
this.snackbar = true
this.timeoutSnackBar: time
this.textSnackBar: text
}
}
drawer: null,
items: [
{
title: "Home",
icon: "mdi-view-dashboard",
to: "/"
},
{
title: "Users",
icon: "mdi-account",
to: "/users"
},
]
}),
}
</script>
and i try use in de UserComponent.vue
<template>
<v-card
class="mx-auto"
max-width="344"
outlined
>
<v-list-item three-line>
<v-list-item-content>
<div class="overline mb-4">
OVERLINE
</div>
<v-list-item-title class="headline mb-1">
Headline 5
</v-list-item-title>
<v-list-item-subtitle>Greyhound divisely hello coldly fonwderfully</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-avatar
tile
size="80"
color="grey"
></v-list-item-avatar>
</v-list-item>
<v-card-actions>
<v-btn
outlined
rounded
text
>
Button
</v-btn>
</v-card-actions>
</v-card>
</template>
<script>
export default {
created() {
this.users();
},
methods: {
users: function() {
axios
.get('/api/users')
.then(response => {
this.users = response.data.data
})
.catch(error => {
this.errored = true
})
.finally(() => {
if (this.firstLoad) this.firstLoad = false
this.loading = false;
this.SnackNotification(2000,'Hi, im a notification')
})
},
}
</script>
My app.js is this.
import App from './components/BaseTemplate.vue'
const app = new Vue({
el: '#app',
render: h => h(App),
vuetify: new Vuetify(),
router
})
had the idea to do it this way but I think I am quite wrong to do this global implementation, I looked for some options but they used NuxtJS and it was not really what I had in mind, any recommendation that could give me how to do it? thank you.
You could add the snack bar in vue.app as global snackbar with vuex.
Example:
App.vue
<template>
<v-app>
...
<v-main>
<router-view />
</v-main>
...
<v-snackbar v-model="snackbar.active" :timeout="-1" :color="snackbar.color">
{{ snackbar.message}}
<template v-slot:action="{ attrs }">
<v-btn text v-bind="attrs" #click="snackbar.active = false">
Close
</v-btn>
</template>
</v-snackbar>
</v-app>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "App",
computed: {
...mapState(["snackbar"])
}
};
</script>
Index.js (store)
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
snackbar: { active: false, color: "", message: "" }
},
mutations: {
SET_SNACKBAR(state, snackbar) {
state.snackbar = snackbar;
}
},
actions: {
snackBar({ commit }, message) {
commit("SET_SNACKBAR", {
active: true,
color: "success", // You can create another actions for diferent color.
message: message
});
}
}
});
Now in any router view you can active the snackbar like this
Example.vue
<template>
...
<v-btn #click="showSnackBar()">
Show SnackBar!
</v-btn>
...
</template>
<script>
import { mapActions} from "vuex";
export default {
methods: {
...mapActions(["snackBar"]),
showSnackBar() {
this.snackBar("Hi, I'm snackbar");
}
}
};
</script>
Please see my answer here for a very similar problem. In that case, they wanted a global 'confirm dialog' but in your case it's a 'global snackbar'
The code that I posted in that answer can be used for a snackbar instead of a dialog with very minimal modification. In fact, in my projects I usually go ahead and add both because they're so useful.

how to pass variable between to vue file?

how to pass variable between to vue file ?
Hello, this is my file SendCode.vue has variable NewEmail which I want to use it in another file changePass.vue .
Is there anyway to sole this ?
Can someone help me ? Thanks
<template>
<v-app id="inspire">
<v-content>
<v-container class="fill-height" fluid>
<v-row align="center" justify="center">
<v-col cols="12" sm="8" md="4">
<v-card class="elevation-12">
<v-toolbar color="#ff8c00">
<v-toolbar-title>Glömt lösenord!</v-toolbar-title>
</v-toolbar>
<v-card-text>
Skrive ditt email.
<v-form>
<v-text-field v-model="email"
:error-messages="emailErrors"
label="E-mail"
required
#input="$v.email.$touch()"
#blur="$v.email.$touch()"></v-text-field>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn #click="getCode" color="primary">Skicka koden</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</v-content>
</v-app>
</template>
<script>
import axios from 'axios'
import router from '#/router.js'
import { validationMixin } from 'vuelidate'
import { required, email } from 'vuelidate/lib/validators'
export default {
mixins: [validationMixin],
validations: {
email: { required, email },
checkbox: {
checked(val) {
return val
}
}
},
props: {
source: String,
},
data: () => ({
email: ""
}),
methods: {
getCode: async function() {
let obj = {
"email": this.email,
};
let NewEmail = this.email;
let response = await this.$store.dispatch("getCode", obj);
//console.log(email)
//console.log(this.email)
if (response.status == 200) {
setTimeout(function() {
router.push({
path: 'ChangePass'
});
}, 500);
}
}
}
}
</script>
I want to use/pass variable NewEmail in this file from SendCode.vue file
I am new in vue and javascript so I do not know how to do this.
<template>
<v-app id="inspire">
<v-content>
<v-container class="fill-height" fluid>
<v-row align="center" justify="center">
<v-col cols="12" sm="8" md="4">
<v-card class="elevation-12">
<v-toolbar color="#ff8c00">
<v-toolbar-title>ÄNDRA LÖSENORDET</v-toolbar-title>
</v-toolbar>
<v-card-text>
<v-form>
<v-text-field :error="pass1Error" label="Koden" v-model="code1" type="password" />
<v-text-field :error="pass2Error" label="Lössenord" v-model="newPassword" type="password" />
<v-text-field :error="pass1Error" label="Samma Lössenord" v-model="rePassword" type="password" />
</v-form>
</v-card-text>
<v-alert v-if="passError" type="error">
password are not same
</v-alert>
<v-alert v-if="passwordChanged" type="success">
Password has been updated!
</v-alert>
<v-card-actions>
<v-spacer />
<v-btn #click="change" color="primary">Ändra</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</v-content>
</v-app>
</template>
<script>
import axios from 'axios'
import SendCode from "#/views/SendCode.vue";
import { validationMixin } from 'vuelidate'
import { required, email } from 'vuelidate/lib/validators'
export default {
mixins: [validationMixin],
validations: {
email: { required, email },
checkbox: {
checked(val) {
return val
}
}
},
props: {
source: String,
},
data: () => ({
code1: "",
newPassword: "",
rePassword: ""
}),
methods: {
change: async function() {
let obj = {
"code1": this.code1,
"newPassword": this.newPassword,
"rePassword": this.rePassword,
};
console.log(obj)
let response = await this.$store.dispatch("changePass", obj);
}
}
}
</script>
We recommend that you use Vuex (State management) for easy transfer and management of data through pages
Documentation:
https://vuex.vuejs.org/
If its only a variable with some value in it you can store it in localstorage i assume.
So in your function where you have the data you want to pass add:
localStorage.setItem('email', variable).
This works as a key value pair where email is the key and the variable is the data you want to access.
Then where you want to access the data you can use:
localStorage.getItem('email')
You probably don't want to do what you're trying to do, but would be better off with state management (vuex/pinia/genericVueStore), or, if you want to pass the data between components in the same app (same project), then the main method is $emits and $props. Check Vue documentation to see if that is what you want, which it probably is.
Nevertheless, within a Vue project, you can generally use Node/ES methods. So, the following would be fine, and would fit into the "composables" category if they weren't ".vue" files.
>> file1.vue
<script setup>
const oneData = "this_text"
export {oneData}
...
>> file2.vue
import {oneData} from "#/file1.vue"
console.log(oneData}
This would be an anti-pattern. Just follow the documentation for the standard things people try to accomplish.

Passing props from one step to another (steppers) in Vue

I am using steppers in vue. I am creating an agency in step 1 and on step 2 I am displaying the agency details. The issue is that the agency details don't appear on step 2 until I refresh page after going on step 2. Is there a way to pass agency as a prop from agency.vue to event.vue so that I dont need to refresh the page to make the agency details appear on step 2.
stepper.vue
<template>
<div >
<v-stepper v-model="e1">
<v-stepper-header>
<v-stepper-step :complete="e1 > 1" step="1">Agency</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step :complete="e1 > 2" step="2">Event</v-stepper-step>
<v-divider></v-divider>
</v-stepper-header>
<v-stepper-items>
<v-stepper-content step="1">
<Agency #next="goTo(2, true)"></Agency>
</v-stepper-content>
<v-stepper-content step="2">
<Event/>
</v-stepper-content>
</v-stepper-items>
</v-stepper>
</div>
</template>
<script>
import Agency from 'parties/agency';
import Event from 'events/event';
export default {
components: {
Agency,
Event
},
data () {
return {
e1: 0,
agency: {
id: '',
name: '',
phone_number: ''
}
}
},
created() {
this.step = 1;
this.getAgency();
},
methods: {
getAgency() {
this.$axios.get('/agency.json')
.then(response => {
if (Object.keys(response.data).length > 0) {
this.agency = response.data;
}
})
},
goTo(step, can) {
if (can) {
this.e1 = step;
}
},
}
};
</script>
agency.vue
<template>
<v-card>
<v-form :model='agency'>
<v-layout row wrap>
<v-flex xs12 sm12 lg12 >
<v-layout row wrap>
<v-flex xs12 md6 class="add-col-padding-right">
<v-text-field
label='Agency Name'
v-model='agency.name'>
</v-text-field>
</v-flex>
</v-layout>
<v-layout row wrap>
<v-flex xs12 md6 class="add-col-padding-right">
<v-text-field
label='Agency Phone Number'
v-model='agency.phone_number'>
</v-text-field>
</v-flex>
</v-layout>
<v-layout row wrap>
<div>
<v-btn #click.prevent='saveAgency'>Save</v-btn>
</div>
</v-layout>
</v-flex>
</v-layout>
</v-form>
<v-btn #click.prevent='nextStep'>
Next
</v-btn>
</v-card>
</template>
<script>
export default {
data: function () {
return {
agency: {
id: '',
name: '',
phone_number: ''
}
};
},
created: function() {
this.getAgency();
},
methods: {
nextStep() {
this.$emit('next');
},
getAgency() {
this.$axios.get('/agency.json')
.then(response => {
if (Object.keys(response.data).length > 0) {
this.agency = response.data;
}
})
},
saveAgency() {
this.$axios.post('/agencies.json', { agency: this.agency })
.then(response => {
});
},
}
};
</script>
event.vue
<template>
<v-card class="mb-12">
<v-form :model='agency'>
{{ agency.name }}<br/>
{{ agency.phone_number }}<br/>
</v-form>
</v-card>
</template>
<script>
export default {
data: function () {
return {
agency: {
id: '',
name: '',
phone_number: ''
},
event_final: false
};
},
created: function() {
this.getAgency();
},
methods: {
getAgency() {
this.$axios.get('/agency.json')
.then(response => {
if (Object.keys(response.data).length > 0) {
this.agency = response.data;
if (this.agency.name === "XYZ") {
this.event_final = true;
}
}
}).
then(() => {
});
},
}
};
</script>
Have Agency emit the details in its next event, capture them at the parent and pass them as a prop to Event.
Given you load the initial data in stepper.vue, you can also pass that into Agency for editing
For example
// agency.vue
props: { editAgency: Object },
data () {
return { agency: this.editAgency } // initialise with prop data
},
methods: {
nextStep() {
this.$emit('next', { ...this.agency }) // using spread to break references
},
// etc, no need for getAgency() here though
}
<!-- stepper.vue -->
<Agency :edit-agency="agency" #next="nextAgency"></Agency>
<!-- snip -->
<Event :agency="agency" />
// stepper.vue
methods: {
nextAgency (agency) {
this.agency = agency
this.goTo(2, true)
},
// event.vue
export default {
props: { agency: Object } // no need for a local "data" copy of agency, just use the prop
}

How to pass array index in image src in Vuejs v-img?

Hey im trying to iterate through an array of urls to feed it inside of my src attribute. I'm not sure about the correct syntax to use. Can you help me?
I have my array called DataArray made of images url, and i want to insert inside of v-img in v-row. i tried this :src=DataArray[n] but it's not the correct way.
<template>
<v-container v-if="Dataloaded" class="dark">
<v-row no-gutters>
<template v-for="n in 6">
<v-col :key="n">
<v-card dark class="mx-auto" max-width="344">
<v-img :src=DataArray[n] height="200px"></v-img>
<v-card-title>Title</v-card-title>
<v-card-subtitle>Anime-Descriptions</v-card-subtitle>
<v-card-actions>
<v-btn text>View</v-btn>
<v-btn color="purple" text>Explore</v-btn>
<v-spacer></v-spacer>
<v-btn icon #click="show = !show">
<v-icon>{{ show ? 'mdi-chevron-up' : 'mdi-chevron-down' }}</v-icon>
</v-btn>
</v-card-actions>
<v-expand-transition>
<div v-show="show">
<v-divider></v-divider>
<v-card-text>I'm a thing. But, like most politicians, he promised more than he could deliver. You won't have time for sleeping, soldier, not with all the bed making you'll be doing. Then we'll go with that data file! Hey, you add a one and two zeros to that or we walk! You're going to do his laundry? I've got to find a way to escape.</v-card-text>
</div>
</v-expand-transition>
</v-card>
<!-- spacing -->
<br :key="1" />
<br :key="2" />
</v-col>
<v-responsive v-if="n === 3" :key="`width-${n}`" width="100%"></v-responsive>
</template>
</v-row>
</v-container>
</template>
<script>
import db from "#/Firebase/firebaseInit";
export default {
name: "Grid",
data() {
return {
DataArray: [],
Dataloaded: false,
show: false
};
},
created() {
let ArtData = db.collection("artworks").doc("yWnmwHTxMhvobLi21FNw");
ArtData.get()
.then(doc => {
if (doc.exists) {
// This variable contains all the necessary artworks for display
let DataArray = doc.data().Array;
console.log("Document data!:", DataArray);
this.Dataloaded = true;
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
})
.catch(function(error) {
console.log("Error getting document:", error);
});
}
};
</script>
Change this:
let DataArray = doc.data().Array;
to:
this.DataArray = doc.data().Array;
And use this to show the image:
<v-img :src="DataArray[n-1]" height="50px"></v-img>
n-1 because the v-for you're using is 1-based.

Categories