Answer the question
In order to leave comments, you need to log in
How to pass data between two components in Vue?
Good afternoon.
I understand with Vue and I want to make my own component that will allow me to make a universal mechanism for displaying forms and editing / adding values in the table (and any other forms). Briefly, the component looks like this:
template.vue
<pages :currentPage.sync="currentPage" >
<page name="index" title='Список проектов'>
<template slot="toolbar">
<v-btn color="primary" dark class="mb-2" @click="newProject">Новый проект</v-btn>
</template>
<v-data-table
:headers="headers"
:items="projects"
hide-actions
class="elevation-1"
>
....
</v-data-table>
</page>
<page parent="index" name="edit" title='Редактирование'>
....
</page>
</pages>
<template>
<v-card width="100%" class="flexcard">
<v-card-title primary-title>
<v-breadcrumbs divider="/" class="pa-0">
....
</v-breadcrumbs>
<v-spacer></v-spacer>
<v-card ref="toolbar">
......тут надо вставить slot toolbar из дочернего компонента page
</v-card>
</v-card-title>
<v-card-text class="grow">
<slot></slot>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
</v-card-actions>
</v-card>
</template>
<template>
<div>
<div v-if="name==pagesActive">
<slot name="toolbar"></slot>
<slot></slot>
</div>
</div>
</template>
<script>
export default {
data: () => ({
}),
computed:{
pagesActive () {
return this.$parent.$parent.activePage
}
},
created () {
..вот тут хотелось бы получить доступ к родительскому компоненту и его слоту
// this.$parent.$refs.toolbar = '123123'
}
}
</script>
Answer the question
In order to leave comments, you need to log in
If anyone is interested, I implemented this task. All executable code and template had to be moved to the Page.vue component
Here is the code listing:
Pages.vue
<template>
<div style="width: 100%; height: 100%">
<slot></slot>
</div>
</template>
<style>
.flexcard {
display: flex;
flex-direction: column;
}
</style>
<script>
export default {
data: () => ({
pages : []
}),
mounted () {
this.initPages()
},
methods: {
initPages() {
this.$children.forEach((child) => {
if (child.$options.name == 'Page'){
this.pages.push(child)
}
})
},
}
}
</script>
<template>
<v-card width="100%" class="flexcard" v-if="name==activePage" style="height: 100%">
<v-card-title primary-title style="padding-bottom: 0; padding-top: 0;">
<slot name="breadcrumbs">
<v-breadcrumbs divider="/" class="">
<v-breadcrumbs-item
v-for="item in breadcrumbs"
:key="item.text"
:disabled="item.disabled"
@click.native="activePage=item.page"
class="pa-0"
>
{{ item.text }}
</v-breadcrumbs-item>
</v-breadcrumbs>
</slot>
<v-spacer></v-spacer>
<slot name="toolbar"></slot>
</v-card-title>
<v-card-text class="grow">
<slot></slot>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<slot name="actions"></slot>
</v-card-actions>
</v-card>
</template>
<script>
export default {
data: () => ({
}),
computed:{
name(){
return this.$attrs.name
},
activePage : {
get: function () {
return this.$store.state.activePage
},
set: function (newValue) {
this.$store.dispatch('setActivePage', newValue)
}
},
breadcrumbs(){
if (this.activePage) {
console.log(this.activePage)
let breadcr = this.getBreadcrumb(this.activePage).reverse()
return breadcr
}else{
return []
}
},
},
methods:{
getBreadcrumb(pageName) {
let items = []
let page = this.getPageByName(pageName)
if (page) {
items.push({
text: page.$attrs.title,
page: page.$attrs.name
})
if (page.$attrs.parent) {
let parentItem = this.getBreadcrumb(page.$attrs.parent)
items = items.concat(parentItem)
}
}
return items
},
getPageByName(name){
if (this.$parent.pages && this.$parent.pages.length > 0){
let page = this.$parent.pages.find((p) => {
return p.$attrs.name == name
})
return page
}
return null
},
},
}
</script>
<template>
<pages style="height : 100%">
<vue-element-loading :active="loading" spinner="bar-fade-scale"/>
<page name="index" title='Список проектов'>
<template slot="toolbar">
<v-btn color="primary" small dark class="mb-2" @click.native="newProject">Новый проект</v-btn>
</template>
<v-data-table
:headers="headers"
:items="projects"
hide-actions
class="elevation-1"
>
<template slot="items" slot-scope="props" :disabled="true">
<td>{{ props.item.name }}</td>
<td class="justify-center layout px-0">
<v-btn flat icon small @click="editItem(props.item)">
<v-icon
small
>
edit
</v-icon>
</v-btn>
<v-btn flat icon small color="error"
@click="deleteItem(props.item)"
:loading="props.item.loading"
>
<v-icon small>
delete
</v-icon>
</v-btn>
</td>
</template>
</v-data-table>
</page>
<page parent="index" name="edit" title='Редактирование'>
<v-form v-model="valid">
<v-layout wrap>
<v-flex xs12>
<v-text-field name="name" :error-messages="errors.collect('name')" :rules="nameRules" required v-model="editedItem.name" label="Название"></v-text-field>
</v-flex>
<v-flex xs12>
<v-spacer></v-spacer>
</v-flex>
</v-layout>
</v-form>
<template slot="actions">
<v-btn small @click.native="close">Отмена</v-btn>
<v-btn
small
:disabled="!valid"
:loading="waitSave"
@click.native="save"
>
Сохранить
</v-btn>
</template>
</page>
</pages>
</template>
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question