Vue親子伝値、親調子、子調親


文書ディレクトリ
  • 親子伝値
  • 親調子
  • 親コンポーネント
  • 子調父
  • サブアセンブリ
  • 親コンポーネント
  • 完全コード
  • サブアセンブリ
  • 親コンポーネント

  • 親子で値を渡す
    サブコンポーネントでpropsを定義して、親コンポーネントがサブコンポーネントに渡す値の名前、タイプ、デフォルト値を定義します.
    props: {
         
        prop: {
         
            type: Object,
        },
        table: {
         
            type: Object,
            required: true,
        },
        pageable: {
         
            type: Boolean,
            default: true,
        },
        search: {
         
            type: Object
        },
        form: {
         
            type: Object,
        },
        toolBar: {
         
            type: Array,
        },
    },
    

    親の調子
    親コンポーネントにrefプロパティを追加します.this.$refs.ref属性名サブコンポーネントメソッド名を使用して親サブアセンブリを実装
    親コンポーネント
    <data-grid :data="data" :height="height" :page="page" :pageable="pageable" :table="table" ref="grid" @currentChange="currentChange">
        <template :slot="field.slot" slot-scope="scope" v-for="field in table.fields">
            <el-button-group v-if="field.slot && field.slot === 'op'">
                <el-button :title="$t('button.edit')" @click="edit(scope.row.id)"
                           icon="el-icon-edit" type="primary"
                           v-if="prop.editPermission && checkPermission(prop.editPermission) && field.edit"></el-button>
                <slot :field="scope.field" :name="field.slot" :row="scope.row"></slot>
            </el-button-group>
            <slot :field="scope.field" :name="field.slot" :row="scope.row" v-else-if="field.slot"></slot>
        </template>
    </data-grid>
    
    getSelected() {
         
        return this.$refs.grid.getSelected();
    },
    

    子の親
    Vueの$emitメソッドによる子調親の実現
    サブアセンブリ
    currentChange(current) {
         
        this.$emit('currentChange', current);
    }
    

    親コンポーネント
     <data-grid :data="data" :height="height" :page="page" :pageable="pageable" :table="table" ref="grid" @currentChange="currentChange">
        <template :slot="field.slot" slot-scope="scope" v-for="field in table.fields">
            <el-button-group v-if="field.slot && field.slot === 'op'">
                <el-button :title="$t('button.edit')" @click="edit(scope.row.id)"
                           icon="el-icon-edit" type="primary"
                           v-if="prop.editPermission && checkPermission(prop.editPermission) && field.edit"></el-button>
                <slot :field="scope.field" :name="field.slot" :row="scope.row"></slot>
            </el-button-group>
            <slot :field="scope.field" :name="field.slot" :row="scope.row" v-else-if="field.slot"></slot>
        </template>
    </data-grid>
    
    currentChange(current) {
         
        this.page.pageNum = current;
        this.load();
    },
    

    完全なコード
    サブアセンブリ
    <template>
        <div>
            <el-table :data="data" :row-key="table.rowKey?'id':table.rowKey" @select="select" border
                      :height="height" tooltip-effect="dark">
                <template v-for="field in table.fields">
                    <el-table-column :type="field.type" align="center" fixed="left" header-align="center" v-if="field.type">
                    </el-table-column>
                    <el-table-column :align="field.align?'center':field.align" :fixed="field.fixed"
                                     :header-align="field.headerAlign?'center':field.headerAlign"
                                     :label="field.label"
                                     :prop="field.prop" :show-overflow-tooltip="true"
                                     :width="field.width" v-else-if="field.slot === undefined">
                    </el-table-column>
                    <el-table-column :align="field.align?'center':field.align" :fixed="field.fixed"
                                     :header-align="field.headerAlign?'center':field.headerAlign"
                                     :label="field.label"
                                     :prop="field.prop" :show-overflow-tooltip="true"
                                     :width="field.width" v-else>
                        <slot :field="field" :name="field.slot" :row="scope.row" slot-scope="scope"></slot>
                    </el-table-column>
                </template>
            </el-table>
            <el-pagination v-if="pageable" @size-change="sizeChange" @current-change="currentChange"
                           :page-sizes="[10, 20, 30, 40, 50, 100]" layout="jumper,prev,pager,next,sizes,total"
                           :current-page="page.pageNum" :page-size="page.pageSize" :total="page.total">
            </el-pagination>
        </div>
    </template>
    
    <script>
        export default {
         
            name: "DataGrid",
            props: {
         
                table: {
         
                    type: Object,
                    required: true,
                },
                pageable: {
         
                    type: Boolean,
                    default: true,
                },
                page: {
         
                    type: Object,
                },
                data: {
         
                    type: Array
                },
                height: {
         
                    type: Number
                }
            },
            data() {
         
                return {
         
                    selected: [],
                }
            },
            methods: {
         
                select(selection) {
         
                    let ids = [];
                    for (let selected of selection) {
         
                        ids.push(selected[this.table.rowKey]);
                    }
                    this.selected = ids;
                },
                getSelected() {
         
                    return this.selected;
                },
                currentChange(current) {
         
                    this.$emit('currentChange', current);
                },
                sizeChange(size) {
         
                    this.$emit('sizeChange', size);
                }
            }, created() {
         
                console.log(this.data)
            }
        }
    </script>
    

    親コンポーネント
    <template>
        <div>
            <div ref="header">
                <dynamic-form :form="search" :model="search.params" ref="search" v-if="search">
                    <el-form-item :label="' '">
                        <el-button-group>
                            <el-button :title="$t('button.search')" @click="load()" type="primary">
                                {
         {
         $t('button.search')}}
                            </el-button>
                            <el-button :title="$t('button.reset')" @click="clear" type="primary">
                                {
         {
         $t('button.reset')}}
                            </el-button>
                        </el-button-group>
                    </el-form-item>
                </dynamic-form>
                <div style="padding-bottom: 10px">
                    <el-button-group slot="toolBar">
                        <el-button :title="$t('button.add')" @click="add()"
                                   icon="el-icon-plus" type="primary"
                                   v-if="prop.addPermission && checkPermission(prop.addPermission)"></el-button>
                        <el-button :title="$t('button.delete')" @click="del()"
                                   icon="el-icon-delete" type="danger"
                                   v-if="prop.delPermission && checkPermission(prop.delPermission)"></el-button>
                        <slot name="toolBar"></slot>
                    </el-button-group>
                </div>
            </div>
            <data-grid :data="data" :height="height" :page="page" :pageable="pageable" :table="table" ref="grid" @currentChange="currentChange">
                <template :slot="field.slot" slot-scope="scope" v-for="field in table.fields">
                    <el-button-group v-if="field.slot && field.slot === 'op'">
                        <el-button :title="$t('button.edit')" @click="edit(scope.row.id)"
                                   icon="el-icon-edit" type="primary"
                                   v-if="prop.editPermission && checkPermission(prop.editPermission) && field.edit"></el-button>
                        <slot :field="scope.field" :name="field.slot" :row="scope.row"></slot>
                    </el-button-group>
                    <slot :field="scope.field" :name="field.slot" :row="scope.row" v-else-if="field.slot"></slot>
                </template>
            </data-grid>
            <el-dialog :close-on-click-modal="false" :title="title" :visible.sync="visible" @closed="closed" v-if="form"
                       width="30%">
                <dynamic-form :form="form" :model="form.model" ref="dynamicForm"></dynamic-form>
                <span class="dialog-footer" slot="footer">
                    <el-button @click="height = 800">{
         {
         $t('button.cancel')}}</el-button>
                    <el-button @click="visible = false">{
         {
         $t('button.cancel')}}</el-button>
                    <el-button :loading="loading" @click="save" type="primary">{
         {
         $t('button.ok')}}</el-button>
                </span>
            </el-dialog>
        </div>
    </template>
    <script>
        export default {
         
            name: 'CommonGrid',
            props: {
         
                prop: {
         
                    type: Object,
                },
                table: {
         
                    type: Object,
                    required: true,
                },
                pageable: {
         
                    type: Boolean,
                    default: true,
                },
                search: {
         
                    type: Object
                },
                form: {
         
                    type: Object,
                },
                toolBar: {
         
                    type: Array,
                },
            },
            data() {
         
                return {
         
                    data: [],
                    page: {
         
                        pageNum: 1,
                        pageSize: 10
                    },
                    loading: false,
                    visible: false,
                    title: '',
                    order: null,
                    height: 500,
                }
            },
            methods: {
         
                load() {
         
                    let params = {
         };
                    if (this.search && this.search.length > 0) {
         
                        params = this.search.params
                    }
                    if (this.pageable) {
         
                        params['pageNum'] = this.page.pageNum;
                        params['pageSize'] = this.page.pageSize;
                    }
                    if (this.order) {
         
                        params['order'] = this.order;
                    }
                    this.$ajax.post(this.prop.dataUrl, params).then((data) => {
         
                        this.tableData = data.list;
                        if (this.pageable) {
         
                            this.page.total = data.total;
                        }
                    })
                },
                add() {
         
                    this.open(this.$t('button.add'));
                },
                save() {
         
                    this.$refs.dynamicForm.validate((valid) => {
         
                        if (valid) {
         
                            this.loading = true;
                            this.$ajax.post(this.prop.saveUrl, this.form.model).then((data) => {
         
                                this.$message({
         
                                    type: data.type,
                                    message: this.$t(data.code)
                                });
                                this.load();
                                this.close();
                            })
                        }
                    });
                },
                edit(id) {
         
                    this.$ajax.post(this.prop.rowUrl, {
         id: id}).then((data) => {
         
                        this.form.model = data;
                        this.open(this.$t('button.edit'));
                    })
                },
                del() {
         
                    let selected = this.getSelected();
                    if (selected > 0) {
         
                        this.$confirm('         ?', '  ', {
         
                            type: 'warning',
                        }).then(() => {
         
                            this.$ajax.post(this.prop.deleteUrl, {
         ids: selected}).then((data) => {
         
                                this.load();
                                this.$message({
         
                                    type: data.type,
                                    message: this.$t(data.code)
                                });
                            })
                        }).catch(() => {
         
                        });
                    } else {
         
                        this.$message.error('          !');
                    }
                },
                clear() {
         
                    this.reset('search');
                    this.load();
                },
                open(title) {
         
                    this.title = title;
                    this.visible = true;
                },
                close() {
         
                    this.visible = false;
                },
                closed() {
         
                    this.reset('dynamicForm');
                    this.loading = false;
                },
                sortChange(column) {
         
                    if (column.order) {
         
                        this.order = column.prop + ' ' + column.order.replace('ending', '');
                    } else {
         
                        this.order = null;
                    }
                    this.load();
                },
                sizeChange(size) {
         
                    this.page.pageSize = size;
                    this.load();
                },
                currentChange(current) {
         
                    this.page.pageNum = current;
                    this.load();
                },
                reset(name) {
         
                    this.$refs[name].reset();
                },
                getSelected() {
         
                    return this.$refs.grid.getSelected();
                },
                resize() {
         
                    let height = document.body.offsetHeight - 116 - this.$refs.header.offsetHeight;
                    if (this.pageable) {
         
                        height = height - 49
                    }
                    this.height = height;
                }
            },
            created() {
         
                this.data = [{
         demo: '1', test: '2'}, {
         demo: '3', test: '4'}]
                //this.load();
            },
            mounted() {
         
                this.$nextTick(() => {
         
                    this.resize();
                    window.onresize = () => {
         
                        this.resize();
                    }
                })
            }
        }
    </script>