Vue + Element-ui實現後臺管理系統(5)---封裝一個Form表單組件和Table表格組件

封裝一個Form表單組件和Table組件

有關後臺管理系統以前寫過四遍博客,看這篇以前最好先看下這四篇博客。另外這裏只展現關鍵部分代碼,項目代碼放在github上: mall-manage-systemcss

一、Vue + Element-ui實現後臺管理系統(1) --- 總述html

二、Vue + Element-ui實現後臺管理系統(2) --- 項目搭建 + ⾸⻚佈局實現vue

三、Vue + Element-ui實現後臺管理系統(3) --- 麪包屑 + Tag標籤切換功能git

四、Vue + Element-ui實現後臺管理系統(4)---封裝一個ECharts組件的一點思路github

這篇主要講解實現圖表的功能:api

總體效果佈局

圖片效果post

1、封裝一個Form表單組件

一、封裝思路

咱們須要看下一個基礎form組件,須要哪些數據。咱們看下官網一個示例 Form 表單ui

<template>
<el-form ref="form" :model="form" label-width="80px">
    <el-form-item label="姓名" >
        <el-input v-model="form.name" style="width: 195px"></el-input>
    </el-form-item>
    <el-form-item label="國籍">
        <el-select v-model="form.region" placeholder="請選擇國籍">
            <el-option label="中國" value="china"></el-option>
            <el-option label="美國" value="America"></el-option>
        </el-select>
    </el-form-item>
    <el-form-item label="愛好">
        <el-checkbox-group v-model="form.type">
            <el-checkbox label="畫畫" name="type" ></el-checkbox>
            <el-checkbox label="吹泡泡" name="type"></el-checkbox>
            <el-checkbox label="放風箏" name="type"></el-checkbox>
            <el-checkbox label="看佩琦" name="type"></el-checkbox>
        </el-checkbox-group>
    </el-form-item>
    <el-form-item>
        <el-button type="primary" @click="onSubmit" size="small">當即建立</el-button>
    </el-form-item>
</el-form>
</template>
<script>
    export default {
        data() {
            return {
                form: {
                    name: '',
                    region: '',
                    type: []
                }
            }
        },
        methods: {
            onSubmit() {
                console.log('提交 -> ' + this.form.name + " " + this.form.region + " " + this.form.type );
            }
        }
    }
</script>

運行結果this

從這個簡單的示例,至少有兩份數據是須要父組件傳入到表單組件中的:

一、v-model對應的數據,這份數據是用戶選擇好後給父組件的,因此是雙向綁定的。

二、label 對應的數據,這裏是寫死的,既然要封裝成一個控件那麼這份數據也須要父組件傳過來。

注意 這裏須要注意的一點就是標籤的類型是input 仍是select是須要外面傳來過來的數據告知的。同時若是是select那麼還須要把option下面的數據返回。

二、封裝Form組件

新建一個CommonForm.vue,做爲封裝Form的組件

<template>
    <!--是否行內表單-->
    <el-form :inline="inline" :model="form" ref="form" label-width="100px">
        <!--標籤顯示名稱-->
        <el-form-item v-for="item in formLabel" :key="item.model" :label="item.label">
            <!--根據type來顯示是什麼標籤-->
            <el-input v-model="form[item.model]" :placeholder="'請輸入' + item.label" v-if="item.type==='input'"></el-input>
            <el-select v-model="form[item.model]" placeholder="請選擇" v-if="item.type === 'select'">
                 <!--若是是select或者checkbox 、Radio就還須要選項信息-->
                <el-option v-for="item in item.opts" :key="item.value" :label="item.label" :value="item.value"></el-option>
            </el-select>
            <el-switch v-model="form[item.model]" v-if="item.type === 'switch'"></el-switch>
            <el-date-picker v-model="form[item.model]" type="date" placeholder="選擇日期" v-if="item.type === 'date'" value-format="yyyy-MM-dd"> </el-date-picker>
        </el-form-item>
        <!--留一個插槽-->
        <el-form-item><slot></slot></el-form-item>
    </el-form>
</template>

<script>
    export default {
        //inline 屬性可讓表單域變爲行內的表單域
        //form 表單數據 formLabel 是標籤數據
        props: {
            inline: Boolean,
            form: Object,
            formLabel: Array
        }
    }
</script>

這樣一個簡單的表單公共組件就完成了。


1、封裝一個Table組件

一、封裝思路

一樣咱們須要去看下element有關表格最簡單的示例。Table 表格

代碼示例

<template>
    <el-table
            :data="tableData"
            style="width: 100%">
        <el-table-column
                prop="date"
                label="日期"
                width="180">
        </el-table-column>
        <el-table-column
                prop="name"
                label="姓名"
                width="180">
        </el-table-column>
        <el-table-column
                prop="address"
                label="地址">
        </el-table-column>
    </el-table>
</template>

<script>
    export default {
        data() {
            return {
                tableData: [{
                    date: '2017-05-04',
                    name: '小小',
                    address: '浙江省杭州市千島湖鎮 陽光路'
                }, {
                    date: '1956-05-04',
                    name: '爺爺',
                    address: '浙江省杭州市千島湖鎮 清波花園'
                }, {
                    date: '1958-05-04',
                    name: '奶奶',
                    address: '浙江省杭州市千島湖鎮 冬瓜烏'
                }]
            }
        }
    }
</script>

運行結果

從這個簡單的示例,至少也是兩份數據是須要父組件傳入到表格組件中的:

一、v-model對應的數據,這份數據是用戶選擇好後給父組件的。

二、label 對應的數據,這裏是寫死的,既然要封裝成一個控件那麼這份數據也須要外面傳過來。

注意 這裏除了上面這兩份數據外,還有一份數據在實際開發中也是須要的,那就是分頁信息,由於通常table數據都會比較多因此分頁仍是很是須要的。

二、封裝Table組件

新建一個CommonTable.vue,做爲封裝Table的組件

<template>
    <div class="common-table">
        <!--stripe	是否爲斑馬紋  v-loading在請求數據未返回的時間有個加載的圖案,提升用戶體驗-->
        <el-table :data="tableData" height="90%" stripe v-loading="config.loading">
            <!--第一行爲序號 默認寫死-->
            <el-table-column label="序號" width="85">
                <!--slot-scope="scope" 這裏取到當前單元格,scope.$index就是索引 默認從0開始這裏從1開始-->
                <template slot-scope="scope">
                    <span style="margin-left: 10px">{{ (config.page - 1) * 20 + scope.$index + 1 }}</span>
                </template>
            </el-table-column>
            <!--show-overflow-tooltip 當內容過長被隱藏時顯示 tooltip-->
            <el-table-column show-overflow-tooltip v-for="item in tableLabel" :key="item.prop" :label="item.label" :width="item.width ? item.width : 125">
                <!--其實能夠在上面:prop="item.prop"就能夠顯示錶單數據 這裏設置插槽的方式話更加靈活 咱們能夠寫樣式-->
                <template slot-scope="scope">
                    <span style="margin-left: 10px">{{ scope.row[item.prop] }}</span>
                </template>
            </el-table-column>
            <!--操做-->
            <el-table-column label="操做" min-width="180">
                <template slot-scope="scope">
                    <el-button size="min" @click="handleEdit(scope.row)">編輯</el-button>
                    <el-button size="min" type="danger" @click="handleDelete(scope.row)">刪除</el-button>
                </template>
            </el-table-column>
        </el-table>
        <!--分頁-->
        <el-pagination class="pager" layout="prev, pager, next" :total="config.total" :current-page.sync="config.page" @current-change="changePage" :page-size="20"></el-pagination>
    </div>
</template>

<script>
    // config分頁數據,這裏面至少包括當前頁碼 總數量
    export default {
        props: {
            tableData: Array,
            tableLabel: Array,
            config: Object
        },
        methods: {
            //更新
            handleEdit(row) {
                this.$emit('edit', row)
            },
            //刪除
            handleDelete(row) {
                this.$emit('del', row)
            },
            //分頁
            changePage(page) {
                this.$emit('changePage', page)
            }
        }
    }
</script>

3、示例

這裏展現用戶管理組件(UserManage.vue),它使用了上面兩個封裝後的組件。

<template>
  <div class="manage">
      <el-dialog :title="operateType === 'add' ? '新增用戶' : '更新用戶'" :visible.sync="isShow">
          <common-form :formLabel="operateFormLabel" :form="operateForm" ref="form"></common-form>
          <div slot="footer" class="dialog-footer">
              <el-button @click="isShow = false">取 消</el-button>
              <el-button type="primary" @click="confirm">確 定</el-button>
          </div>
      </el-dialog>
      <div class="manage-header">
          <el-button type="primary" @click="addUser">+ 新增</el-button>
          <common-form inline :formLabel="formLabel" :form="searchFrom">
              <el-button type="primary" @click="getList(searchFrom.keyword)">搜索</el-button>
          </common-form>
      </div>
      <!--依次是: 表格數據 表格標籤數據 分頁數據  列表方法 更新方法 刪除方法-->
      <common-table :tableData="tableData" :tableLabel="tableLabel" :config="config" @changePage="getList()" @edit="editUser" @del="delUser"></common-table>
  </div>
</template>

<script>
    import CommonForm from '../../components/CommonForm'
    import CommonTable from '../../components/CommonTable'
    export default {
        components: {
            CommonForm,
            CommonTable
        },
        data() {
            return {
                operateType: 'add',
                isShow: false,
                tableData: [],
                tableLabel: [
                    {
                        prop: 'name',
                        label: '姓名'
                    },
                    {
                        prop: 'age',
                        label: '年齡'
                    },
                    {
                        prop: 'sexLabel',
                        label: '性別'
                    },
                    {
                        prop: 'birth',
                        label: '出生日期',
                        width: 200
                    },
                    {
                        prop: 'addr',
                        label: '地址',
                        width: 320
                    }
                ],
                config: {
                    page: 1,
                    total: 30,
                    loading: false
                },
                operateForm: {
                    name: '',
                    addr: '',
                    age: '',
                    birth: '',
                    sex: ''
                },
                operateFormLabel: [
                    {
                        model: 'name',
                        label: '姓名',
                        type: 'input'
                    },
                    {
                        model: 'age',
                        label: '年齡',
                        type: 'input'
                    },
                    {
                        model: 'sex',
                        label: '性別',
                        type: 'select',
                        opts: [
                            {
                                label: '男',
                                value: 1
                            },
                            {
                                label: '女',
                                value: 0
                            }
                        ]
                    },
                    {
                        model: 'birth',
                        label: '出生日期',
                        type: 'date'
                    },
                    {
                        model: 'addr',
                        label: '地址',
                        type: 'input'
                    }
                ],
                searchFrom: {
                    keyword: ''
                },
                formLabel: [
                    {
                        model: 'keyword',
                        label: '',
                        type: 'input'
                    }
                ]
            }
        },
        methods: {
            getList(name = '') {
                this.config.loading = true
                // 搜索時,頁碼須要設置爲1,才能正確返回數據,由於數據是從第一頁開始返回的
                name ? (this.config.page = 1) : ''
                this.$http
                    .get('/api/user/getUser', {
                        params: {
                            page: this.config.page,
                            name
                        }
                    })
                    .then(res => {
                        this.tableData = res.data.list.map(item => {
                            item.sexLabel = item.sex === 0 ? '女' : '男'
                            return item
                        })
                        this.config.total = res.data.count
                        this.config.loading = false
                    })
            },
            addUser() {
                this.operateForm = {}
                this.operateType = 'add'
                this.isShow = true
            },
            editUser(row) {
                this.operateType = 'edit'
                this.isShow = true
                this.operateForm = row
            },
            confirm() {
                if (this.operateType === 'edit') {
                    console.log(this.operateForm)
                    this.$http.post('/api/user/edit', this.operateForm).then(res => {
                        console.log(res.data)
                        this.isShow = false
                        this.getList()
                    })
                } else {
                    this.$http.post('/api/user/add', this.operateForm).then(res => {
                        console.log(res.data)
                        this.isShow = false
                        this.getList()
                    })
                }
            },
            delUser(row) {
                this.$confirm('此操做將永久刪除該文件, 是否繼續?', '提示', {
                    confirmButtonText: '肯定',
                    cancelButtonText: '取消',
                    type: 'warning'
                })
                    .then(() => {
                        let id = row.id
                        this.$http
                            .get('/api/user/del', {
                                params: {
                                    id
                                }
                            })
                            .then(res => {
                                console.log(res.data)
                                this.$message({
                                    type: 'success',
                                    message: '刪除成功!'
                                })
                                this.getList()
                            })
                    })
                    .catch(() => {
                        this.$message({
                            type: 'info',
                            message: '已取消刪除'
                        })
                    })
            }
        },
        created() {
            this.getList()
        }
    }
</script>

<style lang="scss" scoped>
    @import '@/assets/scss/common';
</style>


別人罵我胖,我會生氣,由於我內心認可了我胖。別人說我矮,我就會以爲可笑,由於我內心知道我不可能矮。這就是咱們爲何會對別人的攻擊生氣。
攻我盾者,乃我心裏之矛(15)
相關文章
相關標籤/搜索