vue3中如何封装组件 下面是封装的一个当数据量比较多的时候通过弹窗表格展示分页获取数据支持搜索。的一个公共组件

效果如下 

<template>
    <div>
        <div>
            <el-input ref="inputRef" v-model="iuptu" style="max-width: 200px" @click="showSelectTable">
                <template #append>
                    <el-button @click="showSelectTable" icon="Search" />
                </template>
            </el-input>
        </div>
        <Search-select :url="url" :meta="meta" :label="namekey" :placeholder="placeholder" v-if="showSelectTableDialog"
            :title="title" :data="data" :columns="columns" :multiple="multiplef" :selected="selectedValue"
            v-model:showSelectTableDialog="showSelectTableDialog" @selected="onSelectChange"
            @close="onCloseSelectTable" />
    </div>
</template>

<script setup name="SelectTable">
import SearchSelect from "./SearchSelect"
const emit = defineEmits(['selected']);
const props = defineProps({
    title: String,
    data: Array,
    columns: Array,
    namekey: String,
    placeholder: String,
    url: String,
    meta: String,
    multiple: {
        type: Boolean,
        default: false
    },
    selected: {
        type: [String, Number, Array],
        default: () => []
    },

});
const inputRef = ref(null);
const multiplef = ref(true);
const selectedValue = ref(null);
const showSelectTableDialog = ref(false);
const iuptu = ref(null);
const showSelectTable = () => {
    showSelectTableDialog.value = true;
};
const blurInput = () => {
    if (inputRef.value) {
        inputRef.value.blur();
        console.log('Input blurred manually');
    }
};

const onSelectChange = (value) => {

    iuptu.value = value?.loginIp
    selectedValue.value = value;
    emit('selected获取数据', value);
    onCloseSelectTable()
};

const onCloseSelectTable = () => {
    console.log('Table closed');
    showSelectTableDialog.value = false;
    blurInput()
};
</script>

<style lang=" scss" scoped>


</style>
<template>
  <el-dialog :title="title" destroy-on-close @close="onClose" v-model="showSelectTableDialog" width="60%"
    append-to-body>
    <el-form :inline="true" label-width="68px">
      <el-form-item :label="label" prop="userName">
        <el-input v-model="queryParams.searchText" :placeholder="placeholder" clearable @keyup.enter="onSearch" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="onSearch">搜索</el-button>
        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-table size='small'  
    ref="multipleTableRef" 
    row-key="id"
    default-expand-all
    @select-all="selectall"
      v-loading="loading" :data="displayedData" style="width: 100%" v-model:selection="selectedRow"
      @select="handleSelectionChange">
      <el-table-column type="selection" width="55" />
      <el-table-column v-for="(column, index) in columns" :key="index" :prop="column.prop" :label="column.label" />
    </el-table>
    <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
      v-model:limit="queryParams.pageSize" @pagination="fetchData" />

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="onConfirmSelected">确认</el-button>
        <el-button type="primary" @click="onClose">关闭</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
import { ElMessage } from 'element-plus'
import request from '@/utils/request'
const props = defineProps({
  title: String,
  data: Array,
  label: String,
  placeholder: String,
  url: String,
  meta: String,
  columns: Array,
  multiple: {
    type: Boolean,
    default: false
  },
  showSelectTableDialog: {
    type: Boolean,
    default: false
  },
  selected: {
    type: [String, Number, Array],
    default: () => []
  }
});
const emit = defineEmits(['selected', 'close']);
const displayedData = ref([]);
const queryParams = reactive({
  pageNum: 1,
  pageSize: 10 ,// 初始化每页大小为 10
  searchText: ""
});
const total = ref();
const loading=ref(false)
const { title, showSelectTableDialog, selected, columns, multiple, data } = props;
const multipleTableRef = ref()


const selectedRows = ref([]);
const selectall=(roe)=>{
  console.log(roe,"fff");
    
  multipleTableRef.value.clearSelection()
}
const handleSelectionChange = (selection, row) => {
  console.log(selection, row,"fff");
  
  multipleTableRef.value.clearSelection()
  if(selection.length == 0) return
  multipleTableRef.value.toggleRowSelection(row,true)
  selectedRows.value = row;
};
const tableData= [
  {
    id: 1,
    date: '2016-05-02',
    name: 'wangxiaohu',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    id: 2,
    date: '2016-05-04',
    name: 'wangxiaohu',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    id: 3,
    date: '2016-05-01',
    name: 'wangxiaohu',
    address: 'No. 189, Grove St, Los Angeles',
    children: [
      {
        id: 31,
        date: '2016-05-01',
        name: 'wangxiaohu',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        id: 32,
        date: '2016-05-01',
        name: 'wangxiaohu',
        address: 'No. 189, Grove St, Los Angeles',
      },
    ],
  },
  {
    id: 4,
    date: '2016-05-03',
    name: 'wangxiaohu',
    address: 'No. 189, Grove St, Los Angeles',
  },
]
// 在组件挂载时加载数据
const fetchData = async () => {
  // displayedData.value = tableData

  loading.value=true
  try {
    const data = await gettabe(props.url, props.meta,
    queryParams
  )
  loading.value=false
  displayedData.value = data.rows
  total.value = data.total
  } catch (error) {
    ElMessage.error(error.message)
    loading.value=false
  }
  

};


const onSearch = () => {
  queryParams.pageNum = 1; // 重置页数
  fetchData(); // 重新获取数据
};

const onConfirmSelected = () => {
  console.log(props.multiple, "ffff获取护具", selectedRows.value);
  if (props.multiple) {
    emit('selected', selectedRows.value); // 发送选中的多行数据
  } else {
    emit('selected', selectedRows.value[0]); // 发送单行数据
  }
  emit('close'); // 触发关闭事件
};

const onClose = () => {
  emit('close'); // 触发关闭事件
};

const resetQuery = () => {
  queryParams.searchText = "";
  onSearch();
};

watch(showSelectTableDialog, (newValue) => {
  if (!newValue) {
    emit('close');
  }
});
const gettabe = (url, post, data) => {
  if (post == 'get') {
    return request({
      url: url,
      method: post,
      params: data
    })
  }
  if (post == 'post') {
    return request({
      url: url,
      method: post,
      data: data
    })
  }

}
// 在组件挂载时加载数据
fetchData();

</script>


<style lang="scss" scoped>

:deep(.el-checkbox__input is-indeterminate) {
    display: none !important;

  }
</style>

使用方式 app.component('SearchSelect', SearchSelect) 

      <!--url:请求接口,meta:请求方式,title:弹窗名称,
   columns:表格列,
   placeholder:搜索框提示,
   namekey:搜索框名称,
   onSelectChange:获取选中的参数  -->
      <SearchSelect :url="'/system/user/list'" :meta="'get'" :title="tableTitle" :columns="tableColumns"
         :placeholder="placeholder" :namekey="namekey" @selected="onSelectChange" />
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值