前端组件化设计——布局、逻辑、视图

一、拆分页面:将一个页面拆分成几个部分,如:父子包裹、左右或上下布局

<!-- 上下布局 -->
<template>
  <el-card
    style="background: #fff;min-height: 800px"
    shadow="never">
    <div
      slot="header"
      style="height: 28px">
      <!-- 标题 -->
      <span>xxxx列表<span/>
    </div>
    <!--内容-->
    <div>
      <featureTable :parameters="parameters"/>
    </div>
  </el-card>
</template>

二、表格操作部分,属于中间件——处理复杂逻辑、数据转换

1.纯展示的表格

<template>
  <el-card id="activityManage">
    <div slot="header">
      <el-button
        type="primary"
        @click="addRowDialog"
      >新建</el-button>
    </div>
    <el-row >
      <el-col>
        <CommonTable
          :table-data="tableData"
          :table-column="tableColumn"
          height="680"
          :loading="listLoading"
        >
          <el-table-column
            type="index"
            label="序号"
            align="center"
            width="60"
            slot="header">
            <template slot-scope="scope">
              {{ (currentPage-1)*pageSize+scope.$index+1 }}
            </template>
          </el-table-column>
          <el-table-column
            label="操作"
            align="center"
            width="150"
            slot="footer">
            <template slot-scope="scope">
              <el-button-group>
                <el-button
                  type="primary"
                  @click="editRowDialog(scope.$index, scope.row)">编辑</el-button>
                <el-button
                  type="danger"
                  @click="deleteRowDialog(scope.$index, scope.row)">删除</el-button>
              </el-button-group>
            </template>
          </el-table-column>
        </CommonTable>
        <!-- 分页 -->
        <Pagination
          style="margin-top:20px"
          :table-begin="tableBeigin"
          @changTable="getTablePage"/>
        <!-- 2.对话框 -->
        <el-dialog
          top='60px'
          :title="dialogTitle"
          :visible.sync="dialogVisible"
          :width="dialogWidth"
          :close-on-click-modal="false"
          :show-close="!showCancelButton"
        >
          <component
            :is='componentType'
            :show-btn='showCancelButton'
            :form-info='formInfo'
            @form-change='hanldeFormChange'
          />
        </el-dialog>
    </el-row>
  </el-card>
</template>

2.复杂的内容需要自定义

<template>
  <div>
    <!-- 新建+搜索 -->
    <el-row>
      <el-col :span="4">
        <el-button
          type="primary"
          @click="featureNew"
        >新建xxx</el-button>
      </el-col>
      <el-col
        :span="4"
        :offset="parameters.privatePage==='个人'?16:20">
        <el-input
          v-model="searchInfo"
          placeholder="关键字搜索"
          clearable
          @clear="searchInfoMatch"
          @keyup.enter.native="searchInfoMatch(searchInfo)">
          <el-button
            slot="append"
            icon="el-icon-search"
            @click="searchInfoMatch(searchInfo)"/>
        </el-input>
      </el-col>
    </el-row>
    <!-- 自定义表格合并 -->
    <el-table
      style='margin-top:20px'
      v-loading="parameters.loading"
      :data="tableData"
      border
      :span-method="colspanMethod"
    >
      <el-table-column
        show-overflow-tooltip
        width="120"
        align="center"
        prop="type"
        label="xx分类"
      />
      <!--操作-->
      <el-table-column
        align="center"
        label="操作"
        width="200">
        <template slot-scope="scope">
          <el-button-group>
            <el-button
              @click="tableRowChange(scope, 'edit')"
              type="primary"
              :disabled="scope.row.app_id===''">查看编辑</el-button>
          </el-button-group>
          <el-dropdown
            trigger="click">
            <el-button type="primary">
              更多<i class="el-icon-arrow-down el-icon--right"/>
            </el-button>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item
                style="padding:0"
                v-for="(item,index) in tableRowMore"
                :key='index'>
                <el-button
                  style="padding: 7px 15px;100%"
                  @click="tableRowChange(scope, item.action)"
                  type="text"
                  :disabled="scope.row.app_id===''">{{ item.name }}</el-button>
              </el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件 -->
    <el-pagination
        style="margin-top: 15px"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="pageSizes"
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="pageTotal"/>
    <!-- 2.对话框 -->
    <el-dialog
      top='60px'
      :title="dialogTitle"
      :visible.sync="dialogVisible"
      :width="dialogWidth"
      :close-on-click-modal="false"
      :show-close="!showCancelButton"
    >
        xxx表单内容xxx
        <span slot="footer">
          <el-button
            @click="handleClose('ruleForm')">取消</el-button>
          <el-button
            type="primary"
            @click="submitNewActivity('ruleForm')">确定</el-button>
        </span>
    </el-dialog>
</template>

三、展示组件:

比如通用表格组件、搜索框组件、分页组件、表单校验组件(如果大于1个使用component组件动态切换)、按钮弹框(放大编辑)、通用的编辑器组件、可视化图形组件等,当然通用的函数、数据配置等也可以抽离出来,或者使用第三方库实现:

import CommonTable from 'module-comp/table/CommonTable'
import _ from 'lodash' // 第三方库
import {getSpanArr} from '@/utils/xxxManage'// 公共的方法或数据配置
import canvasInstanceStatus from 'mixins/xxxStatus'// 插入实现方法,比较隐晦不好维护mixins:[xxx]
import Pagination from './Pagination'// 通用的分页组件或自定义需要的内容

化繁为简:

比如上面的表格操作比较繁琐,使用数组遍历输出菜单,设置通用的方法调用(设置一个type区分);

又如:表格输出列自适应时,标题也可以设置成一个数组格式,通过遍历的形式进行输出,示例在下面

    <el-table
      :max-height="height"
      ref="commonTable"
      :data="tableData"
      :size="size"
      :stripe="stripe"
      border
      highlight-current-row
      v-loading="loading"
      :row-class-name="tableRowClassName"
      @filter-change="filterChange"
      @selection-change="handleSelectionChange"
      :row-key="rowKey"
    >
      <!--自定义插入-->
      <slot name="header"/>
      <el-table-column
        v-for="(item, index) in tableColumn"
        :key="`key_${index}`"
        :prop="item.prop"
        :label="item.label"
        show-overflow-tooltip
        :sortable='sortable'
        align="center"
      >
        <template slot-scope="scope">
          <div v-if="tableColumn[index].prop === 'field_key'">
            <span>{{ keyOptionsObj[scope.row.field_key] }}</span>
          </div>
          <div v-else>
            <span>{{ scope.row[tableColumn[index].prop] }}</span>
          </div>
        </template>
      </el-table-column>
      <!--自定义插入-->
      <slot name="footer"/>
    </el-table>

需要注意的问题:组件的通讯问题,通常组件需要进行联动效果,这需要注意传值的技巧(只传一个对象)、以及回调方法尽量设置到中间件(连续回调2次以上就不利于维护了)......

原文地址:https://www.cnblogs.com/wheatCatcher/p/11239219.html