Reputation: 489
I am using Vue-CLI
. I have a Vue component which is called viewGenres.vue
. This component contains Vuetify
table which presents all of the current genres
from Vue store. I am trying to add a new option for each genre which is "Edit".
My objective is that for each line in the table there will be an edit
button. Once the button is clicked, a new component called editGenre.vue
should be rendered.
This component should contain a filled-out form with all the existing details of the specific genre. I have several questions:
1) Once I click on the edit
button, the following exception appears on browser:
ReferenceError: Vue is not defined at VueComponent.editGenre
2) In order for me to load the right properties from the DB, I need to define the "ID" prop of the editGenre component. Does anyone have any recommendation on the best method to do so?
This is viewGenres.vue: (the method editGenre is the one responsible for rendering the new component).
<template>
<div class="root" ref="container">
<h2>Genres Info</h2>
<br>
<v-data-table
:headers="headers"
:items="genres"
hide-actions
class="elevation-1">
<template slot="items" slot-scope="props">
<td class="text-xs-left">{{ props.item.id }}</td>
<td class="text-xs-left">{{ props.item.name }}</td>
<td class="text-xs-left">{{ props.item.desc }}</td>
<td class="text-xs-left">{{ props.item.artists }}</td>
<td class="text-xs-left"><v-btn flat @click="editGenre(props.item.id)">EDIT</v-btn></td>
<td class="text-xs-left"><v-btn flat @click="deleteGenre(props.item.id)">Delete</v-btn></td>
</template>
</v-data-table>
</div>
</template>
<script>
import editGenre from '@/components/administratorView/Genres/editGenre.vue'
const firebase = require('../../../firebaseConfig.js')
export default {
data: function(){
return{
headers: [
{ text: 'ID', value: 'id'},
{ text: 'Name', value: 'name'},
{ text: 'Description', value: 'desc'},
{ text: 'Artists', value: 'artists'},
{ text: 'Edit Genre'},
{ text: 'Delete From DB'}
]
}
},
computed: {
genres: function(){
return this.$store.state.genre.genres
}
},
components: {
editGenre
},
methods: {
editGenre: function(id){
var ComponentClass = Vue.extend(editGenre)
var instance = new ComponentClass()
instance.$mount()
this.$refs.container.appendChild(instance.$el)
},
deleteGenre: function(id){
console.log("Trying to delete " +id)
firebase.firestore.collection("genres").doc(id).delete().then(()=>{
this.$store.dispatch('genre/getGenresFromDB')
alert("Deleted Document Successfully")
}).catch(function(error){
alert(error)
})
}
},
mounted(){
this.$store.dispatch('genre/getGenresFromDB')
}
}
</script>
<style scoped>
</style>
This is editGenre.vue:
<template>
<v-dialog v-model="editGenre" persistent max-width="500px">
<v-card>
<v-card-title>
<h2>Edit Genre {{genre.name}}</h2>
</v-card-title>
<v-card-text>
<v-text-field
v-model="name"
label="Name"
:error-messages="nameErrors"
@touch="$v.name.$touch()"
@blur="$v.name.$touch()"
/>
<v-textarea
v-model="desc"
label="Description"
box
/>
<v-combobox
v-model="artists"
label="Artists"
:items="artistNames"
:error-messages="artistsErrors"
@touch="$v.artists.$touch()"
@blur="$v.artists.$touch()"
multiple>
</v-combobox>
<v-btn
color="primary"
@click="submit">
Submit
</v-btn>
<v-btn
color="primary"
@click="close">
Close
</v-btn>
</v-card-text>
</v-card>
</v-dialog>
</template>
<script>
import { required } from 'vuelidate/lib/validators'
const firebase = require('../../../firebaseConfig')
export default{
data: function(){
return{
name: '',
desc: '',
artists: []
}
},
props: {
id: String
},
mounted: function(){
let docRef = firebase.firestore.collection("genres").doc(this.id)
docRef.get().then(function(doc){
if(doc.exists){
this.name = doc.data().name
this.desc = doc.data().desc
this.artists = doc.data().artists
}
else{
console.error("Doc Doesn't Exist!")
}
}).catch(function(error){
console.error(error)
})
}
}
</script>
<style scoped>
</style>
Thank You! Tom
Upvotes: 0
Views: 2019
Reputation: 1
You missed to import Vue
in your viewGenres.vue
component, so add it as follow :
....
<script>
import Vue from 'vue'
import editGenre from '@/components/administratorView/Genres/editGenre.vue'
const firebase = require('../../../firebaseConfig.js')
....
You could pass props by this way :
var ComponentClass = Vue.extend(
props:{
id:{type:String, default () { return id}}
},editGenre)
and remove this :
props: {
id: String
}
according to Evan You :
It's not recommended to use new to manually construct child components. It is imperative and hard to maintain. You probably want to make your child components data-driven, using and v-for to dynamically render child components instead of constructing them yourself.
Upvotes: 2