点击后渲染一个新的 Vue 组件
Posted
技术标签:
【中文标题】点击后渲染一个新的 Vue 组件【英文标题】:Rendering a new Vue component after click 【发布时间】: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->
<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>
谢谢! 汤姆
【问题讨论】:
【参考方案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 不客气,我编辑了我的答案,希望对你有所帮助以上是关于点击后渲染一个新的 Vue 组件的主要内容,如果未能解决你的问题,请参考以下文章