封装el-autocomplete下拉列表分页滚动加载

文章介绍了如何在Vue项目中创建一个名为scrollLoad的自定义指令,用于监听`el-autocomplete`下拉框的滚动,当滚动到底部时自动加载更多数据。同时展示了指令的绑定、解绑以及调用方法的示例。

添加自定义指令函数在main.js抛出,方便系统其他地方可以直接调用

// 自定义指令,监听el-autocomplete下拉框的滚动,滚动到底部就加载下一页
  Vue.directive('scrollLoad', {
    bind(el, binding, vnode) {
      function handleScroll(e) {
        let isBottom = e.target.clientHeight + e.target.scrollTop >= e.target.scrollHeight - 40
        if (isBottom && !vnode.context.loading) {
          binding.value()
        }
      }
      // 监听滚动
      let wrapDom = el.querySelector('.el-autocomplete-suggestion__wrap')
      el.__handleScroll__ = handleScroll
      el.__wrapDom__ = wrapDom
      wrapDom.addEventListener('scroll', handleScroll, false)
    },

    unbind(el, binding, vnode) {
      // 解除事件监听
      el.__wrapDom__.removeEventListener('scroll', el.__handleScroll__, false)
    },
  })

在需要使用的地方直接使用v-scrollLoad="handleScroll"

// 调用地方
<el-autocomplete
  ref="refName"
  :fetch-suggestions="remoteMethod"
  @select="handleSelect"
  v-model="completeData"
  v-scrollLoad="handleScroll"
/>
// 方法定义
handleScroll(event) {
   // 添加加载loading,避免请求未完成时重复请求导致页码和数据错乱
   if(this.moreLoading) {
        return
   }
   this.moreLoading = true
   this.page += 1
   // getData自定义的请求数据的方法,在callback里处理下拉列表的数据
   this.getData(arr=>{
      this.$refs[refName].$data.suggestions.push(...arr)
      this.$nextTick(()=>{
        this.moreLoading = !arr.length
      })
   })
}

下面的代码是干什么用的,请生成说明注释,同时还有什么改进: <template> <div class="app-container"> <el-card class="box-table"> <el-form :inline="true" class="demo-form-inline" :model="searchForm"> <el-form-item label="账号"> <el-input placeholder="请输入账号" v-model="searchForm.username"></el-input> </el-form-item> <el-form-item label="姓名"> <el-input placeholder="请输入姓名" v-model="searchForm.name"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="handleSearch">查询</el-button> <el-button @click="handleAdd">新增</el-button> </el-form-item> </el-form> <el-table v-loading="listLoading" :data="list" element-loading-text="Loading" border fit highlight-current-row size="small"> <el-table-column align="center" label="ID" prop="id"></el-table-column> <el-table-column align="center" label="账号" prop="username"></el-table-column> <el-table-column align="center" label="姓名" prop="name"></el-table-column> <el-table-column align="center" label="性别" prop="gender"> <template slot-scope="scope"> <el-tag type="success" v-if="scope.row.gender == 1">男</el-tag> <el-tag type="danger" v-else>女</el-tag> </template> </el-table-column> <el-table-column fixed="right" label="操作" width="100"> <template slot-scope="scope"> <el-button @click="handleEdit(scope.row)" type="text" size="small">编辑</el-button> <el-popconfirm title="确定删除吗?" @confirm="deleteCofirm(scope.row)"> <el-button type="text" slot="reference" size="small">删除</el-button> </el-popconfirm> </template> </el-table-column> </el-table> <el-pagination class="page-box" background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageNum" :page-sizes="[10, 20]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total"> </el-pagination> </el-card> <!-- 添加/修改的弹框 --> <el-dialog :title="dialogTitle" :visible.sync="dialogFormVisible"> <el-form label-position="left" :model="dialogForm" label-width="80px"> <el-form-item label="账号"> <el-input placeholder="请输入账号" v-model="dialogForm.username" autocomplete="off"></el-input> </el-form-item> <el-form-item label="密码"> <el-input type="password" placeholder="请输入密码" v-model="dialogForm.password" autocomplete="off"></el-input> </el-form-item> <el-form-item label="姓名"> <el-input placeholder="请输入姓名" v-model="dialogForm.name" autocomplete="off"></el-input> </el-form-item> <el-form-item label="性别"> <el-select v-model="dialogForm.gender" placeholder="请选择"> <el-option v-for="item in genderOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="dialogFormVisible = false">取 消</el-button> <el-button type="primary" @click="dialogConfirm">确 定</el-button> </div> </el-dialog> </div> </template> <script> import { findAdminPageAPI, // 导入查询管理员信息的 API addAdminAPI, // 导入新增管理员的 API modifyAdminAPI, // 导入修改管理员信息的 API removeAdminAPI, // 导入删除管理员的 API } from "@/api/admin"; export default { data() { return { list: null, // 管理员列表数据 listLoading: true, // 列表加载状态 pageSize: 10, // 每页显示条数 pageNum: 1, // 当前页码 total: 0, // 总条数 searchForm: {}, // 搜索表单数据 dialogTitle: "添加", // 弹框标题,默认为添加 dialogFormVisible: false, // 弹框显示状态 dialogForm: {}, // 弹框表单数据 genderOptions: [ // 性别选项 { label: &#39;男&#39;, value: 1 }, { label: &#39;女&#39;, value: 2 } ], }; }, created() { this.fetchData(); }, methods: { handleSizeChange(val) {//每页显示条数改变 this.pageSize = val; this.fetchData(); }, handleCurrentChange(val) {//当前页码改变 this.pageNum = val; this.fetchData(); }, handleSearch() {//点击搜索按钮 this.fetchData(); }, async fetchData() {//查询数据 this.listLoading = true; let response = await findAdminPageAPI( this.pageNum, this.pageSize, this.searchForm ); this.list = response.data.records; this.total = response.data.total; this.listLoading = false; }, handleAdd() {//点击新增按钮-显示弹框 this.dialogTitle = "新增"; this.dialogFormVisible = true; this.dialogForm = {gender: 1}; }, handleEdit(row) {//点击修改按钮-显示弹框 this.dialogTitle = "修改"; this.dialogFormVisible = true; this.dialogForm = { ...row }; }, async dialogConfirm() {//点击弹框确定按钮 let res = null; if (this.dialogTitle == "新增") { res = await addAdminAPI(this.dialogForm); } else { res = await modifyAdminAPI(this.dialogForm); } if (res.flag) { this.dialogFormVisible = false; } this.$message({ message: res.message, type: res.flag ? "success" : "error", }); this.fetchData(); }, async deleteCofirm(row) {//点击确定删除按钮 this.pageNum = 1; const res = await removeAdminAPI(row.id); this.$message({ message: res.message, type: res.flag ? "success" : "error", }); this.fetchData(); }, }, }; </script> <style lang="less" scoped> .page-box { margin-top: 20px; } </style>
06-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值