前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >element-ui 表格hook 及相关组件

element-ui 表格hook 及相关组件

作者头像
copy_left
发布2020-04-16 19:13:37
8240
发布2020-04-16 19:13:37
举报
文章被收录于专栏:方球方球
使用例子
代码语言:javascript
复制
<template>
  <div>
    <Searchbar :searchBarConf='searchBarConf'/>
    <Table :tableConf='tableConf'>
         <div slot="btns" slot-scope="slotProps" v-bind="slotProps.itemProps">
          <el-button type='text' @click="onEditor(slotProps)" > 编辑 </el-button>
        </div>
    </Table>
    <Pagination />
  </div>
</template>

<script>
import { reactive, computed, toRefs, provide } from '@vue/composition-api'
import {
  tableConf,
  searchBarConf,
  confHook
} from './model'
import { delPop, reqSuccessTip, reqFailTip, asyncVessel } from '@/utils/tool'
import * as api from './api'
import {
  tableHook,
  injectMark,
  Pagination,
  Searchbar,
  Table
} from '@/components/manage-table/index.js'

    
 const tableConf = {
    props: {

    },
    columns: [
        { label: '用户id', prop: 'id', align: 'center', sortable: true },
        { label: '用户昵称', prop: 'realName', align: 'center' },
        { label: '参团数', prop: 'joinGroupNum', align: 'center', sortable: true },
        { label: '订货数', prop: 'buyProductNum', align: 'center', sortable: true },
        { label: '操作', prop: 'btns', align: 'center', width: 80, slot: 'btns' }
    ]
  }
 
const searchBarConf = [

    {
      col: 6,
      cmp: 'el-input',
      cmpProps:{
          size:'small',
          placeholder: '请输入完整的手机号码'
      },
      formItemProp: {
        label: '手机号码',
        prop: 'phone'
      },
    },

  ]
 
export default {
  components:{
    Pagination,
    Searchbar,
    Table
  },

  setup(){
      
    // 创建state
    const tableState = tableHook( api.tableList )
    
    // 注入组件依赖
    provide(injectMark, tableState)
    
    // 表格更新
    const updateTable = tableState.onSearchNoQuery
    const onEditor = (row) => {
        console.log(row);
        updateTable()
    }
    
    return {

      tableConf,
      searchBarConf,
     
    }
  }

 
}
</script>
tableHook实现
代码语言:javascript
复制
/**
  * author: huhaiguo
  * date: 2019-51-26 10:12
  * summary: 表格功能逻辑
  */
import { reactive, computed, toRefs, ref, watch } from '@vue/composition-api'
import cloneDeep from 'lodash/cloneDeep'


import { 
  asyncVessel
} from '@/utils/tool'

export const injectMark = 'MANAGE_TABLE' 

/**
 * 
 * @param { Function } update 表格数据请求接口 
 * @param { Object } initQuery 搜素条初始参数
 * @param { Object } options 设置项 
 */
export default function tableHook( update, initQuery={}, options={}){

  // 默认配置
  const defOptions = {
    pageSize: 10,
    totalCount: 0,
    currentPage: 1,
    tableList: [],
  }

  const state = reactive(Object.assign({}, defOptions, options))
  
  // 表格对象,用于获取对象上的方法
  const tableEle = ref(null)

  // 设置搜索条参数
  const setQuery = (initQuery) => reactive({
    pageSize: computed(() => state.pageSize),
    pageNo: computed(() => state.currentPage),
    ...cloneDeep(initQuery),
  })
  
  
  // 重置搜索条参数
  let query = ref(setQuery(initQuery))
   

  // 向外开放查询参数
  watch(() => query.value, () => state.localCopyQuery&&state.localCopyQuery(query.value))
  
  // 搜索条重置
  const resetQuery = () => query.value = setQuery(initQuery)

  // 请求表格数据
  async function onSearch(params=query.value){
    
    const [ res, err ] = await asyncVessel(update(params)) 

    if(err){
      console.error('TABLE_ERROR: ', err)
      return
    }
    
    const { result, totalCount } = res
    state.tableList = result
    state.totalCount = totalCount
    
  }

  // 分页选择
  const onCurrentChange = num => {
    state.currentPage = num
    onSearch()
  }
  
  // 重置表格数据
  const restTable = () => {
    resetQuery()
    onCurrentChange(1)
  }


  // 初始请求
  restTable()

  return {
    query,
    tableEle,
    restTable,
    resetQuery,
    onSearch,
    onSearchNoQuery: () => onSearch(),
    onCurrentChange,
    ...toRefs(state)
    
  }
  
}
搜索条
代码语言:javascript
复制
<template>
<div style="margin-bottom: 40px">
    <el-card shadow="hover" body-style="padding: 0">
        <DefTableTopbar @search='onSearchHandler' @reset='onResetHandler' />
        <div style="padding: 20px; padding-bottom: 2px">
            <Form :itemsConf='searchBarConf' :model='query' />
        </div>
    </el-card>
</div>
</template>

<script>
import DefTableTopbar from './searchbar-btns'
import Form from '../form-container/index.vue'
import { toRefs, inject } from '@vue/composition-api'
import { injectMark } from './table-hook'

export default {

    components: {
        DefTableTopbar,
        Form
    },
    
    props: {

        searchBarConf:{
            default(){return {}}
        },
        
    },
    
    setup(){
        const allState = inject(injectMark)
    
        const onSearchHandler = () => {
            allState.currentPage = 1
            allState.onSearch()
        }

        const onResetHandler = () =>{
            allState.restTable()
        }
        
        return {
            onSearchHandler,
            onResetHandler,
            ...toRefs(allState)
        }
    }

}
</script>
分页
代码语言:javascript
复制
<template>
  <div style='margin-top: 20px'>
   <el-card bodyStyle="padding: 10px 20px" shadow='hover'>
        <Pagination
        @current-change='onCurrentChange'
        :total='totalCount' 
        :pageSize='pageSize' 
        :currentPage='currentPage' >
        </Pagination>
    </el-card>
  </div>
</template>

<script>
import { toRefs, inject } from '@vue/composition-api'
import { injectMark } from './table-hook'

const Pagination = ctx => {

  const _defaultConf = {

    ['layout']: ['total', 'prev', 'pager', 'next',  'jumper'].join(','),
    ['current-page']: '',
    ['page-sizes']: [10],
    ['page-size']: 10,
    ['total']: 0,
    ['currentPage']: 1,
    
  }

  if(ctx.props){
    ctx.props = Object.assign({}, _defaultConf, ctx.props)  
  }

  return (
    <el-pagination style={{padding:0, marginTop:0}} { ...ctx } on={ ctx.listeners } ></el-pagination>
  )
   
} 

export default {

    components: {
      Pagination
    },

    setup(){
        const allState = inject(injectMark)
        return toRefs(allState)
    }

}

</script>
表格
代码语言:javascript
复制
import CadTopBar from '@/components/card-top-bar'
import { inject } from '@vue/composition-api'
import { injectMark } from './table-hook'

const Table = {

    props:{
        tableConf:{
            default(){return {}}
        },
       
    },

    setup(props){
        const allState = inject(injectMark)
        
        return {
            tableList: allState.tableList 
        }
    },

    render(){

        const { tableList, tableConf } = this
        
        // 表格列
        const tableColumns = tableConf.columns.map((item, index) =>{

            // child 插槽
            if(item.child){

                const Cmp = item.child
                const scopedSlots = {
                    default: slotprops => [
                        <Cmp slotprops={slotprops} on={ item.on } attrs={ item } ></Cmp>
                    ]
                }
                
                return <el-table-column  key={index} props={item} scopedSlots={scopedSlots} ></el-table-column>
            }

            // slot 插槽
            if(item.slot){

                const Cmp = this.$scopedSlots[ typeof item.slot === 'string' ? item.slot : item.prop]
                
                if(!Cmp) return 
                
                const scopedSlots ={
                    default: slotprops => [
                        Cmp(slotprops),
                    ]
                }

                return <el-table-column key={index} props={item} scopedSlots={scopedSlots} ></el-table-column>
                
            }
            
            // 默认column
            return <el-table-column key={index} props={item} ></el-table-column>
            
        })

        // topbar 插槽
        let Topbar = this.$slots['table-top-bar']

        return (

            <el-card body-style='padding: 0' shadow='hover' >

                <CadTopBar title='数据列表'>
                    { Topbar }
                </CadTopBar>
            
                <el-table ref='tableEle' data={ tableList } listeners={ tableConf.on } attrs={ tableConf.props }  >
                    { tableColumns }
                </el-table>
    
            </el-card>
            
        )
        
    }
    
}


export default Table
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用例子
  • tableHook实现
  • 搜索条
  • 分页
  • 表格
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档