网络知识 娱乐 Vue element ui的二次封装

Vue element ui的二次封装

文章目录

  • 一、element ui二次封装的优缺点
  • 二、element ui二次封装的过程及原理
  • 三、效果示例
    • 1.视频
    • 2.图片
  • 四、代码编写
    • 1.可复用的子组件主界面TableContainer
    • 2.可复用的子组件弹窗TableDialog
    • 3.UserCon父组件引用实例
  • 总结


一、element ui二次封装的优缺点

优点:组件复用性高,利于后期维护。在封装好后能极大提高开发效率,适合用于后台管理系统、页面繁多或具有多个及其相似的页面工厂系统里。

缺点:封装过程较难,封装后的页面较为单一,如不写注释代码可读性较差,不适合用于具有变化多、逻辑复杂的页面的系统。

二、element ui二次封装的过程及原理

主要以父传子的形式实现,将需要复用的组件进行封装成子组件,子组件内主要负责页面的展示,Props接收父组件传来的值,将需要进行的逻辑操$emit给父组件。父组件引入子组件并向子组件内传入不同的值,使页面显示不同的文字描述,接收子组件传来的值编写函数来进行逻辑操作。

主界面封装:将element ui中的表格Table、分页Pagination、Input输入框、Select搜索框等放进一个组件内,在props里定义好要从父组件接收的值,在函数里定义好 $emit传给父组件的值。

弹窗封装:将element ui中的对话框Dialog、表单Form、上传Upload等放进一个组件内,在props里定义好要从父组件接收的值,在函数里定义好 $emit传给父组件的值。

三、效果示例

1.视频

封装界面实例

2.图片

在这里插入图片描述
在这里插入图片描述

四、代码编写

1.可复用的子组件主界面TableContainer

<template>
  <div>
    <!-- 顶部按钮部分 -->
    <div class="Top">
      <div v-if="TopBtu" class="top_btu">
        <el-button
          v-for="(item, index) in TopBtu"
          :key="index"
          :type="item.type"
          :icon="item.icon"
          size="small"
          @click="cast(item.incident)"
          >{{ item.label }}</el-button
        >
      </div>
      
      <!-- 搜索框部分 -->
      <div class="searchK" v-if="searchK">
        <el-form :model="searchform" ref="searchform" label-width="100px">
          <div class="searchinput">
            <el-form-item
              v-for="(item, index) in searchK"
              :key="index"
              :label="item.label"
              :prop="item.prop"
              label-width="150px"
            >
              <el-input
                v-if="item.type === 'number' || item.type === 'text'"
                :type="item.type"
                :placeholder="'请输入要搜索的' + item.label"
                v-model="searchform[item.prop]"
                clearable
                style="width: 220px"
              ></el-input>
              <el-select
                v-if="item.type === 'select'"
                :placeholder="'请输入' + item.label"
                v-model="searchform[item.prop]"
              >
                <el-option
                  v-for="item in options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                >
                </el-option>
              </el-select>
            </el-form-item>
            
            <!--搜索框按钮部分-->
            <el-form-item>
              <el-button
                type="primary"
                size="small"
                icon="el-icon-search"
                item
                @click="submitForm(searchform)"
                >查询</el-button
              >
              <el-button
                icon="el-icon-refresh-right"
                type="info"
                size="small"
                @click="resetForm(searchform)"
                >重置</el-button
              >
              <!--列配置按钮部分-->
              <el-button
                type="primary"
                class="el-icon-menu"
                @click="lieconfig"
                v-if="this.lieconfigshow == false"
                size="small"
                >列配置</el-button
              >
              <div
                style="display: inline-block; margin-left: 30px"
                v-show="this.lieconfigshow == true"
              >
                排序<el-switch
                  v-model="issortable"
                  active-color="#13ce66"
                  inactive-color="#ff4949"
                  :active-value="true"
                  :inactive-value="false"
                ></el-switch>
                <el-tooltip
                  class="item"
                  effect="dark"
                  content="查询"
                  placement="top"
                >
                  <i
                    class="el-icon-search"
                    @click="submitForm"
                    style="font-size: 25px; color: DodgerBlue"
                  ></i>
                </el-tooltip>
                <!--列配置设置按钮部分-->
                <el-tooltip
                  class="item"
                  effect="dark"
                  content="设置"
                  placement="top"
                >
                  <el-popover placement="top" width="300" v-model="visible">
                    <div>
                      <el-checkbox
                        :indeterminate="isIndeterminate"
                        v-model="checkAll"
                        :checked="true"
                        @change="handleCheckAllChange"
                        >列配置</el-checkbox
                      >
                      <el-button
                        type="text"
                        style="margin-left: 80px; color: red"
                        @click="reset"
                        >重置</el-button
                      >
                      <el-row v-for="(item, index) in tableProp">
                        <el-col :span="12">
                          <el-checkbox-group
                            v-model="selecttable"
                            @change="handleCheckedChange"
                          >
                            <el-checkbox
                              style="margin-top: 15px"
                              :label="item"
                              :key="index"
                              :checked="true"
                              >{{ item.name }}</el-checkbox
                            >
                          </el-checkbox-group>
                        </el-col>
                        <el-col :span="12">
                          <span>表格宽度 </span>
                          <el-input
                            v-model="item.width"
                            style="width: 60px; margin-top: 5px"
                          ></el-input>
                          <span>px</span>
                        </el-col>
                      </el-row>
                    </div>
                    <i
                      class="el-icon-setting"
                      slot="reference"
                      style="font-size: 25px; color: DodgerBlue"
                    ></i>
                  </el-popover>
                </el-tooltip>
                <el-tooltip
                  class="item"
                  effect="dark"
                  content="重置"
                  placement="top"
                >
                  <i
                    class="el-icon-refresh"
                    style="font-size: 25px; color: DodgerBlue"
                    @click="mainreset"
                  ></i>
                </el-tooltip>
                <el-tooltip
                  class="item"
                  effect="dark"
                  content="普通查询"
                  placement="top"
                >
                  <i
                    class="el-icon-d-arrow-left"
                    @click="lieconfig"
                    style="font-size: 25px; color: DodgerBlue"
                  ></i>
                </el-tooltip>
              </div>
            </el-form-item>
          </div>
        </el-form>
      </div>
      
      <!-- 表格部分 -->
      <div class="tableT">
        <el-table
          :data="tableData"//表格数据
          @select="danxuan"
          @select-all="quanxuan"
          :border="tableConfig.border"//表格边框
          style="width: 100%"
          :default-sort="{ prop: 'id', order: 'descending' }"//表格默认排列方式
        >
        
        <!--表格中的多行选择框-->
          <el-table-column
            v-if="tableConfig.selection"
            type="selection"
            width="55"
            align="center"
          >
          </el-table-column>
          <el-table-column
            fixed
            v-if="tableConfig.index"
            type="index"
            label="序号"
            align="center"
            width="50"
          >
          </el-table-column>
          
          <!--表格中的图像类型-->
          <el-table-column
            v-for="(item, index) in selecttable"
            v-if="item.prop == 'avatar' || item.prop == 'preimg'"
            :key="index"
            :prop="item.prop"
            :label="item.name"
            :width="item.width"
            align="center"
          >
            <template slot-scope="scope">
              <img
                v-if="scope.row[item.prop]"
                :src="scope.row[item.prop]"
                min-width="70"
                height="70"
              />
              <el-tag v-else type="primary" disable-transitions>无图片</el-tag>
            </template>
          </el-table-column>
          <el-table-column
            v-for="(item, index) in selecttable"
            v-if="item.prop !== 'avatar' && item.prop !== 'preimg'"
            :key="index"
            :prop="item.prop"//表格值
            :label="item.name"//表格名
            :width="item.width"//表格宽度
            :show-overflow-tooltip="true"//是否展示文字提示
            :formatter="item.formatter || undefined"//表格格式化
            align="center"
            :sortable="issortable"//是否可排序
          >
          </el-table-column>
          
          <!--表格内最右边操作列-->
          <el-table-column
            v-if="tableConfig.handle"
            fixed="right"
            label="操作"
            align="center"
            :min-width="210"
          >
            <template slot-scope="scope">
            <!--操作列内的按钮部分-->
              <el-button
                v-for="(item, index) in tableConfig.buttonAffairs"
                :key="index"
                @click="handleClick(item.affairs, scope.row)"
                :type="item.type"
                size="mini"
                >{{ item.name }}</el-button
              >
            </template>
          </el-table-column>
        </el-table>
      </div>
      
      <!-- 分页 -->
      <div class="block">
        <el-pagination
          v-if="tableConfig.pagin"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="page.page"
          :page-sizes="[5, 10, 50, 100]"
          :page-size="page.pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="tabletotal"
        >
        </el-pagination>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "TableContainer",
  props: {
    TopBtu: Array,//顶部按钮接收值
    searchK: Array,//搜索框接收值
    tableProp: Array,//表格字段接收值
    tableData: Array, //表格内显示的数据
    tabletotal: 0,//表格内数量接收值
    //分页对象
    page: {
      page: Number,
      pageSize: Number,
    },
    tableConfig: {//表格配置
      type: Object,
      default: function () {
        return {
          pagin: true, //是否分页
          selection: true, // 选择框
          index: true, // 序号
          border: true, // 边框
          handle: true, // 是否显示操作列
          buttonAffairs: [
          //操作列内按钮
            {
              name: "编辑",
              icon: "el-icon-plus",
              type: "primary",
              affairs: "Edit",
            },
            {
              name: "删除",
              icon: "el-icon-delete",
              type: "danger",
              affairs: "Remove",
            },
          ],
        };
      },
    },
  },
  data() {
    return {
      lieconfigshow: false,
      issortable: true,
      visible: false,
      checkAll: false,
      isIndeterminate: false,
      selecttable: [],
      //表单对象
      searchform: {},
      //批量删除数组
      batchdel: [],
    };
  },
  methods: {
    cast(val) {    //顶部按钮抛出事件
      if (val === "Remove") {
        this.$emit("simTop" + val, this.batchdel);
        return;
      }
      this.$emit("simTop" + val);
    },
    
    //列配置
    lieconfig() {
      this.lieconfigshow = !this.lieconfigshow;
    },
    handleCheckAllChange(val) {
      this.selecttable = val ? this.tableProp : [];
      this.isIndeterminate = false;
    },
    handleCheckedChange(value) {
      let checkedCount = value.length;
      this.checkAll = checkedCount === this.tableProp.length; //选中长度等于总长度时全选按钮为true
      this.isIndeterminate =
        checkedCount > 0 && checkedCount < this.tableProp.length;
    },
    
    reset() {//列配置内设置的重置按钮
      this.tableProp = this.$options.propsData.tableProp;
      this.selecttable = this.tableProp;
      this.isIndeterminate = false;
      this.checkAll = true;
    },
    mainreset() {//重置按钮抛出事件
      this.searchform = {};
      this.$emit("reset");
    },
    submitForm(searchform) {  //查询抛出事件
      this.$emit("selCX", searchform);
    },
    resetForm(searchform) {//重置按钮抛出事件
      this.searchform = {};
      this.$emit("reset");
    },
    handleClick(affairs, row) {//表格内操作列抛出事件
      this.$emit("sim" + affairs, row);
    },
    danxuan(selection) {//表格多选
      this.batchdel = selection;
    },
    quanxuan(selection) {//表格多选
      this.batchdel = selection;
    },
    handleSizeChange(val) {//分页每页大小改变操作事件
      this.page.pageSize = val;
      this.$emit("getlist", this.page);
    },
    handleCurrentChange(val) {//分页当前页改变操作事件
      this.page.page = val;
      this.$emit("getlist", this.page);
    },
  },
};
</script>

<style scoped>
.searchinput {
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
}
.el-table thead {
  background-color: aqua;
}
.block {
  margin-top: 20px;
  text-align: right;
}
</style>

2.可复用的子组件弹窗TableDialog

<template>
  <div>
    <el-dialog
      :title="title"
      :visible.sync="dialogVisible"
      :close-on-click-modal="false"
      append-to-body
      width="45%"
      @close="handleClose"
    >
      <div>
        <el-form :model="dataform" ref="popform" :inline="true" size="medium">
          <div class="dataform">
            <el-form-item
              v-for="(item, index) in PopupViewinput"
              :key="index"
              :label=