欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

el?autocomplete支持分頁上拉加載使用詳解

 更新時(shí)間:2022年11月22日 10:12:31   作者:日升_月落  
這篇文章主要為大家介紹了el?autocomplete支持分頁上拉加載使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

el-autocomplete使用

  • 效果圖

template

<template>
  <el-autocomplete
    :clearable="true"                                  //支持清空
    :title="searchStr"                                 // 鼠標(biāo)移上去提示文案
    :trigger-on-focus="true"                           // 聚焦時(shí)是否觸發(fā)下拉列表展示
    :fetch-suggestions="querySearchAsync"              // 篩選符合條件的數(shù)據(jù)
    :placeholder="placeholder"                         // 占位符提示信息
    v-scrollLoad="load"                                // 自定義上拉加載指令
    v-model="searchStr"                                // 搜索關(guān)鍵字
    popper-class="diy-autocomplete"                    // 下拉框自定義class控制樣式
    class="el-autocomplete-component"                  // 給當(dāng)前組件定義專屬類名
    size="small"                                       // 組件顯示尺寸
    ref="autocomplete"                                 // 用于后期獲取dom元素
    @select="handleSelect"                             // 選中時(shí)觸發(fā)事件
    @blur="handleBlur"                                 // 失去焦點(diǎn)時(shí)觸發(fā)
    @clear="handleClear"                               // 清空數(shù)據(jù)時(shí)觸發(fā)
  ></el-autocomplete>
</template>

實(shí)現(xiàn)需求分析

輸入框?yàn)榭諘r(shí)聚焦或失焦后又重新聚焦不會(huì)觸發(fā)請(qǐng)求數(shù)據(jù)接口

// blurTxt: 記錄上次失焦時(shí) 和 選中時(shí)的篩選字段
// blurArr: 記錄上次失焦時(shí) 和 選中時(shí)已經(jīng)查詢到的數(shù)據(jù)
async querySearchAsync(queryString, cb) {
      if (this.blurTxt === queryString || !queryString) {
        cb(this.blurArr)
        return
      }
    },

緩存上一次已查詢的數(shù)據(jù)&搜索條件:blurArr、blurTxt

    // 失焦事件
    handleBlur() {
      this.blurTxt = this.searchStr || ''
      this.blurArr = this.$refs['autocomplete'].$data.suggestions
    },
    // 過濾數(shù)據(jù)時(shí)及時(shí)更新篩選字段
    async querySearchAsync(queryString, cb) {
      this.blurTxt = searchVal
    },

滾動(dòng)加載指令(監(jiān)聽容器的scroll事件并進(jìn)行防抖處理)

  • 防抖函數(shù)
/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result
  const later = function() {
    // 據(jù)上一次觸發(fā)時(shí)間間隔
    const last = +new Date() - timestamp
    // 上次被包裝函數(shù)被調(diào)用時(shí)間間隔 last 小于設(shè)定時(shí)間間隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果設(shè)定為immediate===true,因?yàn)殚_始邊界已經(jīng)調(diào)用過了此處無需調(diào)用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }
  return function(...args) {
    context = this
    timestamp = +new Date()
    const callNow = immediate && !timeout
    // 如果延時(shí)不存在,重新設(shè)定延時(shí)
    if (!timeout) timeout = setTimeout(later, wait)
    if (callNow) {
      result = func.apply(context, args)
      context = args = null
    }
    return result
  }
}
  • 滾動(dòng)加載指令
  directives: {
    scrollLoad: {
      bind(el, binding, vnode) {
        let wrapDom = el.querySelector('.el-autocomplete-suggestion__wrap')
        let listDom = el.querySelector('.el-autocomplete-suggestion__wrap  .el-autocomplete-suggestion__list')
        // 滾動(dòng)事件做防抖處理
        wrapDom.addEventListener(
          'scroll',
          debounce(e => {
            let condition = wrapDom.offsetHeight + wrapDom.scrollTop + 50 - listDom.offsetHeight
            if (condition > 0 && !vnode.context.loading) {
              binding.value()
            }
          }, 300),
          false
        )
      }
    }
  }

分頁加載

  • 請(qǐng)求前展示加載圈
  • 加載至最后一頁時(shí)不再進(jìn)行請(qǐng)求并提示暫無更多數(shù)據(jù)
  • 關(guān)閉loading加載圈
  • 把數(shù)據(jù)追加至已展示的數(shù)據(jù)列表中

獲取數(shù)據(jù),并進(jìn)行格式化

第一種方式: 在組件上設(shè)置valueKey為你要展示的字段名稱,默認(rèn)值為value

<el-autocomplete valueKey="nickName"></el-autocomplete>

第二種方式:拿到數(shù)據(jù)后遍歷數(shù)據(jù)為每一項(xiàng)增添value屬性,值為自己組合想展示的方式

    // 獲取用戶列表
    async getList(queryString) {
      let result = await searchUserList({
        pageNum: this.pageNum,
        pageSize: this.pageSize,
        searchValue: decodeURI(queryString)
      })
      this.total = result.total
      // 調(diào)用 callback 返回建議列表的數(shù)據(jù)
      result.rows &&
        result.rows.forEach(element => {
          // 學(xué)生展示 姓名+班級(jí)
          if (element.classList[0] && element.roleId === 101) {
            element.value = element.nickName + '-' + element.classList[0].className
          } else {
            // 非學(xué)生或者學(xué)生沒有主班級(jí)展示 姓名+身份
            element.value = element.nickName + '-' + (element.roleName || '暫無角色I(xiàn)D')
          }
        })
      return result.rows
    },

第三種方式:在組件對(duì)應(yīng)的插槽slot中自定義展示內(nèi)容

<el-autocomplete > 
    <!--  輸入框小圖標(biāo)插槽  -->
    <i class="el-icon-edit el-input__icon" slot="suffix"> </i> 
    <!--  搜索列表每一項(xiàng)展示  -->
    <template slot-scope="{ item }"> 
        <div class="name">{{ item.nickName }} - {{item.className}}</div>
    </template> 
</el-autocomplete>

關(guān)閉加載圈

    // 關(guān)閉加載圈
    closeLoading() {
      loadingInstance && loadingInstance.close && loadingInstance.close()
      loadingInstance = null
    },

分頁加載事件

    // 滾動(dòng)加載
    async load() {
      this.closeLoading()
      // 加載到最后一頁停止加載
      if (this.pageNum * this.pageSize > this.total) {
        return
      }
      this.pageNum++
      loadingInstance = Loading.service({
        target: document.querySelector('.el-autocomplete-suggestion'),
        fullscreen: false,
        spinner: 'el-icon-loading',
        lock: true,
        text: '加載中...'
      })
      let results = await this.getList(this.searchStr)
      this.closeLoading()
      this.pageNum * this.pageSize >= this.total ? results.push({ value: '暫無更多數(shù)據(jù)' }) : ''
      // 將數(shù)據(jù)添加到下拉列表
      this.$refs['autocomplete'].$data.suggestions = this.$refs['autocomplete'].$data.suggestions.concat(results)
    },

清空輸入框,重置上次記錄的數(shù)據(jù)

    // 清空搜索項(xiàng)
    handleClear() {
      this.blurTxt = ''
      this.blurArr = []
      this.$refs['autocomplete'].$data.suggestions = []
    },

選中時(shí)記錄相關(guān)數(shù)據(jù)

    // 選中用戶跳轉(zhuǎn)至對(duì)應(yīng)的頁面
    handleSelect(item) {
      this.$refs['autocomplete'].$data.suggestions = this.blurArr = [item]
      this.blurTxt = this.searchStr || ''
      this.pageNum = 1
      this.total = 0
      ...
      //下拉選中的值
      // console.log(item)
    }

數(shù)據(jù)展示不穩(wěn)定問題

例如姓名模糊搜索過程中,也許我們會(huì)先輸入姓為第一個(gè)關(guān)鍵詞,接著在輸入第二個(gè)關(guān)鍵詞名字,只輸入姓的時(shí)候肯定要比姓名要查詢的數(shù)據(jù)多,當(dāng)在大量數(shù)據(jù)中查詢時(shí)會(huì)面臨著第二個(gè)請(qǐng)求(搜索條件:輸入姓名的)先返回?cái)?shù)據(jù),然后第一個(gè)請(qǐng)求(搜索條件:輸入姓的)才會(huì)返回?cái)?shù)據(jù)的情況,而此時(shí)篩選列表中展示的肯定是最后請(qǐng)求出來的結(jié)果(搜索框中展示的是完整姓名:張三,而展示列表中卻展示出了:張一、張二、張三...),此時(shí)的解決方案是相同接口取消上一次的接口。

  • 請(qǐng)求攔截中限制重復(fù)請(qǐng)求某個(gè)接口
import axios from 'axios'
let pending = []; //聲明一個(gè)數(shù)組用于存儲(chǔ)每個(gè)ajax請(qǐng)求的取消函數(shù)和ajax標(biāo)識(shí)
let cancelToken = axios.CancelToken;
let removePending = (ever) => {
    for (let p in pending) {
        if (pending[p].u === ever.url + '&' + ever.method) { //當(dāng)當(dāng)前請(qǐng)求在數(shù)組中存在時(shí)執(zhí)行函數(shù)體 
            pending[p].f(); //執(zhí)行取消操作
            pending.splice(p, 1); //把這條記錄從數(shù)組中移除
        }
    }
}
var errorFlag = false;
var erFlag = false;
// 創(chuàng)建axios實(shí)例
const service = axios.create({
  // axios中請(qǐng)求配置有baseURL選項(xiàng),表示請(qǐng)求URL公共部分
  baseURL: process.env.VUE_APP_BASE_API,
  // 超時(shí)
  timeout: 90000
})
// request攔截器
service.interceptors.request.use(
  config => {
     // 如果你是在老項(xiàng)目中開發(fā)就加一個(gè)限制,避免影響到原有的功能
    // if(config.url.indexOf('system/user/newsearch_list')!==-1){
      config && removePending(config); //在一個(gè)ajax發(fā)送前執(zhí)行一下取消操作
      config.cancelToken = new cancelToken((c) => {
          // 這里的ajax標(biāo)識(shí)我是用請(qǐng)求地址&請(qǐng)求方式拼接的字符串,當(dāng)然你可以選擇其他的一些方式
          pending.push({
              u: config.url + '&' + config.method,
              f: c
          });
      });
    // }
    return config
  },
  error => {
    console.log(error)
    Promise.reject(error)
  }
)
  • 相應(yīng)攔截中對(duì)取消請(qǐng)求這個(gè)操作單獨(dú)處理,不展示錯(cuò)誤消息提示彈窗
// 響應(yīng)攔截器
service.interceptors.response.use(res => {
    const code = res.data.code
    if (code === 401) {
     ...         
    } else if (code !== 200) {
      if(!errorFlag){
        ...      
        return Promise.reject(res.data || {})
      }      
    } else {
      return res.data
    }
  },
  error => {
    // 單獨(dú)處理取消請(qǐng)求導(dǎo)致的錯(cuò)誤
    if(error.__CANCEL__){
      return false
    }
    if(!erFlag){
      Message({
        message: error.message,
        type: 'error',
        duration: 3 * 1000
      })
      return Promise.reject(error)
    }    
  }
)

完整的 scss 文件

.el-autocomplete-component {
  max-width: 230px;
  vertical-align: text-bottom;
  height: 50px;
  padding-top: 1px;
  cursor: pointer;
  /deep/ .el-input__inner {
    cursor: pointer;
    padding-left: 5px;
    padding-right: 8px;
    background: transparent;
    border: none;
    color: #fff;
    font-size: 14px;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
    &::placeholder {
      color: #bfbfbf;
      font-size: 12px;
    }
  }
}
.diy-autocomplete {
  .name {
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    height: 34px;
  }
}

完整的 js 文件

<script>
import { searchUserList } from '@/api/system/user'  // 請(qǐng)求用戶列表的接口
import { debounce } from '@/utils/index' // 防抖函數(shù)
import { Loading } from 'element-ui' // 下拉加載時(shí)的過渡loading
let loadingInstance = null
export default {
  data() {
    return {
      showAutocomplete: false,
      searchStr: '', //輸入關(guān)鍵詞的值
      pageNum: 1,
      pageSize: 20,
      total: 0, //篩選數(shù)據(jù)的總值
      placeholder: '請(qǐng)輸入用戶名/手機(jī)號(hào)/QQ',
      blurTxt: '', //記錄失焦時(shí)搜索框中的文字,避免聚焦時(shí)重新篩選數(shù)據(jù)
      blurArr: [] //記錄失焦時(shí)已經(jīng)搜索出來的列表
    }
  },
  methods: {
    // 失焦事件
    handleBlur() {
      this.blurTxt = this.searchStr || ''
      this.blurArr = this.$refs['autocomplete'].$data.suggestions
    },
    // 清空搜索項(xiàng)
    handleClear() {
      this.blurTxt = ''
      this.blurArr = []
      this.$refs['autocomplete'].$data.suggestions = []
    },
    // 關(guān)閉加載圈
    closeLoading() {
      loadingInstance && loadingInstance.close && loadingInstance.close()
      loadingInstance = null
    },
    // 條件查詢
    async querySearchAsync(queryString, cb) {
      this.$refs['autocomplete'].$data.suggestions = []
      if (this.blurTxt === queryString || !queryString) {
        cb(this.blurArr)
        return
      }
      this.handleClear()
      let searchVal = queryString
      // 后面所拼接的班級(jí)名稱和角色不參與篩選字段中
      queryString.indexOf('-') !== -1 ? (searchVal = queryString.split('-')[0]) : ''
      this.pageNum = 1
      this.blurTxt = searchVal
      let results = await this.getList(searchVal)
      cb(results || [])
    },
    // 獲取用戶列表
    async getList(queryString) {
      let result = await searchUserList({
        pageNum: this.pageNum,
        pageSize: this.pageSize,
        searchValue: decodeURI(queryString)
      })
      this.total = result.total
      // 調(diào)用 callback 返回建議列表的數(shù)據(jù)
      result.rows &&
        result.rows.forEach(element => {
          // 學(xué)生展示 姓名+班級(jí)
          if (element.classList[0] && element.roleId === 101) {
            element.value = element.nickName + '-' + element.classList[0].className
          } else {
            // 非學(xué)生或者學(xué)生沒有主班級(jí)展示 姓名+身份
            element.value = element.nickName + '-' + (element.roleName || '暫無角色I(xiàn)D')
          }
        })
      return result.rows
    },
    // 滾動(dòng)加載
    async load() {
      this.closeLoading()
      // 加載到最后一頁停止加載
      if (this.pageNum * this.pageSize > this.total) {
        return
      }
      this.pageNum++
      loadingInstance = Loading.service({
        target: document.querySelector('.el-autocomplete-suggestion'),
        fullscreen: false,
        spinner: 'el-icon-loading',
        lock: true,
        text: '加載中...'
      })
      let results = await this.getList(this.searchStr)
      this.closeLoading()
      this.pageNum * this.pageSize >= this.total ? results.push({ value: '暫無更多數(shù)據(jù)' }) : ''
      // 將數(shù)據(jù)添加到下拉列表
      this.$refs['autocomplete'].$data.suggestions = this.$refs['autocomplete'].$data.suggestions.concat(results)
    },
    // 選中用戶跳轉(zhuǎn)至對(duì)應(yīng)的頁面
    handleSelect(item) {
      this.$refs['autocomplete'].$data.suggestions = this.blurArr = [item]
      this.blurTxt = this.searchStr || ''
      this.pageNum = 1
      this.total = 0
      let routeData = {}
      if (item.roleId === 101) {
        // 學(xué)生
        routeData = this.$router.resolve({ path: '/personInf/student', query: { userId: item.userId } })
      } else {
        // 非學(xué)生
        routeData = this.$router.resolve({
          path: '/userManagement/user',
          query: { userInfo: item.nickName ,roleId: item.roleId||''}
        })
      }
      window.open(routeData.href, '_blank')
      //下拉選中的值
      // console.log(item)
    }
  },
  directives: {
    scrollLoad: {
      bind(el, binding, vnode) {
        let wrapDom = el.querySelector('.el-autocomplete-suggestion__wrap')
        let listDom = el.querySelector('.el-autocomplete-suggestion__wrap  .el-autocomplete-suggestion__list')
        // 滾動(dòng)事件做防抖處理
        wrapDom.addEventListener(
          'scroll',
          debounce(e => {
            let condition = wrapDom.offsetHeight + wrapDom.scrollTop + 50 - listDom.offsetHeight
            if (condition > 0 && !vnode.context.loading) {
              binding.value()
            }
          }, 300),
          false
        )
      }
    }
  }
}
</script>

以上就是el autocomplete支持分頁上拉加載使用詳解的詳細(xì)內(nèi)容,更多關(guān)于el autocomplete分頁上拉加載的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue實(shí)現(xiàn)商城上貨組件簡(jiǎn)易版

    vue實(shí)現(xiàn)商城上貨組件簡(jiǎn)易版

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)商城上貨組件簡(jiǎn)易版,50行js代碼實(shí)現(xiàn)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • vue.js內(nèi)置組件之keep-alive組件使用

    vue.js內(nèi)置組件之keep-alive組件使用

    keep-alive是Vue.js的一個(gè)內(nèi)置組件。這篇文章主要介紹了vue.js內(nèi)置組件之keep-alive組件使用,需要的朋友可以參考下
    2018-07-07
  • vue.js實(shí)現(xiàn)圖書管理功能

    vue.js實(shí)現(xiàn)圖書管理功能

    這篇文章主要為大家詳細(xì)介紹了vue.js實(shí)現(xiàn)圖書管理功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • vue+quasar使用遞歸實(shí)現(xiàn)動(dòng)態(tài)多級(jí)菜單

    vue+quasar使用遞歸實(shí)現(xiàn)動(dòng)態(tài)多級(jí)菜單

    這篇文章主要為大家詳細(xì)介紹了vue+quasar使用遞歸實(shí)現(xiàn)動(dòng)態(tài)多級(jí)菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • Vue 列表頁帶參數(shù)進(jìn)詳情頁的操作(router-link)

    Vue 列表頁帶參數(shù)進(jìn)詳情頁的操作(router-link)

    這篇文章主要介紹了Vue 列表頁帶參數(shù)進(jìn)詳情頁的操作(router-link),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • vue中三元表達(dá)式方法例子

    vue中三元表達(dá)式方法例子

    這篇文章主要給大家介紹了關(guān)于vue中三元表達(dá)式的相關(guān)資料,眾所周知三元表達(dá)式用來根據(jù)參數(shù)的不同執(zhí)行不同的代碼是很方便的,需要的朋友可以參考下
    2023-09-09
  • Vue實(shí)戰(zhàn)之掌握自定義指令

    Vue實(shí)戰(zhàn)之掌握自定義指令

    作為使用Vue的開發(fā)者,我們對(duì)Vue指令一定不陌生,諸如v-model、v-on、v-for、v-if等,同時(shí)Vue也為開發(fā)者提供了自定義指令的api,熟練的使用自定義指令可以極大的提高了我們編寫代碼的效率,讓我們可以節(jié)省時(shí)間開心的摸魚
    2022-11-11
  • vue watch如何深度監(jiān)聽數(shù)組每一項(xiàng)的變化

    vue watch如何深度監(jiān)聽數(shù)組每一項(xiàng)的變化

    這篇文章主要介紹了vue watch如何深度監(jiān)聽數(shù)組每一項(xiàng)的變化問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • vue實(shí)現(xiàn)動(dòng)態(tài)綁定行內(nèi)樣式style的backgroundImage

    vue實(shí)現(xiàn)動(dòng)態(tài)綁定行內(nèi)樣式style的backgroundImage

    這篇文章主要介紹了vue實(shí)現(xiàn)動(dòng)態(tài)綁定行內(nèi)樣式style的backgroundImage方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • vue的rules驗(yàn)證部分可以部分又失效的原因及解決方案

    vue的rules驗(yàn)證部分可以部分又失效的原因及解決方案

    vue的rules驗(yàn)證失效,部分可以部分又失效,很多百度都有,但是我這里遇到了一個(gè)特別的,那就是prop沒有寫全,導(dǎo)致驗(yàn)證某一個(gè)失效,接下來就跟小編一起來看看這個(gè)失效的原因和解決方案吧
    2023-11-11

最新評(píng)論