ElementPlus Select V2 虛擬列表選擇器

2021-09-07 16:36 更新

Select V2 虛擬列表選擇器

這個組件目前在測試當中,如果在使用中發(fā)現(xiàn)任何漏洞和問題,請在 Github 中提交 issue 以便我們進行處理

背景

在數(shù)據(jù)量爆發(fā)的今天,很多時候一個選擇器可能從服務器加載非常多的數(shù)據(jù),然而瀏覽器在一次性把這些數(shù)據(jù)渲染到頁面上的時候會出現(xiàn)卡頓甚至是崩潰的情況,所以虛擬化技術應運而生,為了更好的用戶體驗和更好的使用體驗,我們決定添加這個組件。

基礎用法

適用廣泛的基礎選擇器


<template>
  <el-select-v2
    v-model="value"
    :options="options"
    placeholder="請選擇"
    style="width: 240px;"
  />
</template>

<script>
  const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
  export default {
    data() {
      return {
        options: Array.from({ length: 1000 }).map((_, idx) => ({
          value: `選項${idx + 1}`,
          label: `${initials[idx % 10]}${idx}`,
        })),
        value: '',
      }
    },
  }
</script>

多選

最基礎的多選選擇器

<template>
  <el-select-v2
    v-model="value"
    :options="options"
    placeholder="請選擇"
    style="width: 240px;"
    multiple
  />
</template>

<script>
  const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
  export default {
    data() {
      return {
        options: Array.from({ length: 1000 }).map((_, idx) => ({
          value: `選項${idx + 1}`,
          label: `${initials[idx % 10]}${idx}`,
        })),
        value: [],
      }
    },
  }
</script>

隱藏多余標簽的多選

<template>
  <el-select-v2
    v-model="value"
    :options="options"
    placeholder="請選擇"
    style="width: 240px;"
    multiple
    collapse-tags
  />
</template>

<script>
  const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
  export default {
    data() {
      return {
        options: Array.from({ length: 1000 }).map((_, idx) => ({
          value: `選項${idx + 1}`,
          label: `${initials[idx % 10]}${idx}`,
        })),
        value: [],
      }
    },
  }
</script>

可篩選的多選

當選項過多時,可通過匹配篩選

<template>
  <el-select-v2
    v-model="value"
    filterable
    :options="options"
    placeholder="請選擇"
    style="width: 240px;"
    multiple
  />
</template>

<script>
  const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
  export default {
    data() {
      return {
        options: Array.from({ length: 1000 }).map((_, idx) => ({
          value: `選項${idx + 1}`,
          label: `${initials[idx % 10]}${idx}`,
        })),
        value: [],
      }
    },
  }
</script>

禁用狀態(tài)

您可以選擇禁用 Select 或者 Select 的 Option

<template>
  <el-select-v2
    v-model="value"
    filterable
    :options="options"
    placeholder="請選擇"
    style="width: 240px; margin-right: 16px; vertical-align: middle;"
    multiple
  />
  <el-select-v2
    disabled
    v-model="value"
    filterable
    :options="options"
    placeholder="請選擇"
    style="width: 240px; vertical-align: middle;"
    multiple
  />
</template>

<script>
  const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
  export default {
    data() {
      return {
        options: Array.from({ length: 1000 }).map((_, idx) => ({
          value: `選項${idx + 1}`,
          label: `${initials[idx % 10]}${idx}`,
          disabled: idx % 10 === 0,
        })),
        value: [],
      }
    },
  }
</script>

選項分組

我們可以為選項分組,只需要滿足例子里的這個 pattern

<template>
  <el-select-v2
    v-model="value"
    filterable
    :options="options"
    placeholder="請選擇"
    style="width: 240px;"
    multiple
  />
</template>

<script>
  const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
  export default {
    data() {
      return {
        options: Array.from({ length: 10 }).map((_, idx) => {
          const label = idx + 1
          return {
            value: `組 ${label}`,
            label: `組 ${label}`,
            options: Array.from({ length: 10 }).map((_, idx) => ({
              value: `選項${idx + 1 + 10 * label}`,
              label: `${initials[idx % 10]}${idx + 1 + 10 * label}`,
            })),
          }
        }),
        value: [],
      }
    },
  }
</script>

自定義渲染模板

我們也可以通過自己自定義模板來渲染自己想要的內(nèi)容。

<template>
  <el-select-v2
    v-model="value"
    filterable
    :options="options"
    placeholder="請選擇"
    style="width: 240px;"
    multiple
  >
    <template #default="{item}">
      <span style="margin-right: 8px;">{{ item.label }}</span>
      <span style="color: var(--el-text-color-secondary); font-size: 13px">
        {{ item.value }}
      </span>
    </template>
  </el-select-v2>
</template>

<script>
  const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
  export default {
    data() {
      return {
        options: Array.from({ length: 1000 }).map((_, idx) => ({
          value: `選項${idx + 1}`,
          label: `${initials[idx % 10]}${idx}`,
        })),
        value: [],
      }
    },
  }
</script>

一鍵清除

一鍵刪除所有的選項(也可適用于單選)

<template>
  <el-select-v2
    v-model="value1"
    :options="options"
    placeholder="請選擇"
    style="width: 240px; margin-right: 16px; vertical-align: middle;"
    multiple
    clearable
  />
  <el-select-v2
    v-model="value2"
    :options="options"
    placeholder="請選擇"
    style="width: 240px; vertical-align: middle;"
    clearable
  />
</template>

<script>
  const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
  export default {
    data() {
      return {
        options: Array.from({ length: 1000 }).map((_, idx) => ({
          value: `選項${idx + 1}`,
          label: `${initials[idx % 10]}${idx}`,
        })),
        value1: [],
        value2: '',
      }
    },
  }
</script>

創(chuàng)建臨時選項

可以創(chuàng)建并選中選項中不存在的條目

使用allow-create屬性即可通過在輸入框中輸入文字來創(chuàng)建新的條目。注意此時filterable必須為真。

<template>
  <el-select-v2
    v-model="value1"
    :options="options"
    placeholder="請選擇"
    style="width: 240px; margin-right: 16px; vertical-align: middle;"
    allow-create
    filterable
    multiple
    clearable
  />
  <el-select-v2
    v-model="value2"
    :options="options"
    placeholder="請選擇"
    style="width: 240px; vertical-align: middle;"
    allow-create
    filterable
    clearable
  />
</template>

<script>
  const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
  export default {
    data() {
      return {
        options: Array.from({ length: 1000 }).map((_, idx) => ({
          value: `選項${idx + 1}`,
          label: `${initials[idx % 10]}${idx}`,
        })),
        value1: [],
        value2: '',
      }
    },
  }
</script>

遠程搜索

從服務器搜索數(shù)據(jù),輸入關鍵字進行查找

為了啟用遠程搜索,需要將filterable和remote設置為true,同時傳入一個remote-method。remote-method為一個Function,它會在輸入值發(fā)生變化時調(diào)用,參數(shù)為當前輸入值。

<template>
  <el-select-v2
    v-model="value"
    style="width: 240px"
    multiple
    size="medium"
    filterable
    remote
    :remote-method="remoteMethod"
    clearable
    :options="options"
    :loading="loading"
    placeholder="請輸入關鍵詞"
  />
</template>

<script>
  export default {
    created() {
      this.list = this.states.map((item) => {
        return { value: `value:${item}`, label: `label:${item}` }
      })
    },
    methods: {
      remoteMethod(query) {
        if (query !== '') {
          this.loading = true
          setTimeout(() => {
            this.loading = false
            this.options = this.list.filter((item) => {
              return item.label.toLowerCase().indexOf(query.toLowerCase()) > -1
            })
          }, 200)
        } else {
          this.options = []
        }
      },
    },
    data() {
      return {
        list: [],
        loading: false,
        states: [
          'Alabama',
          'Alaska',
          'Arizona',
          'Arkansas',
          'California',
          'Colorado',
          'Connecticut',
          'Delaware',
          'Florida',
          'Georgia',
          'Hawaii',
          'Idaho',
          'Illinois',
          'Indiana',
          'Iowa',
          'Kansas',
          'Kentucky',
          'Louisiana',
          'Maine',
          'Maryland',
          'Massachusetts',
          'Michigan',
          'Minnesota',
          'Mississippi',
          'Missouri',
          'Montana',
          'Nebraska',
          'Nevada',
          'New Hampshire',
          'New Jersey',
          'New Mexico',
          'New York',
          'North Carolina',
          'North Dakota',
          'Ohio',
          'Oklahoma',
          'Oregon',
          'Pennsylvania',
          'Rhode Island',
          'South Carolina',
          'South Dakota',
          'Tennessee',
          'Texas',
          'Utah',
          'Vermont',
          'Virginia',
          'Washington',
          'West Virginia',
          'Wisconsin',
          'Wyoming',
        ],
        options: [],
        value: [],
      }
    },
  }
</script>

SelectV2 Attributes

參數(shù)說明類型可選值默認值
model-value / v-model綁定值string / number / boolean / object
multiple是否多選booleanfalse
disabled是否禁用booleanfalse
value-key作為 value 唯一標識的鍵名,綁定值為對象類型時必填stringvalue
size輸入框尺寸stringmedium/small/mini
clearable是否可以清空選項booleanfalse
collapse-tags多選時是否將選中值按文字的形式展示booleanfalse
multiple-limit多選時用戶最多可以選擇的項目數(shù),為 0 則不限制number0
nameselect input 的 name 屬性string
autocompleteselect input 的 autocomplete 屬性stringoff
placeholder占位符string請選擇
filterable是否可搜索booleanfalse
filter-method自定義搜索方法function
remote是否為遠程搜索booleanfalse
remote-method遠程搜索方法function
allow-create是否允許用戶創(chuàng)建新條目,需配合 filterable 使用booleanfalse
no-data-text選項為空時顯示的文字,也可以使用#empty設置string無數(shù)據(jù)
popper-classSelect 下拉框的類名string
popper-append-to-body是否將彈出框插入至 body 元素。在彈出框的定位出現(xiàn)問題時,可將該屬性設置為 falseboolean-false
popper-options用戶定制化 popper 的行為, 更多請查看文檔popper.jsobject--
automatic-dropdown對于不可搜索的 Select,是否在輸入框獲得焦點后自動彈出選項菜單boolean-false
clear-icon自定義清空圖標的類名stringel-icon-circle-close
height面板的高度,每項的高度為 34pxnumber-170

SelectV2 Events

事件名稱說明回調(diào)參數(shù)
change選中值發(fā)生變化時觸發(fā)目前的選中值
visible-change下拉框出現(xiàn)/隱藏時觸發(fā)出現(xiàn)則為 true,隱藏則為 false
remove-tag多選模式下移除 tag 時觸發(fā)移除的 tag 值
clear可清空的單選模式下用戶點擊清空按鈕時觸發(fā)
blur當 input 失去焦點時觸發(fā)(event: Event)
focus當 input 獲得焦點時觸發(fā)(event: Event)

SelectV2 Slots

name說明
defaultOption 模板
empty無選項時的列表


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號