【问题标题】:Rendering a new Vue component after click点击后渲染一个新的 Vue 组件
【发布时间】:2019-03-20 01:00:39
【问题描述】:

我正在使用Vue-CLI。我有一个名为 viewGenres.vue 的 Vue 组件。该组件包含 Vuetify 表,它显示了 Vue 商店中所有当前的 genres。我正在尝试为每种类型添加一个新选项,即“编辑”。

我的目标是表格中的每一行都有一个edit 按钮。单击按钮后,应呈现一个名为 editGenre.vue 的新组件。

此组件应包含一个已填写的表格,其中包含特定类型的所有现有详细信息。 我有几个问题:

1) 单击edit 按钮后,浏览器上会出现以下异常:

ReferenceError: Vue 没有在 VueComponent.editGenre 中定义

2) 为了让我从数据库中加载正确的属性,我需要定义 editGenre 组件的“ID”属性。有没有人对这样做的最佳方法有任何建议?

这是 viewGenres.vue:(方法 editGenre 负责渲染新组件)。

<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>

这是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>

谢谢! 汤姆

【问题讨论】:

    标签: vue.js vuejs2 vue-component vuetify.js vue-cli


    【解决方案1】:

    您错过了在viewGenres.vue 组件中导入Vue,因此添加如下:

       ....
       <script>
          import Vue from 'vue'
          import editGenre from '@/components/administratorView/Genres/editGenre.vue'
           const firebase = require('../../../firebaseConfig.js')
          ....
    

    你可以通过这种方式传递道具:

          var ComponentClass = Vue.extend(
                  props:{
                    id:{type:String, default () { return id}}
                   },editGenre)
    

    并删除它:

         props: {
           id: String
        }
    

    尤文

    不建议使用 new 手动构造子组件。这是势在必行且难以维护的。您可能希望使您的子组件数据驱动,使用和 v-for 来动态呈现子组件,而不是自己构建它们。

    【讨论】:

    • 谢谢它解决了我的第一个问题!你对我的第二个问题有什么建议吗?
    • @TomHarpaz 不客气,我编辑了我的答案,希望对你有所帮助
    猜你喜欢
    • 2019-10-03
    • 2021-08-07
    • 1970-01-01
    • 2017-11-09
    • 2019-07-03
    • 2017-11-23
    • 2020-12-04
    • 2022-08-13
    • 2019-03-05
    相关资源
    最近更新 更多