天天看點

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>