一次需求组件的封装

140 阅读2分钟

简介

简单的组件封装。Vue2+ElementUI,主要记录实现思路,步骤。

UI

角色 -添加角色 image.png

image.png

人员 - 添加人员 image.png

image.png

下面还有部分机构....,有人肯定会怀疑为什么要用这种方式,不用el-tree,emmm...。

实现思路

  1. 提取公共的部分 el-table 就是整一个table,包括搜索栏, 那么页面上代码就是变成了
    <A></A>
       <el-dialog>
            <A></A>
       </el-dialog>

显然,有些重复数据

2.将以上代码再封装一层,那么页面上代码就是变成了

    <B></B>
   // B组件
     <A></A>
    <el-dialog>
        <A></A>
    </el-dialog>
  1. (角色,人员)不同部分(搜索栏)使用slot
//A组件
<div>
<slot />
   //tabel组件,这里可以将el-table 二次封装,
<el-table></el-table>
 </div>

// B组件
     <A>
        <slot /> // 暴露到顶级组件
      </A>
    <el-dialog>
          <A>
            <slot /> // 暴露到顶级组件
          </A> 
    </el-dialog>
  1. 将搜索栏代码封装一层,使用component(类似form-create的做法),或者是一个type去匹配el-input / el- select
// C组件
    <el-row>
        <el-form>
        ...
        </el-form>
        <slot>按钮</slot>
    </el-row>

// B组件
     <A>
        <C>
        <el-button>按钮</el-button> //至于为什么 按钮需要放在B组件
        </C>
      </A>
    <el-dialog>
            <A>
               <C>
             <el-button>按钮</el-button> //至于为什么 按钮需要放在B组件
            </C>
            </A>
             <el-button>提交</el-button>
    </el-dialog>
  1. 将C 组件放入到A组件内部
//A组件
<div>
    <C>
        <el-button>按钮</el-button>
    </C>
   //tabel组件,这里可以将el-table 二次封装,
<el-table></el-table>
 </div>

6.最终 A,B,C组件

//A组件
<div>
   <C>
       <el-button>按钮</el-button>
   </C>
  //tabel组件,这里可以将el-table 二次封装,
<el-table></el-table>
</div>

// B组件
     <A>
      </A>
    <el-dialog>
            <A>
            </A>
            <el-button>提交</el-button>
    </el-dialog>
// C组件
    <el-row>
        <el-form>
        ...
        </el-form>
        <slot>按钮</slot>
    </el-row>

  1. 数据事件部分

    7.1 从要展示的数据出发,就是el-table 的data数据,调接口方法,接口方法必定是顶级组件传入到A组件,因为数据需要在A组件使用,那么formSearch( C组件中的formSearch)也需要放在A组件然后向C组件传递。

//A组件
<div>
   <C :formSearch='formSearch'>
       <div>
           // 这里用一个变量去区别,就不展开了
             <el-button>查询</el-button> // 调顶级组件传入的getdata(formSearch).then(res=>...)
             <el-button>重置</el-button> // 重置 formSearch={}
            <el-button>新增</el-button>  // $emit,向B组件传递
       </div>
   </C>
  //tabel组件,这里可以将el-table 二次封装,
<el-table >
   

//用一个变量区分,调顶级组件传入的deleteItem(row,index).then(res=>...),或者是使用$emit
   <el-button>删除按钮</el-button> 
   </el-table> 
</div>

7.2 选中数据的提交,2种方式,方式1:将勾选数据存放在A组件中,点击B组件中的提交按钮,去A组件中获取数据,方式2:勾选数据时,A组件$emit数据到B组件,点击B组件中的提交按钮,提交数据。更倾向第2种

// B组件
   <A @selection-change /> 

7.3 其他数据和事件的传递,传递 顶级组件 =》 B组件=》A 组件=》C组件。那么每层将需要的数据props声明,不需要的数据使用 v-bind="attrs"事件使用von="attrs" 事件使用v-on="listeners" (vue2)

  1. 对于不使用form-create,将搜索栏放在顶级组件,方案是将formSearch, 按钮事件(search,add,reset),从A组件中暴露。因为如果按钮事件都在顶级就是重复了,再在table数据也是需要从顶级一层层传递到A组件。
// 原本B组件
     <A>
        <slot /> // 暴露到顶级组件
      </A>
    <el-dialog>
          <A>
            <slot /> // 暴露到顶级组件
          </A> 
    </el-dialog>


修改后

//A组件
<div>
        ////暴露到顶级组件 向上层组件传递数据
     <slot formSearch="formSearch" :search="search" :reset="reset"/>   
   //tabel组件,这里可以将el-table 二次封装,
<el-table></el-table>
 </div>
 
 

//B组件
       <A>
         <template #default={formSearch,search,reset}>
         //暴露到顶级组件 向上层组件传递数据
         <slot formSearch="formSearch" :search="search" :reset="reset"/> 
        </template>
      </A>
    <el-dialog>
          <A>
            <slot /> // 暴露到顶级组件
          </A> 
    </el-dialog>


页面使用


 <B ...>
   <template #default={formSearch,search,reset}>
        // 搜索栏   
        <el-form></el-form>
    </template>
 </B>
 

总结

  1. 提取相同部分,table(A组件),整个组件(B组件)
  2. 归纳不同部分,搜索栏,请求地址(获取数据,删除数据,提交数据等接口),table的columns。
  3. 数据定义的位置:formSearch由A组件提供,因为table数据在A组件,那么发起请求在A组件,那么formSearch放在A组件。第二点不同部分的数据都是由顶级提供(搜索栏formcreate,table的columns)
  4. 事件定义的位置:大多跟随数据,如reset,search。不同部分的事件都是由顶级提供(接口事件),添加按钮事件(show dialong)由B组件提供,dialong 在B组件中。
  5. 数据传递,事件传递,v-bind="attrs"von="attrs" v-on="listeners"

有不同观点的可以谈论谈论😊