feat:多端base-select以及grid-select文档 (#3872)

This commit is contained in:
liukun 2025-12-04 16:29:47 +08:00 committed by GitHub
parent 7fee0474f7
commit dba45e3e61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
56 changed files with 4095 additions and 16 deletions

View File

@ -1,12 +1,15 @@
export const apis = import.meta.glob('../../../sites/demos/apis/*.js', { eager: false })
export const getPath = (path) => {
if (path.startsWith('grid-')) {
if (path === 'grid-select') {
return 'grid-select'
} else if (path.startsWith('grid-')) {
return 'grid'
} else if (path.startsWith('chart-')) {
return 'chart'
} else {
return path
}
return path
}
export const getApisConfig = async (component, mode) => {

View File

@ -1,5 +1,5 @@
export default {
mode: ['pc'],
mode: ['pc', 'mobile-first'],
apis: [
{
name: 'grid-select',
@ -13,7 +13,7 @@ export default {
'zh-CN': '是否启用一键清除的功能',
'en-US': 'Whether to display the one click clear button, only applicable to radio selection'
},
mode: ['pc'],
mode: ['pc', 'mobile-first'],
pcDemo: 'basic-usage'
},
{
@ -24,7 +24,7 @@ export default {
'zh-CN': '是否可搜索',
'en-US': 'Is it searchable'
},
mode: ['pc'],
mode: ['pc', 'mobile-first'],
pcDemo: 'remote'
},
{
@ -35,7 +35,7 @@ export default {
'zh-CN': '自定义过滤方法',
'en-US': 'Custom filtering method'
},
mode: ['pc'],
mode: ['pc', 'mobile-first'],
pcDemo: 'remote'
},
{
@ -47,7 +47,7 @@ export default {
'zh-CN': '下拉表格时,内置表格组件的配置,用法同 Grid 组件。',
'en-US': ''
},
mode: ['pc'],
mode: ['pc', 'mobile-first'],
pcDemo: 'basic-usage'
},
{
@ -69,7 +69,7 @@ export default {
'zh-CN': '是否允许选择多个选项',
'en-US': 'Allow multiple options to be selected'
},
mode: ['pc'],
mode: ['pc', 'mobile-first'],
pcDemo: 'remote'
},
{
@ -81,7 +81,7 @@ export default {
'zh-CN': '单选配置项',
'en-US': 'Radio config'
},
mode: ['pc'],
mode: ['pc', 'mobile-first'],
pcDemo: 'config'
},
{
@ -92,7 +92,7 @@ export default {
'zh-CN': '是否为远程搜索',
'en-US': 'Is it a remote search'
},
mode: ['pc'],
mode: ['pc', 'mobile-first'],
pcDemo: 'remote'
},
{
@ -103,7 +103,7 @@ export default {
'zh-CN': '远程搜索的方法',
'en-US': 'Remote search methods'
},
mode: ['pc'],
mode: ['pc', 'mobile-first'],
pcDemo: 'remote'
},
{
@ -115,7 +115,7 @@ export default {
'en-US':
'When selecting multiple searchable options, do you still keep the current search keywords after selecting one option'
},
mode: ['pc'],
mode: ['pc', 'mobile-first'],
pcDemo: 'remote'
},
{
@ -127,7 +127,7 @@ export default {
'zh-CN': '多选配置项',
'en-US': 'Select config'
},
mode: ['pc'],
mode: ['pc', 'mobile-first'],
pcDemo: 'config'
},
{
@ -138,7 +138,7 @@ export default {
'zh-CN': '显示值字段',
'en-US': 'Show Value Fields'
},
mode: ['pc'],
mode: ['pc', 'mobile-first'],
pcDemo: 'basic-usage'
},
{
@ -149,7 +149,7 @@ export default {
'zh-CN': '绑定值字段',
'en-US': 'Bind Value Field'
},
mode: ['pc'],
mode: ['pc', 'mobile-first'],
pcDemo: 'basic-usage'
}
]

View File

@ -0,0 +1,43 @@
<template>
<div>
<div style="margin: 16px 0">全选后显示多个 tag</div>
<tiny-base-select v-model="value" multiple all-text="全部小吃">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<div style="margin: 16px 0">全选后显示自定义的全部 Tag</div>
<tiny-base-select v-model="value1" multiple all-text="全部小吃" show-all-text-tag>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
value: [],
value1: [],
options: [
{ value: '选项 1', label: '黄金糕' },
{ value: '选项 2', label: '双皮奶' },
{ value: '选项 3', label: '蚵仔煎' },
{ value: '选项 4', label: '龙须面' },
{ value: '选项 6', label: '螺蛳粉' }
]
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,51 @@
<template>
<div>
<div>场景 1allow-create + filterable点击创建条目</div>
<br />
<tiny-base-select v-model="value" allow-create filterable>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
<br />
<div>场景 2allow-create + filterable + default-first-optionEnter 键创建条目</div>
<br />
<tiny-base-select v-model="value" allow-create filterable default-first-option>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption, TinyInput, TinyButton, TinyDialogBox, TinyModal } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption,
TinyInput,
TinyButton,
TinyDialogBox
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: '',
boxVisibility: false,
optionLabel: '',
optionValue: ''
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,60 @@
<template>
<div>
<p>场景 1默认不可搜索时获取焦点不下拉</p>
<tiny-button @click="handleFocus1"> 点击获取焦点 </tiny-button>
<tiny-base-select v-model="value" ref="selectOnlyFocusRef">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<p>场景 2设置不可搜索时获取焦点并自动下拉</p>
<tiny-button @click="handleFocus2"> 点击获取焦点 </tiny-button>
<tiny-base-select v-model="value" ref="selectAutoDropRef" automatic-dropdown>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption, TinyButton } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption,
TinyButton
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: ''
}
},
methods: {
handleFocus1() {
this.$refs.selectOnlyFocusRef.focus()
},
handleFocus2() {
this.$refs.selectAutoDropRef.focus()
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
padding: 16px 0;
}
.tiny-button {
margin-right: 10px;
}
</style>

View File

@ -0,0 +1,47 @@
<template>
<div>
<div>选中的值为 {{ value }}</div>
<br />
<div>场景 1标签式</div>
<br />
<tiny-base-select v-model="value">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" :icon="item.icon">
</tiny-option>
</tiny-base-select>
<br />
<br />
<div>场景 2配置式</div>
<br />
<tiny-base-select v-model="value" :options="options"> </tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
import { iconFile } from '@opentiny/vue-icon'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ value: '选项 1', label: '北京', icon: iconFile() },
{ value: '选项 2', label: '上海', icon: iconFile() },
{ value: '选项 3', label: '天津', icon: iconFile() },
{ value: '选项 4', label: '重庆', icon: iconFile() },
{ value: '选项 5', label: '深圳', icon: iconFile() }
],
value: ''
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,44 @@
<template>
<div>
<tiny-base-select v-model="value" value-key="val">
<tiny-option v-for="(item, index) in options" :key="index" :label="item.text" :value="item.obj"> </tiny-option>
</tiny-base-select>
<p class="value">
{{ value }}
</p>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ obj: { val: '选项 1', id: 1 }, text: '北京' },
{ obj: { val: '选项 2', id: 2 }, text: '上海' },
{ obj: { val: '选项 3', id: 3 }, text: '天津' },
{ obj: { val: '选项 4', id: 4 }, text: '重庆' },
{ obj: { val: '选项 5', id: 5 }, text: '深圳' }
],
value: { val: '选项 3', id: 3 }
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
padding: 16px 0;
}
</style>

View File

@ -0,0 +1,55 @@
<template>
<div>
<tiny-base-select
v-model="value"
clearable
:options="options"
:cache-op="cacheOp"
@change="cacheChange"
></tiny-base-select>
<p class="cache-value">
{{ cacheValue }}
</p>
</div>
</template>
<script>
import { TinyBaseSelect } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect
},
data() {
return {
cacheOp: {
key: 'test'
},
cacheValue: '',
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: '选项 3'
}
},
methods: {
cacheChange() {
this.cacheValue = window.localStorage.getItem(`tiny_memorize_${this.cacheOp.key}`)
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
}
</style>

View File

@ -0,0 +1,52 @@
<template>
<div>
<p>
场景 1单选val 找不到匹配值val ,<span class="val">{{ val }}</span>
</p>
<tiny-base-select v-model="val" :clear-no-match-value="true">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<p>
场景 2多选multiVal 找不到匹配值multiVal <span class="multi-val">{{ multiVal }}</span>
</p>
<tiny-base-select v-model="multiVal" :clear-no-match-value="true" multiple>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
val: '11',
multiVal: ['选项 2', '11']
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
padding: 16px 0;
}
</style>

View File

@ -0,0 +1,34 @@
<template>
<tiny-base-select v-model="value" clearable>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: '选项 3'
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,49 @@
<template>
<div>
<br />
<div>场景 1collapse-tags 折叠</div>
<br />
<tiny-base-select v-model="value1" :show-proportion="true" multiple collapse-tags>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
<br />
<div>场景 2hover-expand 折叠</div>
<br />
<tiny-base-select v-model="value2" multiple hover-expand>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
<br />
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆超长超长超长超长超长超长超长超长超长' },
{ value: '选项 5', label: '深圳' }
],
value1: ['选项 1', '选项 2'],
value2: ['选项 1', '选项 2', '选项 3', '选项 4']
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,55 @@
<template>
<div>
<p>场景 1多选复制单个标签</p>
<tiny-base-select ref="selectTagSelectable" v-model="value1" multiple tag-selectable>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<p>场景 2多选一键复制所有标签</p>
<tiny-base-select ref="selectCopyable" v-model="value2" multiple copyable>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<p>场景 3多选设置复制文本分隔符</p>
<tiny-base-select ref="selectCopyable" v-model="value2" multiple copyable text-split="/">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<p>复制到此处</p>
<tiny-input v-model="copyValue" class="copy-value" type="text"></tiny-input>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption, TinyInput } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption,
TinyInput
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value1: ['选项 1'],
value2: ['选项 1', '选项 2'],
copyValue: ''
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
padding: 16px 0;
}
</style>

View File

@ -0,0 +1,158 @@
<template>
<div>
<p>场景 1单选无需配置可复制</p>
<tiny-base-select v-model="value1" :options="options1"> </tiny-base-select>
<p>场景 2单选可搜索配置 allow-copy 可复制</p>
<tiny-base-select
ref="selectRef"
v-model="value1"
:options="options1"
filterable
:filter-method="filter"
allow-copy
>
</tiny-base-select>
<p>场景 3单选远程搜索配置 allow-copy 可复制</p>
<tiny-base-select
v-model="value2"
filterable
remote
placeholder="请输入关键词"
:remote-method="remoteMethod"
:loading="loading"
loading-text="Loading..."
allow-copy
>
<tiny-option v-for="item in options2" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<p class="font-style">粘贴至此处</p>
<tiny-input v-model="inputVal" type="text" class="custom"></tiny-input>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption, TinyInput } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption,
TinyInput
},
data() {
return {
options1: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
options2: [],
value1: '选项 1',
value2: 'Alabama',
inputVal: '',
loading: false,
list: []
}
},
mounted() {
const 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'
]
this.list = states.map((item) => {
return { value: item, label: item }
})
},
methods: {
filter(value) {
const select = this.$refs.selectRef
if (value) {
select.state.cachedOptions.forEach((item) => {
item.state.visible = item.label.includes(value)
})
} else {
select.state.cachedOptions.forEach((item) => {
item.state.visible = true
})
}
},
remoteMethod(query) {
if (query !== undefined) {
this.loading = true
setTimeout(() => {
this.loading = false
this.options2 = this.list.filter((item) => {
return item.label.toLowerCase().includes(query.toLowerCase())
})
}, 200)
} else {
this.options2 = []
}
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
padding: 16px 0;
}
</style>

View File

@ -0,0 +1,107 @@
<template>
<div>
<br />
<div>场景 1下拉禁用</div>
<br />
<tiny-base-select v-model="value1" disabled autocomplete>
<tiny-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
<br />
<div>场景 2多选 + 下拉某项禁用</div>
<br />
<tiny-base-select v-model="value2" multiple>
<tiny-option
v-for="item in options2"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
>
</tiny-option>
</tiny-base-select>
<br />
<br />
<div>场景 3单选 + 下拉某项禁用</div>
<br />
<tiny-base-select v-model="value3">
<tiny-option
v-for="item in options2"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
>
</tiny-option>
</tiny-base-select>
<br />
<br />
<div>场景 4多选 + 禁用项默认选中</div>
<br />
<tiny-base-select v-model="value4" multiple>
<tiny-option
v-for="item in options2"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
>
</tiny-option>
</tiny-base-select>
<br />
<br />
<div>场景 5多选 hover-expand 模式下禁用</div>
<br />
<tiny-base-select
v-model="value5"
placeholder="请选择"
multiple
disabled
hover-expand
disabled-tooltip-content="我是自定义内容"
>
<tiny-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options1: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆重庆超长超长超长超长超长超长超长超长超长' },
{ value: '选项 5', label: '深圳' }
],
options2: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海', disabled: true },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆', disabled: true },
{ value: '选项 5', label: '深圳' }
],
value1: '',
value2: ['选项 2'],
value3: '',
value4: ['选项 2', '选项 3'],
value5: ['选项 1', '选项 2', '选项 3', '选项 4', '选项 5']
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,112 @@
<template>
<div>
<div>单选</div>
<br />
<tiny-base-select
v-model="value1"
clearable
@change="change"
@blur="blur"
@focus="focus"
@visible-change="visibleChange"
@clear="clear"
@dropdown-click="dropdownClick"
>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
<br />
<div>多选</div>
<br />
<tiny-base-select
v-model="value2"
multiple
clearable
@change="change"
@blur="blur"
@focus="focus"
@visible-change="visibleChange"
@remove-tag="removeTag"
@dropdown-click="dropdownClick"
>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption, TinyModal } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value1: '',
value2: []
}
},
methods: {
change() {
TinyModal.message({
message: '触发 change 事件',
status: 'info'
})
},
clear() {
TinyModal.message({
message: '触发 clear 事件',
status: 'info'
})
},
focus() {
TinyModal.message({
message: '触发 focus 事件'
})
},
blur() {
TinyModal.message({
message: '触发 blur 事件',
status: 'info'
})
},
removeTag() {
TinyModal.message({
message: '触发 remove-tag 事件',
status: 'info'
})
},
visibleChange() {
TinyModal.message({
message: '触发 visible-change 事件',
status: 'info'
})
},
dropdownClick() {
TinyModal.message({
message: '触发 dropdown-click 事件',
status: 'info'
})
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
}
</style>

View File

@ -0,0 +1,83 @@
<template>
<div>
<p>场景 1组件默认过滤</p>
<tiny-base-select v-model="value1" ref="selectRef" filterable no-match-text="No Match">
<tiny-option
v-for="item in options"
v-show="!item.filter"
:key="item.value"
:label="item.label"
:value="item.value"
>
</tiny-option>
</tiny-base-select>
<p>场景 2自定义过滤</p>
<tiny-base-select
v-model="value2"
ref="customFilterRef"
filterable
:filter-method="customFilterMethod"
clearable
no-match-text="No Match"
>
<tiny-option
v-for="item in options"
v-show="!item.filter"
:key="item.value"
:label="item.label"
:value="item.value"
>
</tiny-option>
</tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value1: '',
value2: ''
}
},
methods: {
customFilterMethod(searchValue) {
const customFilterRef = this.$refs.customFilterRef
if (searchValue) {
customFilterRef.state.cachedOptions.forEach((item) => {
item.state.visible = item.label.includes(searchValue)
})
} else {
customFilterRef.state.cachedOptions.forEach((item) => {
item.state.visible = true
})
}
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
padding: 16px 0;
}
</style>

View File

@ -0,0 +1,57 @@
<template>
<div>
<div>场景 1过滤器模式 (默认)</div>
<br />
<tiny-base-select
v-model="value"
label="地区名称"
shape="filter"
:drop-style="{ width: '200px', 'min-width': '200px' }"
>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
<br />
<br />
<div>场景 2过滤器模式 (透明)</div>
<br />
<tiny-base-select
v-model="value"
label="地区名称"
shape="filter"
:drop-style="{ width: '200px', 'min-width': '200px' }"
blank
>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: ''
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,34 @@
<template>
<tiny-base-select v-model="value" :hide-drop="true">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: ''
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,49 @@
<template>
<div>
<p>场景 1默认下拉弹框宽度由内容撑开</p>
<tiny-base-select v-model="value">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<p>场景 2下拉弹框宽度与输入框一致</p>
<tiny-base-select v-model="value" is-drop-inherit-width>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{
value: '选项 1',
label: '北京北京北京北京北京北京北京北京北京北京北京北京北京北京北京北京北京'
},
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: ''
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
padding: 16px 0;
}
</style>

View File

@ -0,0 +1,90 @@
<template>
<div>
<div class="demo1">
<div>场景 1默认 focus() 后仅聚焦不下拉</div>
<br />
<tiny-button @click="handleFocus1"> 点击获取焦点 </tiny-button>
<tiny-button @click="handleBlur1"> 点击失去焦点 </tiny-button>
<br />
<tiny-base-select v-model="value" ref="drop1">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</div>
<br />
<div class="demo2">
<div>场景 2配置 filterablefocus() 后聚焦并自动下拉</div>
<br />
<tiny-button @click="handleFocus2"> 点击获取焦点 </tiny-button>
<tiny-button @click="handleBlur2"> 点击失去焦点 </tiny-button>
<br />
<tiny-base-select v-model="value" ref="drop2" filterable>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</div>
<br />
<div class="demo3">
<div>场景 3配置 automaticDropdownfocus() 后聚焦并自动下拉</div>
<br />
<tiny-button @click="handleFocus3"> 点击获取焦点 </tiny-button>
<tiny-button @click="handleBlur3"> 点击失去焦点 </tiny-button>
<br />
<tiny-base-select v-model="value" ref="drop3" automatic-dropdown>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</div>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption, TinyButton } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption,
TinyButton
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: ''
}
},
methods: {
handleFocus1() {
this.$refs.drop1.focus()
},
handleBlur1() {
this.$refs.drop1.blur()
},
handleFocus2() {
this.$refs.drop2.focus()
},
handleBlur2() {
this.$refs.drop2.blur()
},
handleFocus3() {
this.$refs.drop3.focus()
},
handleBlur3() {
this.$refs.drop3.blur()
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
.tiny-button {
max-width: unset;
margin-bottom: 10px;
}
</style>

View File

@ -0,0 +1,42 @@
<template>
<div>
<p>场景 1配置式配置映射字段</p>
<tiny-base-select v-model="value1" multiple :options="options" value-field="val" text-field="text">
</tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect
},
data() {
return {
value1: ['选项 1', '选项 2'],
options: [
{ val: '选项 1', text: '北京' },
{ val: '选项 2', text: '上海' },
{ val: '选项 3', text: '天津' },
{ val: '选项 4', text: '重庆' },
{ val: '选项 5', text: '深圳' },
{ val: '选项 6', text: '南京' },
{ val: '选项 7', text: '成都' }
]
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
padding: 16px 0;
}
</style>

View File

@ -0,0 +1,66 @@
<template>
<div>
<tiny-base-select v-model="value">
<tiny-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
@click.native="clickItem(item.value)"
:highlight-class="item._highlightClass"
></tiny-option>
</tiny-base-select>
<p class="cache-value">
{{ cacheValue }}
</p>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
import { Memorize } from '@opentiny/utils'
const MemorizeInstance = new Memorize({ key: 'test456' })
const options = MemorizeInstance.assemble([
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
])
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options,
value: '选项 3',
cacheValue: []
}
},
methods: {
clickItem(value) {
MemorizeInstance.updateByKey(value)
this.cacheValue = window.localStorage.getItem('tiny_memorize_test456')
}
},
mounted() {
window.localStorage.setItem('tiny_memorize_test456', '')
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
padding: 16px 0;
}
</style>

View File

@ -0,0 +1,156 @@
<template>
<div class="demo-box">
<tiny-button @click="displayOnly = !displayOnly">display-only/{{ displayOnly }}</tiny-button>
<br />
<br />
<p>边框为表单范围</p>
<br />
<br />
<tiny-form class="custom-form" :inline="inline" label-position="top" :display-only="displayOnly">
<tiny-form-item label="label 垂直布局">
<div>
<tiny-base-select v-model="formData.select1" multiple hover-expand>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
</tiny-option>
</tiny-base-select>
<br />
<br />
<tiny-base-select v-model="formData.select1" multiple hover-expand>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
</tiny-option>
</tiny-base-select>
</div>
</tiny-form-item>
<p>&nbsp;</p>
</tiny-form>
<br />
<br />
<tiny-form class="custom-form" :inline="inline" :display-only="displayOnly">
<tiny-form-item label="form 超出隐藏">
<tiny-base-select v-model="formData.select1" multiple hover-expand>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</tiny-form-item>
</tiny-form>
<br />
<tiny-form class="custom-form visible-form" :inline="inline" :display-only="displayOnly">
<tiny-form-item label="自定义-超出显示">
<tiny-base-select v-model="formData.select1" multiple hover-expand>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</tiny-form-item>
</tiny-form>
<br />
<tiny-form class="custom-form" :inline="inline" :display-only="displayOnly">
<tiny-form-item label="默认尺寸">
<tiny-base-select v-model="formData.select1" multiple hover-expand>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</tiny-form-item>
<p>&nbsp;</p>
</tiny-form>
<br />
<br />
<tiny-form class="custom-form" size="mini" :inline="inline" :display-only="displayOnly">
<tiny-form-item label="mini" size="mini">
<tiny-base-select v-model="formData.select1" size="mini" multiple hover-expand>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</tiny-form-item>
<p>&nbsp;</p>
</tiny-form>
<br />
<br />
<tiny-form class="custom-form" size="small" :inline="inline" :display-only="displayOnly">
<tiny-form-item label="small" size="small">
<tiny-base-select v-model="formData.select1" size="small" multiple hover-expand>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</tiny-form-item>
<p>&nbsp;</p>
</tiny-form>
<br />
<br />
<tiny-form class="custom-form" size="medium" :inline="inline" :display-only="displayOnly">
<tiny-form-item label="medium" size="medium">
<tiny-base-select v-model="formData.select1" size="medium" multiple hover-expand>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</tiny-form-item>
<p>&nbsp;</p>
</tiny-form>
</div>
</template>
<script>
import { TinyForm, TinyFormItem, TinyOption, TinyButton, TinyBaseSelect } from '@opentiny/vue'
export default {
components: {
TinyForm,
TinyButton,
TinyFormItem,
TinyBaseSelect,
TinyOption
},
data() {
return {
displayOnly: true,
top: false,
inline: false,
size: '',
options: [
{
value: '选项 1',
label: '北京'
},
{
value: '选项 2',
label: '上海'
},
{
value: '选项 3',
label: '天津'
},
{
value: '选项 4',
label: '重庆'
},
{
value: '选项 5',
label: '深圳'
},
{
value: '选项 6',
label: '杭州'
},
{
value: '选项 7',
label: '宇宙无敌老面小馒头'
}
],
formData: {
select1: ['选项 1', '选项 2', '选项 3', '选项 4', '选项 5', '选项 6', '选项 7']
}
}
}
}
</script>
<style lang="less" scoped>
.demo-box {
width: 350px;
.custom-form {
border: 1px solid #fdf4f4;
padding: 10px;
}
.visible-form {
overflow: visible;
}
}
</style>

View File

@ -0,0 +1,98 @@
<template>
<div>
<br />
<div>场景 1多选</div>
<br />
<tiny-base-select v-model="value1" multiple searchable>
<tiny-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
<br />
<br />
<div>场景 2必选</div>
<br />
<tiny-base-select v-model="value2" multiple>
<tiny-option
v-for="item in options2"
:key="item.value"
:label="item.label"
:value="item.value"
:required="item.required"
>
</tiny-option>
</tiny-base-select>
<br />
<br />
<br />
<div>场景 3配置式必选</div>
<br />
<tiny-base-select v-model="value3" multiple :options="options2"> </tiny-base-select>
<br />
<br />
<br />
<div>场景 4多选个数限制</div>
<br />
<tiny-base-select v-model="value4" multiple :multiple-limit="2" show-limit-text>
<tiny-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
<br />
<br />
<div>场景 5自定义图标 + 自定义样式</div>
<br />
<tiny-base-select
v-model="value4"
multiple
:dropdown-icon="iconPopup"
:drop-style="{ width: '200px', 'min-width': '200px' }"
>
<tiny-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
import { iconPopup } from '@opentiny/vue-icon'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options1: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' },
{ value: '选项 6', label: '南京' },
{ value: '选项 7', label: '成都' }
],
options2: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳', required: true },
{ value: '选项 6', label: '南京' },
{ value: '选项 7', label: '成都' }
],
value1: ['选项 1', '选项 2'],
value2: ['选项 1', '选项 2'],
value3: ['选项 1', '选项 2'],
value4: [],
iconPopup: iconPopup()
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,34 @@
<template>
<tiny-base-select v-model="value" placeholder="自定义 placeholder" name="inputName" autocomplete>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: ''
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,40 @@
<template>
<div>
<p>场景 1默认</p>
<tiny-base-select v-model="value">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<p>场景 2自定义空数据文本</p>
<tiny-base-select v-model="value" no-data-text="暂无数据">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [],
value: ''
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
padding: 16px 0;
}
</style>

View File

@ -0,0 +1,55 @@
<template>
<div>
<p>单选</p>
<tiny-base-select v-model="value1" :options="options" optimization @change="onChange"></tiny-base-select>
<p>多选</p>
<tiny-base-select
v-model="value2"
optimization
multiple
collapse-tags
:multiple-limit="5"
:options="options"
@change="onChange"
></tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect, TinyModal } from '@opentiny/vue'
const buildOptions = () =>
Array.from({ length: 100000 }).map((item, i) => JSON.parse(`{"value":"选项 ${i}","label":"北京 ${i}"}`))
export default {
components: {
TinyBaseSelect
},
data() {
return {
value1: '',
value2: [],
options: buildOptions()
}
},
methods: {
onChange(value) {
TinyModal.message({
message: JSON.stringify(value),
status: 'info'
})
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
padding: 16px 0;
}
</style>

View File

@ -0,0 +1,105 @@
<template>
<div>
<div>场景 1分组 + 多选 + 面板可搜索</div>
<br />
<tiny-base-select v-model="value2" multiple filterable :searchable="true">
<tiny-option-group v-for="group in options3" :key="group.label" :label="group.label" :disabled="!!group.disabled">
<tiny-option
v-for="item in group.options"
:key="item.value"
:label="item.label"
:value="item.value"
></tiny-option>
</tiny-option-group>
</tiny-base-select>
<br />
<br />
<div>场景 2单选分组</div>
<br />
<tiny-base-select v-model="value1" filterable>
<tiny-option-group v-for="group in options3" :key="group.label" :label="group.label" :disabled="!!group.disabled">
<tiny-option
v-for="item in group.options"
:key="item.value"
:label="item.label"
:value="item.value"
></tiny-option>
</tiny-option-group>
</tiny-base-select>
<br />
<br />
<div>场景 3分组 + 多选</div>
<br />
<tiny-base-select v-model="value2" multiple>
<tiny-option-group v-for="group in options3" :key="group.label" :label="group.label" :disabled="!!group.disabled">
<tiny-option
v-for="item in group.options"
:key="item.value"
:label="item.label"
:value="item.value"
></tiny-option>
</tiny-option-group>
</tiny-base-select>
<br />
<br />
<div>场景 4分组 + 多选 + 可搜索</div>
<br />
<tiny-base-select v-model="value2" filterable multiple>
<tiny-option-group v-for="group in options3" :key="group.label" :label="group.label" :disabled="!!group.disabled">
<tiny-option
v-for="item in group.options"
:key="item.value"
:label="item.label"
:value="item.value"
></tiny-option>
</tiny-option-group>
</tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption, TinyOptionGroup } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption,
TinyOptionGroup
},
data() {
return {
value1: [],
value2: '',
options3: [
{
label: '热门城市',
disabled: true,
options: [
{ value: 'Shanghai', label: '上海' },
{ value: 'Beijing', label: '北京' }
]
},
{
label: '城市名',
options: [
{ value: 'Chengdu', label: '成都' },
{ value: 'Shenzhen', label: '深圳' },
{ value: 'Guangzhou', label: '广州' },
{ value: 'Dalian', label: '大连' },
{ value: 'Chongqing', label: '重庆' },
{ value: 'Xianggang', label: '香港' },
{ value: 'Aomen', label: '澳门' },
{ value: 'Wulumuqi', label: '乌鲁木齐' }
]
}
]
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,40 @@
<template>
<tiny-base-select v-model="value" popper-class="drop" :popper-append-to-body="false" placement="top">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: ''
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>
<style>
.drop {
background-color: var(--tv-color-bg-3);
}
</style>

View File

@ -0,0 +1,286 @@
<template>
<div>
<div>场景 1远程搜索 (单选)</div>
<br />
<tiny-base-select
v-model="value1"
filterable
remote
:remote-method="remoteMethod1"
:loading="loading1"
loading-text="Loading..."
>
<tiny-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
<br />
<div>场景 2远程搜索多选 + 保留搜索关键字</div>
<br />
<tiny-base-select
v-model="value2"
filterable
multiple
remote
reserve-keyword
placeholder="请输入关键词"
:remote-method="remoteMethod2"
:loading="loading2"
loading-text="Loading..."
>
<tiny-option v-for="item in options2" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
<br />
<div>场景 3获焦时触发远程搜索</div>
<br />
<tiny-base-select
v-model="value3"
filterable
remote
:remote-config="{ autoSearch: true }"
:remote-method="remoteMethod3"
:loading="loading3"
loading-text="Loading..."
>
<tiny-option v-for="item in options3" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
<br />
<div>场景 4失焦清空查询数据显示下拉图标</div>
<br />
<tiny-base-select
v-model="value4"
multiple
filterable
remote
:remote-config="{ clearData: true, showIcon: true }"
reserve-keyword
:remote-method="remoteMethod4"
>
<tiny-option v-for="item in options4" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
<br />
<div>场景 5聚焦时触发搜索失焦清空查询数据显示下拉图标</div>
<br />
<tiny-base-select
v-model="value5"
multiple
filterable
remote
:remote-config="{ autoSearch: true, clearData: true, showIcon: true }"
reserve-keyword
:remote-method="remoteMethod5"
:loading="loading5"
loading-text="Loading..."
>
<tiny-option v-for="item in options5" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
<br />
<div>场景 6远程搜索配置 trim 属性去除绑定值空格</div>
<br />
<tiny-button @click="trim = !trim">trim {{ trim }}</tiny-button>
<tiny-button @click="changeVal">改变成有空格的值</tiny-button>
<tiny-button @click="resetVal">重置绑定值</tiny-button>
<br />
<br />
<tiny-base-select
v-model="value6"
filterable
remote
:remote-config="{ autoSearch: true, clearData: true, showIcon: true }"
reserve-keyword
:remote-method="remoteMethod6"
:loading="loading5"
loading-text="Loading..."
:trim="trim"
>
<tiny-option v-for="item in options6" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption, TinyButton } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption,
TinyButton
},
data() {
return {
loading1: false,
loading2: false,
loading3: false,
loading4: false,
loading5: false,
value1: '',
value2: [],
value3: '',
value4: [],
value5: [],
value6: '',
options1: [],
options2: [],
options3: [],
options4: [],
options5: [],
options6: [],
list: [],
trim: false
}
},
mounted() {
const 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'
]
this.list = states.map((item) => {
return { value: item, label: item }
})
},
methods: {
remoteMethod1(query) {
if (query !== undefined) {
this.loading1 = true
setTimeout(() => {
this.loading1 = false
this.options1 = this.list.filter((item) => {
return item.label.toLowerCase().includes(query.toLowerCase())
})
}, 200)
} else {
this.options1 = []
}
},
remoteMethod2(query) {
if (query !== undefined) {
this.loading2 = true
setTimeout(() => {
this.loading2 = false
this.options2 = this.list.filter((item) => {
return item.label.toLowerCase().includes(query.toLowerCase())
})
}, 200)
} else {
this.options2 = []
}
},
remoteMethod3(query) {
if (query !== undefined) {
this.loading3 = true
setTimeout(() => {
this.loading3 = false
this.options3 = this.list.filter((item) => {
return item.label.toLowerCase().includes(query.toLowerCase())
})
}, 300)
} else {
this.options3 = []
}
},
remoteMethod4(query) {
if (query !== undefined) {
this.loading4 = true
setTimeout(() => {
this.loading4 = false
this.options4 = this.list.filter((item) => {
return item.label.toLowerCase().includes(query.toLowerCase())
})
}, 200)
} else {
this.options4 = []
}
},
remoteMethod5(query) {
if (query !== undefined) {
this.loading5 = true
setTimeout(() => {
this.loading5 = false
this.options5 = this.list.filter((item) => {
return item.label.toLowerCase().includes(query.toLowerCase())
})
}, 200)
} else {
this.options5 = []
}
},
remoteMethod6(query) {
if (query !== undefined) {
setTimeout(() => {
this.options6 = this.list.filter((item) => {
return item.label.toLowerCase().includes(query.toLowerCase())
})
}, 200)
} else {
this.options6 = []
}
},
changeVal() {
this.value6 = ' Wyoming'
},
resetVal() {
this.value6 = ''
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,34 @@
<template>
<tiny-base-select v-model="value" multiple :show-alloption="false">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: ''
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,34 @@
<template>
<tiny-base-select v-model="value" multiple show-overflow-tooltip style="width: 200px">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: ''
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,48 @@
<template>
<div>
<p>medium</p>
<tiny-base-select v-model="value2" size="medium" multiple :options="options"></tiny-base-select>
<p>默认</p>
<tiny-base-select v-model="value1" multiple :options="options"></tiny-base-select>
<p>small</p>
<tiny-base-select v-model="value3" size="small" multiple :options="options"> </tiny-base-select>
<p>mini</p>
<tiny-base-select v-model="value4" size="mini" multiple :options="options"> </tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value1: ['选项 1', '选项 2'],
value2: ['选项 1', '选项 2'],
value3: ['选项 1', '选项 2'],
value4: ['选项 1', '选项 2']
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
padding: 16px 0;
}
</style>

View File

@ -0,0 +1,95 @@
<template>
<div>
<p>场景 1带标签和提示信息</p>
<br />
<tiny-base-select v-model="value1" popper-class="slot-default">
<template v-for="item in options1">
<tiny-tooltip v-if="item.tip" :content="item.tip" placement="right" effect="light" :key="item.value">
<tiny-option :label="item.label" :value="item.value">
<span class="left">{{ item.label }}</span>
<tiny-tag v-if="item.tag" type="danger" effect="light" size="small">{{ item.tag }}</tiny-tag>
</tiny-option>
</tiny-tooltip>
<tiny-option v-if="!item.tip" :key="item.value" :label="item.label" :value="item.value">
<span class="left">{{ item.label }}</span>
<tiny-tag v-if="item.tag" type="danger" effect="light" size="small">{{ item.tag }}</tiny-tag>
</tiny-option>
</template>
</tiny-base-select>
<br /><br />
<p>场景 2选项双行</p>
<br />
<tiny-base-select v-model="value2" popper-class="double-row">
<tiny-option v-for="item in options2" :key="item.value" :label="item.label" :value="item.value">
<div>
<p>
{{ item.label }}
</p>
<p>{{ item.desc }}</p>
</div>
</tiny-option>
</tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption, TinyTag, TinyTooltip } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption,
TinyTag,
TinyTooltip
},
data() {
return {
options1: [
{ value: '选项 1', label: '北京', tag: 'New', tip: '自定义提示' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
options2: [
{ value: '选项 1', label: '子网 1192.168.0.1/24', desc: '可用 IP 数 250' },
{ value: '选项 2', label: '子网 2192.168.0.1/24', desc: '可用 IP 数 250' },
{ value: '选项 3', label: '子网 3192.168.0.1/24', desc: '可用 IP 数 250' },
{ value: '选项 4', label: '子网 4192.168.0.1/24', desc: '可用 IP 数 250' },
{ value: '选项 5', label: '子网 5192.168.0.1/24', desc: '可用 IP 数 250' }
],
value1: '选项 1',
value2: '选项 1'
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
.tiny-option {
.left {
margin-right: 8px;
}
p {
height: 18px;
line-height: 18px;
margin: 6px;
}
}
</style>
<style lang="less">
.double-row {
&.tiny-select-dropdown .tiny-select-dropdown__wrap {
max-height: 224px;
.tiny-option {
height: 54px;
}
}
}
</style>

View File

@ -0,0 +1,41 @@
<template>
<tiny-base-select v-model="value">
<template #empty>
<div class="custom-empty">
<p>APIG 网关异常</p>
<tiny-button size="small">重新加载</tiny-button>
</div>
</template>
</tiny-base-select>
</template>
<script>
import { TinyBaseSelect, TinyButton } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyButton
},
data() {
return {
value: ''
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
.custom-empty {
text-align: center;
padding: 20px;
.tiny-button {
margin-top: 8px;
}
}
</style>

View File

@ -0,0 +1,45 @@
<template>
<tiny-base-select v-model="value">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
<template #footer>
<div class="select-footer">
<tiny-button type="success" round> 底部插槽 </tiny-button>
</div>
</template>
</tiny-base-select>
</template>
<script>
import { TinyBaseSelect, TinyOption, TinyButton } from '@opentiny/vue'
export default {
components: {
TinyButton,
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: ''
}
}
}
</script>
<style scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
.select-footer {
text-align: center;
background-color: rgb(207, 243, 232, 0.3);
padding: 8px;
}
</style>

View File

@ -0,0 +1,85 @@
<template>
<div class="demo-select-slot-label">
<tiny-base-select v-model="value1" placeholder="请选择" multiple>
<template #label="{ item }">
<img class="label-user-head" :src="imgSrc(item.value)" alt="" />
<span class="label-desc">{{ item.label }}</span>
</template>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<br />
<br />
<tiny-base-select v-model="value2" :options="options" placeholder="请选择" multiple>
<template #label="{ item }">
<img class="label-user-head" :src="imgSrc(item.value)" alt="" />
<span class="label-desc">{{ item.label }}</span>
</template>
</tiny-base-select>
</div>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{
value: '选项 1',
label: '北京超长超长超长超长超长超长超长超长超长超长超长超长超长超长超长超长超长超长超长超长超长',
src: `${import.meta.env.VITE_APP_BUILD_BASE_URL}static/images/user-head.png`
},
{
value: '选项 2',
label: '上海',
src: `${import.meta.env.VITE_APP_BUILD_BASE_URL}static/images/1.jpg`
},
{
value: '选项 3',
label: '天津',
src: `${import.meta.env.VITE_APP_BUILD_BASE_URL}static/images/2.jpg`
},
{
value: '选项 4',
label: '重庆',
src: `${import.meta.env.VITE_APP_BUILD_BASE_URL}static/images/3.jpg`
},
{
value: '选项 5',
label: '深圳',
src: `${import.meta.env.VITE_APP_BUILD_BASE_URL}static/images/4.jpg`
}
],
value1: ['选项 1', '选项 2'],
value2: ['选项 3']
}
},
methods: {
imgSrc(value) {
const option = this.options.find((option) => option.value === value)
return option && option.src
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
.demo-select-slot-label.label-user-head,
.tiny-tooltip .label-user-head {
display: inline-block;
height: 18px;
width: 18px;
margin-right: 4px;
vertical-align: middle;
}
</style>

View File

@ -0,0 +1,155 @@
<template>
<p>场景 1下拉树单选</p>
<tiny-base-select v-model="value">
<template #panel="{ methods: { updateSelectedData, hidePanel } }">
<tiny-tree
:data="treeData"
:expand-on-click-node="false"
:icon-trigger-click-node="false"
:default-expand-all="true"
@node-click="
(data) => {
updateSelectedData({
...data,
currentLabel: data.label,
value: data.id,
state: {
currentLabel: data.label
}
})
hidePanel()
}
"
></tiny-tree>
</template>
</tiny-base-select>
<p>场景 2下拉树多选</p>
<tiny-base-select v-model="value2" multiple>
<template #panel="{ methods: { updateSelectedData } }">
<tiny-tree
:data="treeData"
:expand-on-click-node="false"
:icon-trigger-click-node="false"
:default-expand-all="true"
:show-checkbox="true"
@check="
(data, { checkedNodes }) => {
updateSelectedData(
checkedNodes.map((node) => {
return {
...node,
currentLabel: node.label,
value: node.id,
isTree: true
}
})
)
}
"
></tiny-tree>
</template>
</tiny-base-select>
<p>场景 3下拉树可搜索</p>
<tiny-base-select v-model="value3" filterable clearable :filter-method="filterMethod">
<template #panel="{ methods: { updateSelectedData, hidePanel } }">
<tiny-tree
ref="treeRef"
:data="treeData"
:expand-on-click-node="false"
:icon-trigger-click-node="false"
:default-expand-all="true"
:filter-node-method="filter"
@node-click="
(data) => {
updateSelectedData({
...data,
currentLabel: data.label,
value: data.id,
state: {
currentLabel: data.label
}
})
hidePanel()
}
"
></tiny-tree>
</template>
</tiny-base-select>
</template>
<script>
import { TinyBaseSelect, TinyTree } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyTree
},
data() {
return {
value: '',
value2: '',
value3: '',
treeData: [
{
id: 1,
label: '一级 1',
children: [
{
id: 4,
label: '二级 1-1',
children: [
{
id: 9,
label: '三级 1-1-1'
},
{
id: 10,
label: '三级 1-1-2'
}
]
}
]
},
{
id: 2,
label: '一级 2',
children: [
{
id: 5,
label: '二级 2-1'
},
{
id: 6,
label: '二级 2-2'
}
]
}
]
}
},
methods: {
filterMethod(value) {
this.$refs.treeRef.filter(value)
},
filter(value, data) {
if (!value) return true
return data.label.includes(value)
}
}
}
</script>
<style scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
p {
font-size: 14px;
line-height: 1.5;
padding: 16px 0;
}
</style>

View File

@ -0,0 +1,39 @@
<template>
<tiny-base-select v-model="value" multiple collapse-tags>
<template #prefix>
<tiny-icon-location></tiny-icon-location>
</template>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
import { iconLocation } from '@opentiny/vue-icon'
export default {
components: {
TinyBaseSelect,
TinyOption,
TinyIconLocation: iconLocation()
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: ''
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,41 @@
<template>
<tiny-base-select v-model="value">
<template #reference>
<tiny-icon-setting class="custom-reference"></tiny-icon-setting>
</template>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
import { iconSetting } from '@opentiny/vue-icon'
export default {
components: {
TinyBaseSelect,
TinyOption,
TinyIconSetting: iconSetting()
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: ''
}
}
}
</script>
<style scoped>
.custom-reference {
font-size: 24px;
fill: #8b949e;
cursor: pointer;
}
</style>

View File

@ -0,0 +1,36 @@
<template>
<tiny-base-select v-model="value" multiple tag-type="success">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</template>
<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' },
{ value: '选项 6', label: '南京' },
{ value: '选项 7', label: '成都' }
],
value: ['选项 1', '选项 2']
}
}
}
</script>
<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</style>

View File

@ -0,0 +1,7 @@
---
title: BaseSelect 基础选择器
---
# BaseSelect 基础选择器
BaseSelect 基础选择器是 Select 组件的基础版本,用法和 Select 一样但是不包含下拉树和下拉表格功能。BaseSelect 组件的包体积更小,如果你不需要下拉树和下拉表格功能,推荐使用 BaseSelect 组件,而不是 Select 组件。

View File

@ -0,0 +1,7 @@
---
title: BaseSelect
---
# BaseSelect
BaseSelect is a UI component that displays and selects data from a drop-down list box.

View File

@ -0,0 +1,590 @@
export default {
column: '2',
owner: '',
show: true,
cloud: true,
demos: [
{
demoId: 'basic-usage',
name: {
'zh-CN': '基本用法',
'en-US': 'Basic Usage'
},
desc: {
'zh-CN':
'<p>通过 <code>v-model</code> 设置被选中的 <code>tiny-option</code> 的 <code>value</code> 属性值。</p>\n',
'en-US':
'<p>Set the <code>value</code> attribute value of the selected <code>tiny-option</code> by <code>v-model</code>.</p>\n'
},
codeFiles: ['basic-usage.vue']
},
{
demoId: 'multiple',
name: {
'zh-CN': '多选',
'en-US': 'Multiple'
},
desc: {
'zh-CN': `
通过 <code>multiple</code> <code>v-model</code> Tag <br>
通过 <code>multiple-limit</code> 0 <br>
通过 <code>show-limit-text</code> 0 <br>
多选时通过给 option 标签配置 <code>required</code> options <code>required</code> <br>
通过 <code>dropdown-icon</code> <code>drop-style</code> <br>
`,
'en-US': `
Use the <code>multiple</code> attribute to enable the multi-selection function. In this case, the value of <code>v-model</code> is an array of selected values. By default, the selected value is displayed as a tag (Tag component).<br>
The <code>multiple-limit</code> attribute is used to limit the maximum number of users that can be selected. The default value is 0.
The <code>show-limit-text</code> attribute is used to limit the maximum number of users that can be selected. The default value is 0, which is not limited.<br>
When multiple options are selected, you can set <code>required</code> for the option tag or add the <code>required</code> attribute to the options configuration item to set mandatory options.<br>
You can use the <code>dropdown-icon</code> attribute to customize the drop-down icon, and the <code>drop-style</code> attribute to customize the style of the drop-down options.<br>
`
},
codeFiles: ['multiple.vue']
},
{
demoId: 'collapse-tags',
name: {
'zh-CN': '折叠标签',
'en-US': 'Collapse tags'
},
desc: {
'zh-CN':
'<p>通过 <code>collapse-tags</code> 属性设置选中多个选项时,多个标签缩略展示。设置 <code>show-proportion</code> 可展示当前选中条数和总条数占比,默认值为 <code>false</code> 。设置 <code>hover-expand</code> 为 <code>true</code> ,默认折叠标签,<code>hover</code> 时展示所有标签。标签内容超长时超出省略,<code>hover</code> 标签时展示 <code>tooltip</code> 。</p>\n',
'en-US':
'<p>When multiple options are selected through the <code>collapse-tags</code> attribute settings, multiple tags are displayed in a thumbnail. Set <code>show-proportion</code> to display the current number of selected items and the proportion of total items, with a default value of <code>false</code> . By setting <code>hover-expand</code> to <code>true</code> , the tags are collapsed by default, and all tags are displayed when hovering. If the content of the tag is too long, it should be omitted. When hovering the tag, a <code>tooltip</code> should be displayed</p>'
},
codeFiles: ['collapse-tags.vue']
},
{
demoId: 'multiple-mix',
name: {
'zh-CN': '仅显示',
'en-US': 'Display only'
},
desc: {
'zh-CN':
'<p>Form 表单内 Select 组件不同尺寸设置 <code>hover-expand</code> 和 <code>display-only</code> 属性的综合应用。</p>\n',
'en-US':
'<p>Comprehensive application of the <code>hover-expand</code> and <code>display-only</code> attributes of the Select component in the form. </p>\n'
},
codeFiles: ['multiple-mix.vue']
},
{
demoId: 'tag-type',
name: {
'zh-CN': '标签类型',
'en-US': 'Tag type'
},
desc: {
'zh-CN':
'<p>通过 <code>tag-type</code> 属性设置标签类型,同 Tag 组件的 type 属性。可选值success / info / warning / danger。</p>\n',
'en-US':
'<p>Set the label type through the <code>tag-type</code> attribute, which is the same as the type attribute of the Tag component. Optional values: success/info/warning/danger.</p>\n'
},
codeFiles: ['tag-type.vue']
},
{
demoId: 'size',
name: {
'zh-CN': '尺寸',
'en-US': 'Size'
},
desc: {
'zh-CN': '<p>通过 <code>size</code> 属性设置输入框尺寸可选值medium / small / mini。</p>',
'en-US':
'<p>Set the input box size through the <code>size</code> attribute, with optional values of medium / small / mini.</p>'
},
codeFiles: ['size.vue']
},
{
demoId: 'disabled',
name: {
'zh-CN': '禁用',
'en-US': 'Disabled'
},
desc: {
'zh-CN': '<p>通过 <code>disabled</code> 属性设置下拉或者下拉项的禁用状态。</p>\n',
'en-US':
'<p>Set the disabled status of the dropdown or dropdown item through the <code>disabled</code> attribute. </p>\n'
},
codeFiles: ['disabled.vue']
},
{
demoId: 'clearable',
name: {
'zh-CN': '可清除',
'en-US': 'Clearable'
},
desc: {
'zh-CN': '<p>通过 <code>clearable</code> 属性启用一键清除选中值的功能。仅适用于单选。</p>\n',
'en-US':
'<p>Enable the function of clearing selected values with one click through the<code>clearable</code> attribute. Only applicable for single selection.</p>\n'
},
codeFiles: ['clearable.vue']
},
{
demoId: 'filter-method',
name: {
'zh-CN': '可搜索',
'en-US': 'Filterable'
},
desc: {
'zh-CN':
'<p>通过 <code>filterable</code> 属性启用搜索功能。<code>filter-method</code> 自定义过滤方法。 <code>no-match-text</code> 属性自定义与搜索条件无匹配项时显示的文字。</p>\n',
'en-US':
'<p>Enable search functionality through the <code>filterable</code> attribute <code>filter-method</code> customize the filtering method <code>no-match-text</code> the text displayed when there is no match between attribute customization and search criteria.</p>\n'
},
codeFiles: ['filter-method.vue']
},
{
demoId: 'remote-method',
name: {
'zh-CN': '远程搜索',
'en-US': 'Remote search'
},
desc: {
'zh-CN':
'<p>通过 <code>filterable</code> 和 <code>remote</code> 和 <code>remote-method</code> 这三个属性同时使用设置远程搜索。通过 <code>reserve-keyword</code> 属性设置多选可搜索时,可以在选中一个选项后保留当前的搜索关键词。</p>\n<p>通过 <code>trim</code> 属性去除双向数据绑定值空格。</p>',
'en-US':
'<p>Set remote search through the use of three attributes:<code>filterable</code>,<code>remote</code>, and <code>remote-method</code>. When setting multiple searchable options through the <code>reserve-keyword</code> attribute, the current search keyword can be retained after selecting an option.</p>\n<p> Removes spaces from bidirectional data binding values through the <code>trim</code> attribute. </p>'
},
codeFiles: ['remote-method.vue']
},
{
demoId: 'allow-create',
name: {
'zh-CN': '创建条目',
'en-US': 'Create Entry'
},
desc: {
'zh-CN':
'<p>通过 <code>allow-create</code> 和 <code>filterable</code> 属性,设置当搜索字段不在已有选项中时,可创建为新的条目。结合 <code>default-first-option</code> 属性,可以按 Enter 键选中第一个匹配项。</p>\n<p>设置 <code>top-create</code> 属性后Select 下拉框中会显示新增按钮,点击按钮会抛出一个 <code>top-create-click</code> 事件,可以在事件中自定义一些行为。</p>',
'en-US':
'<p>By using the <code>allow-create</code> and <code>filterable</code> attributes, the search field can be created as a new entry when it is not in an existing option. By combining the <code>default-first-option</code> attribute, you can press the Enter key to select the first matching option.</p>\n'
},
codeFiles: ['allow-create.vue']
},
{
demoId: 'map-field',
name: {
'zh-CN': '映射字段',
'en-US': 'Map Fields'
},
desc: {
'zh-CN': '通过 <code>text-field</code> 设置显示文本字段,<code>value-field</code>设置绑定值字段。',
'en-US':
'<p>Set the display text field by <code>text-field</code>, and set the binding value field by <code>value-field</code>. </p>\n'
},
codeFiles: ['map-field.vue']
},
{
demoId: 'popup-style-position',
name: {
'zh-CN': '弹框样式与定位',
'en-US': 'Bullet Box Style and Positioning'
},
desc: {
'zh-CN':
'<p>通过 <code>popper-class</code> 属性设置下拉弹框的类名,可自定义样式。<code>placement</code>设置弹出位置。<code>popper-append-to-body</code> 设置是否将弹框 dom 元素插入至 body 元素,默认为 true。</p>\n',
'en-US':
'<p>You can customize the style by setting the class name of the dropdown pop-up box through the <code>popper-class</code> attribute <code>placement</code> set the pop-up position <code>popper-append-to-body</code> set whether to insert the pop-up dom element into the body element, default to true. </p>\n'
},
codeFiles: ['popup-style-position.vue']
},
{
demoId: 'show-alloption',
name: {
'zh-CN': '不展示全选',
'en-US': 'Hide Select All'
},
desc: {
'zh-CN': '<p>通过 <code>show-alloption</code> 属性设置多选时不展示 <code>全选</code> 选项,默认展示。</p>\n',
'en-US':
'<p>By setting the <code>show-allocation</code> attribute, do not display the <code>select all</code> option when multiple selections are made, and display by default.</p>\n'
},
codeFiles: ['show-alloption.vue']
},
{
demoId: 'clear-no-match-value',
name: {
'zh-CN': '自动清除不匹配的值',
'en-US': 'Clear mismatch value'
},
desc: {
'zh-CN':
'<p>通过 <code>clear-no-match-value</code> 属性设置 v-model 的值在 options 中无法找到匹配项的值会被自动清除,默认不清除。 </p>\n',
'en-US':
'<p>By setting the value of the v-model through the <code>clear-no-match-value</code>attribute, if a matching value cannot be found in the options, it will be automatically cleared and will not be cleared by default.</p>\n'
},
codeFiles: ['clear-no-match-value.vue']
},
{
demoId: 'optimization',
name: {
'zh-CN': '虚拟滚动',
'en-US': 'Virtual scrolling'
},
desc: {
'zh-CN':
'<p>通过 <code>optimization</code> 开启大数据虚拟滚动功能。仅配置式(使用 options 属性)时支持。\n多选模式下最大选中项数 <code>multiple-limit</code> 默认值为 20如果选中项比较多建议开启 <code>collapse-tags</code> 进行折叠显示。</p>\n',
'en-US':
'<p>Enable the big data virtual scrolling function through <code>optimization</code>. Supported only when configuring (using the options attribute). In n multiple selection mode, the maximum number of selected items is <code>multiple-limit</code> with a default value of 20. If there are many selected items, it is recommended to turn on <code>collapse-tags</code> for collapsed display. </p>\n'
},
codeFiles: ['optimization.vue']
},
{
demoId: 'option-group',
name: {
'zh-CN': '分组',
'en-US': 'Group'
},
desc: {
'zh-CN':
'<p>使用 <code>tiny-option-group</code> 组件对备选项进行分组。通过 <code>label</code> 属性设置分组名,<code>disabled</code> 属性设置该分组下所有选项为禁用。</p>\n',
'en-US':
'<p>Use the <code>tiny-option-group</code> component to group alternative options. Set the group name through the <code>label</code> attribute, and set all options under the group to disabled through the <code>disabled</code> attribute. </p>\n'
},
codeFiles: ['option-group.vue']
},
{
demoId: 'copy-single',
name: {
'zh-CN': '单选可复制',
'en-US': 'Single choice replicable'
},
desc: {
'zh-CN': '<p>通过 <code>allow-copy</code> 属性设置单选可搜索时,鼠标可滑动选中并复制输入框的内容。</p>\n',
'en-US':
'<p>When setting radio searchable through the <code>allow-copy</code> attribute, the mouse can slide to select and copy the content of the input box. </p>\n'
},
codeFiles: ['copy-single.vue']
},
{
demoId: 'copy-multi',
name: {
'zh-CN': '多选可复制',
'en-US': 'Multiple choices can be copied'
},
desc: {
'zh-CN':
'<p>通过 <code>tag-selectable</code> 属性设置输入框中标签可通过鼠标选择,然后按 Ctrl + C 或右键进行复制。<code>copyable</code> 属性设置启用一键复制所有标签的文本内容并以逗号分隔。</p>\n',
'en-US':
'<p>By setting the <code>tag-selectable</code> attribute in the input box, the label can be selected with the mouse, and then copied by pressing Ctrl+C or right-click <code>copyable</code> attribute settings enable one click copying of all label text content separated by commas.</p>\n'
},
codeFiles: ['copy-multi.vue']
},
{
demoId: 'native-properties',
name: {
'zh-CN': '原生属性',
'en-US': 'Native properties'
},
desc: {
'zh-CN':
'<p>通过 <code>name</code> / <code>placeholder</code> / <code>autocomplete</code> 属性设置下拉组件内置 Input 的原生属性。</p>\n',
'en-US':
'<p>Set the native properties of the built-in Input in the dropdown component through the <code>name</code> / <code>placeholder</code> / <code>autocomplete</code> attribute settings.</p>\n'
},
codeFiles: ['native-properties.vue']
},
{
demoId: 'binding-obj',
name: {
'zh-CN': '绑定值为对象',
'en-US': 'Bind value as object'
},
desc: {
'zh-CN': '<p>通过 <code>value-key</code> 属性设置 value 唯一标识的键名,绑定值可以设置为对象。</p>\n',
'en-US':
'<p>By using the <code>value-key</code> attribute to set the key name uniquely identified by value, the binding value can be set as an object. </p>\n'
},
codeFiles: ['binding-obj.vue']
},
{
demoId: 'no-data-text',
name: {
'zh-CN': '空数据文本',
'en-US': 'Empty data text'
},
desc: {
'zh-CN':
'<p>通过 <code>no-data-text</code> 属性设置选项为空时显示的文本,<code>show-empty-image</code> 属性设置是否显示空数据图片,默认不显示。</p>\n',
'en-US':
'<p>By setting the<code>no-data-text</code> attribute to display text when the option is empty, and by setting the <code>show-empty-image</code> attribute to display empty data images, it is not displayed by default.</p>\n'
},
codeFiles: ['no-data-text.vue']
},
{
demoId: 'manual-focus-blur',
name: {
'zh-CN': '手动聚焦失焦',
'en-US': 'Manual focusing out of focus'
},
desc: {
'zh-CN': '<p>通过 <code>focus()</code> 方法聚焦,<code>blur()</code>方法失焦。</p>\n',
'en-US':
'<p>Focusing is achieved through the <code>focus()</code> method, while the <code>blur()</code> method is out of focus. </p>\n'
},
codeFiles: ['manual-focus-blur.vue']
},
{
demoId: 'automatic-dropdown',
name: {
'zh-CN': '获焦即弹出',
'en-US': 'Eject upon capture of focus'
},
desc: {
'zh-CN': '<p>通过 <code>automatic-dropdown</code> 设置不可搜索的 select 获得焦点并自动弹出选项菜单。</p>\n',
'en-US':
'<p>Set non searchable select to obtain focus and automatically pop up an option menu through <code>automatic-dropdown</code>. </p>\n'
},
codeFiles: ['automatic-dropdown.vue']
},
{
demoId: 'is-drop-inherit-width',
name: {
'zh-CN': '继承宽度',
'en-US': 'Inherit width'
},
desc: {
'zh-CN':
'<p>通过 <code>is-drop-inherit-width</code> 属性设置下拉弹框的宽度是否跟输入框保持一致。默认超出输入框宽度时由内容撑开。</p>\n',
'en-US':
'<p>Set whether the width of the dropdown pop-up box is consistent with the input box through the <code>is-drop-inherit-width</code> attribute. By default, when the width of the input box is exceeded, it is supported by the content. </p>\n'
},
codeFiles: ['is-drop-inherit-width.vue']
},
{
demoId: 'hide-drop',
name: {
'zh-CN': '隐藏下拉',
'en-US': 'Hide drop'
},
desc: {
'zh-CN': '<p>通过 <code>hide-drop</code> 属性设置下拉列表不显示。</p>\n',
'en-US': '<p>Set the drop-down list to not display through the <code>hide-drop</code> attribute.</p>'
},
codeFiles: ['hide-drop.vue']
},
{
demoId: 'filter-mode',
name: {
'zh-CN': '过滤器模式',
'en-US': 'Filter mode'
},
desc: {
'zh-CN':
'<p>通过 <code>shape</code> 属性设置为 <code>filter</code> 切换至过滤器模式。过滤器模式下可传入 label 显示标题tip 显示提示信息clearable 是否显示清除按钮placeholder 显示占位符。</p>\n<p>通过 <code>blank</code> 属性将过滤器背景设置为透明。</p>',
'en-US':
'<p>Set the <code>shape</code> attribute to <code>filter</code> to switch to filter mode. In filter mode, you can transfer the label display title, tip display prompt information, clearable whether to display the clear button, and placeholder display placeholder.</p>\n<p>Set the filter background to transparent with the <code>blank</code> attribute.</p>'
},
codeFiles: ['filter-mode.vue']
},
{
demoId: 'cache-usage',
name: {
'zh-CN': '自动缓存',
'en-US': 'Automatic caching'
},
desc: {
'zh-CN': '<p>通过 <code>cache-op</code> 开启缓存功能,仅配置式生效。</p>\n',
'en-US': '<p>Enable cache function through <code>cache-op</code>, only configuration mode takes effect</p>'
},
codeFiles: ['cache-usage.vue']
},
{
demoId: 'memoize-usage',
name: {
'zh-CN': '手动缓存',
'en-US': 'Manual caching'
},
desc: {
'zh-CN': '<p>使用 tiny-option 组件,则需要手动加入缓存功能。</p>\n',
'en-US': '<p>If using the tiny-option component, you need to manually add caching functionality.<p>'
},
codeFiles: ['memoize-usage.vue']
},
{
demoId: 'slot-default',
name: {
'zh-CN': '选项插槽',
'en-US': 'Option slot'
},
desc: {
'zh-CN': '<p>通过 tiny-option 的 <code>default</code> 插槽自定义选项的 HTML 模板。</p>\n',
'en-US': '<p>HTML template for customizing options through the <code>default</code> slot of tiny-option.</p>'
},
codeFiles: ['slot-default.vue']
},
{
demoId: 'slot-footer',
name: {
'zh-CN': '底部插槽',
'en-US': 'Footer slot'
},
desc: {
'zh-CN': '<p>通过 <code>footer</code> 插槽自定义下拉弹框底部的 HTML 模板。</p>\n',
'en-US':
'<p>Customize the HTML template at the bottom of the dropdown pop-up box through the <code>footer</code> slot.</p>'
},
codeFiles: ['slot-footer.vue']
},
{
demoId: 'slot-empty',
name: {
'zh-CN': '空数据插槽',
'en-US': 'Empty data slot'
},
desc: {
'zh-CN': '<p>通过 <code>empty</code> 插槽自定义没有选项列表时显示的 HTML 模板。</p>\n',
'en-US':
'<p>Customize the HTML template displayed when there is no option list through the <code>empty</code> slot.</p>'
},
codeFiles: ['slot-empty.vue']
},
{
demoId: 'slot-prefix',
name: {
'zh-CN': '输入框前缀插槽',
'en-US': 'Predix slot'
},
desc: {
'zh-CN': '<p>通过 <code>prefix</code> 插槽自定义输入框前缀的 HTML 模板。</p>\n',
'en-US': '<p>Customize the HTML template for the input box prefix through the <code>prefix</code> slot. </p>\n'
},
codeFiles: ['slot-prefix.vue']
},
{
demoId: 'slot-reference',
name: {
'zh-CN': '触发源插槽',
'en-US': 'Reference slot'
},
desc: {
'zh-CN': '<p>通过 <code>reference</code> 插槽自定义触发源的 HTML 模板。</p>\n',
'en-US': '<p>Customize the HTML template of the trigger source through the <code>reference</code> slot.</p>'
},
codeFiles: ['slot-reference.vue']
},
{
demoId: 'slot-panel',
name: {
'zh-CN': '下拉面板插槽',
'en-US': 'Panel slot'
},
desc: {
'zh-CN': '<p>通过 <code>panel</code> 插槽自定义下拉面板的内容。</p>\n',
'en-US': '<p>Customize content of the panel through the <code>panel</code> slot.</p>'
},
codeFiles: ['slot-panel.vue']
},
{
demoId: 'slot-label',
name: {
'zh-CN': '标签插槽',
'en-US': 'Reference slot'
},
desc: {
'zh-CN': '<p>通过 <code>label</code> 插槽自定义多选选中标签的 HTML 模板。</p>\n',
'en-US':
'<p>Customize the HTML template for multiple-choice selected labels through the <code>label</code> slot. </p>'
},
codeFiles: ['slot-label.vue']
},
{
demoId: 'all-text',
name: {
'zh-CN': '自定义全部文本',
'en-US': 'Custom All Text'
},
desc: {
'zh-CN': '当下拉中显示全部时,通过<code>all-text</code> 属性自定义全部的显示文本',
'en-US':
'Use the <code>all-text</code> attribute to customize all displayed text when all is displayed in the drop-down list box.'
},
codeFiles: ['all-text.vue']
},
{
demoId: 'events',
name: {
'zh-CN': '事件',
'en-US': 'Events'
},
desc: {
'zh-CN':
'<div class="tip custom-block"><p class="custom-block-title">事件说明</p>\n<p>change监听 v-model 的值发生变化。</p>\n<p>clear监听单选时点击清空按钮。</p>\n<p>blur监听 input 失去焦点。</p>\n<p>focus监听 input 获得焦点。</p>\n<p>visible-change监听下拉框可见状态的变化。</p>\n<p>remove-tag监听多选移除选中的标签。</p>\n<p>dropdown-click监听下拉图标的点击事件。</p>\n</div>\n',
'en-US':
'<div class="tip custom-block"><p class="custom-block-title"> Event Description</p>\n<p>change: Listen for changes in the value of the v-model.</p><p>clear: When listening to radio selection, click the clear button.</p>\n<p>blur: Listening to input losing focus.</p>\n<p>focus: Listening for input to gain focus.</p>\n<p>visible-change: Listen for changes in the visible status of the dropdown box</p>\n<p>remove-tag: Listen for multiple selections to remove selected tags.</p>\n<p>dropdown-click: Listens to the click event of the drop-down icon.</p>\n</div>\n'
},
codeFiles: ['events.vue']
}
],
features: [
{
id: 'basic',
name: '基本功能',
support: {
value: true
},
description: '支持基本的单选和多选功能,可通过 v-model 进行数据绑定。',
cloud: {
value: true
},
apis: ['v-model', 'multiple'],
demos: ['basic-usage']
},
{
id: 'size',
name: '尺寸',
support: {
value: true
},
description: '支持 medium、small、mini 三种尺寸。',
cloud: {
value: true
},
apis: ['size'],
demos: ['size']
},
{
id: 'disabled',
name: '禁用状态',
support: {
value: true
},
description: '支持禁用整个选择器或单个选项。',
cloud: {
value: true
},
apis: ['disabled'],
demos: ['disabled']
},
{
id: 'clearable',
name: '可清空',
support: {
value: true
},
description: '支持清空已选择的值。',
cloud: {
value: true
},
apis: ['clearable'],
demos: ['clearable']
},
{
id: 'filterable',
name: '可搜索',
support: {
value: true
},
description: '支持输入关键字进行选项搜索。',
cloud: {
value: true
},
apis: ['filterable'],
demos: ['filterable']
}
]
}

View File

@ -0,0 +1,70 @@
<template>
<div id="basic-usage">
<p>场景 1单选</p>
<br />
<tiny-grid-select v-model="value" :grid-op="gridOpSingle" value-field="id" text-field="city"></tiny-grid-select>
<br />
<br />
<p>场景 2多选</p>
<br />
<tiny-grid-select
v-model="value2"
multiple
:grid-op="gridOpMulti"
value-field="id"
text-field="city"
></tiny-grid-select>
</div>
</template>
<script>
import { TinyGridSelect } from '@opentiny/vue'
export default {
components: {
TinyGridSelect
},
data() {
return {
value: '',
value2: [],
gridOpSingle: {
data: [
{ id: '001', area: '华南区', province: '广东省', city: '广州市' },
{ id: '002', area: '华南区', province: '广东省', city: '深圳市' },
{ id: '003', area: '华南区', province: '广东省', city: '珠海市' },
{ id: '004', area: '华南区', province: '广东省', city: '佛山市' },
{ id: '005', area: '华南区', province: '广东省', city: '中山市' }
],
columns: [
{ type: 'radio', title: '' },
{ field: 'area', title: '区域', width: 90 },
{ field: 'province', title: '省份', width: 60 },
{ field: 'city', title: '城市', width: 60 }
]
},
gridOpMulti: {
data: [
{ id: '001', area: '华南区', province: '广东省', city: '广州市' },
{ id: '002', area: '华南区', province: '广东省', city: '深圳市' },
{ id: '003', area: '华南区', province: '广东省', city: '珠海市' },
{ id: '004', area: '华南区', province: '广东省', city: '佛山市' },
{ id: '005', area: '华南区', province: '广东省', city: '中山市' }
],
columns: [
{ type: 'checkbox', title: '' },
{ field: 'area', title: '区域', width: 90 },
{ field: 'province', title: '省份', width: 60 },
{ field: 'city', title: '城市', width: 60 }
]
}
}
}
}
</script>
<style scoped>
#basic-usage {
width: 280px;
}
</style>

View File

@ -0,0 +1,88 @@
<template>
<div id="config">
<p>场景 1单选</p>
<br />
<tiny-grid-select
v-model="valueSingle"
value-field="id"
text-field="city"
:grid-op="gridOpSingle"
:radio-config="radioConfig"
></tiny-grid-select>
<br /><br />
<p>场景 2多选</p>
<br />
<tiny-grid-select
v-model="valueMulti"
multiple
value-field="id"
text-field="city"
:grid-op="gridOpMulti"
:select-config="selectConfig"
></tiny-grid-select>
</div>
</template>
<script>
import { TinyGridSelect } from '@opentiny/vue'
export default {
components: {
TinyGridSelect
},
data() {
return {
valueSingle: '',
valueMulti: [],
gridOpSingle: {
data: [
{ id: '001', area: '华南区', province: '广东省', city: '广州市' },
{ id: '002', area: '华南区', province: '广东省', city: '深圳市' },
{ id: '003', area: '华南区', province: '广东省', city: '珠海市' },
{ id: '004', area: '华南区', province: '广东省', city: '佛山市' },
{ id: '005', area: '华南区', province: '广东省', city: '中山市' }
],
columns: [
{ type: 'radio', title: '' },
{ field: 'area', title: '区域', width: 90 },
{ field: 'province', title: '省份', width: 60 },
{ field: 'city', title: '城市', width: 60 }
]
},
gridOpMulti: {
data: [
{ id: '001', area: '华南区', province: '广东省', city: '广州市' },
{ id: '002', area: '华南区', province: '广东省', city: '深圳市' },
{ id: '003', area: '华南区', province: '广东省', city: '珠海市' },
{ id: '004', area: '华南区', province: '广东省', city: '佛山市' },
{ id: '005', area: '华南区', province: '广东省', city: '中山市' }
],
columns: [
{ type: 'selection', title: '' },
{ field: 'area', title: '区域', width: 90 },
{ field: 'province', title: '省份', width: 60 },
{ field: 'city', title: '城市', width: 60 }
]
},
radioConfig: {
trigger: 'row',
checkMethod({ rowIndex }) {
return rowIndex % 2 === 1
}
},
selectConfig: {
trigger: 'row',
checkMethod({ rowIndex }) {
return rowIndex % 2 === 0
}
}
}
}
}
</script>
<style scoped>
#config {
width: 280px;
}
</style>

View File

@ -0,0 +1,126 @@
<template>
<div id="extra-query-params" class="demo-select">
<div>父选项</div>
<br />
<tiny-grid-select
v-model="parentValue"
multiple
clearable
filterable
remote
text-field="label"
value-field="id"
:grid-op="gridOpParent"
:init-query="loadParents"
:remote-method="remoteParents"
:remote-config="{ autoSearch: true, clearData: true, showIcon: true }"
@change="handleParentChange"
></tiny-grid-select>
<br /><br />
<div>子选项</div>
<br />
<tiny-grid-select
v-model="childValue"
multiple
clearable
filterable
remote
text-field="label"
value-field="id"
:extra-query-params="parentValue"
:grid-op="gridOpChild"
:init-query="loadChildren"
:remote-method="remoteChildren"
:remote-config="{ autoSearch: true, clearData: true, showIcon: true }"
></tiny-grid-select>
</div>
</template>
<script>
import { TinyGridSelect } from '@opentiny/vue'
export default {
components: {
TinyGridSelect
},
created() {
this.parentOptions = [
{ id: '001', label: '指南' },
{ id: '002', label: '组件' }
]
this.childOptions = [
{ id: '001', label: '安装', parent: '001' },
{ id: '002', label: '开发', parent: '001' },
{ id: '004', label: '框架风格', parent: '002' },
{ id: '005', label: '表单组件', parent: '002' },
{ id: '006', label: '数据组件', parent: '002' },
{ id: '007', label: '提示组件', parent: '002' },
{ id: '008', label: '导航组件', parent: '002' },
{ id: '009', label: '其他组件', parent: '002' }
]
},
data() {
return {
parentValue: ['001'],
childValue: ['001'],
gridOpParent: {
data: [],
height: 260,
optimization: {
animat: true,
scrollY: { gt: 20 }
},
columns: [
{ type: 'selection', title: '' },
{ field: 'label', title: '父级' }
]
},
gridOpChild: {
data: [],
height: 260,
optimization: {
animat: true,
scrollY: { gt: 20 }
},
columns: [
{ type: 'selection', title: '' },
{ field: 'label', title: '子级' }
]
}
}
},
methods: {
loadParents() {
return Promise.resolve(this.parentOptions)
},
remoteParents(keyword) {
const list = this.parentOptions.filter((item) => item.label.includes(keyword || ''))
return Promise.resolve(list)
},
loadChildren(value, extraQueryParams) {
return this.filterChildren(extraQueryParams)
},
remoteChildren(keyword, extraQueryParams) {
return this.filterChildren(extraQueryParams, keyword)
},
filterChildren(parentIds, keyword = '') {
const list = this.childOptions
.filter((child) => parentIds.includes(child.parent))
.filter((child) => child.label.includes(keyword || ''))
return new Promise((resolve) => {
setTimeout(() => resolve(list), 300)
})
},
handleParentChange(parents) {
const childIds = this.childOptions.filter((child) => parents.includes(child.parent)).map((child) => child.id)
this.childValue = this.childValue.filter((value) => childIds.includes(value))
}
}
}
</script>
<style scoped>
#extra-query-params {
width: 280px;
}
</style>

View File

@ -0,0 +1,124 @@
<template>
<div id="init-query" class="demo-select">
<div>场景 1远程搜索初始化查询单选</div>
<br />
<tiny-grid-select
ref="select"
v-model="radioValue1"
placeholder="请输入关键词"
clearable
:init-query="initQuery"
:remote-method="remoteMethod"
:remote-config="{ autoSearch: true, clearData: true, showIcon: true }"
remote
filterable
value-field="id"
text-field="city"
:grid-op="gridOpRadio"
></tiny-grid-select>
<br />
<br />
<div>场景 2远程搜索初始化查询多选</div>
<br />
<tiny-grid-select
ref="select"
v-model="radioValue2"
placeholder="请输入关键词"
clearable
:init-query="initQuery"
:remote-method="remoteMethod"
:remote-config="{ autoSearch: true, clearData: true, showIcon: true }"
remote
filterable
value-field="id"
text-field="city"
multiple
:grid-op="gridOpRadio2"
></tiny-grid-select>
</div>
</template>
<script>
import { TinyGridSelect } from '@opentiny/vue'
export default {
components: {
TinyGridSelect
},
created() {
this.allData = Array.from({ length: 10000 }, (item, index) => {
return {
id: '00' + index,
area: '华南区' + index,
province: '广东省' + index,
city: '广州市' + index
}
})
},
data() {
return {
allData: [],
radioValue1: '001',
radioValue2: ['001', '002'],
gridOpRadio: {
data: [],
height: 300,
optimization: {
animat: true,
delayHover: 250,
scrollX: { gt: 20 },
scrollY: { gt: 20 }
},
columns: [
{ type: 'radio', title: '' },
{ field: 'area', title: '区域' },
{ field: 'province', title: '省份' },
{ field: 'city', title: '城市' }
]
},
gridOpRadio2: {
data: [],
height: 300,
optimization: {
animat: true,
delayHover: 250,
scrollX: { gt: 20 },
scrollY: { gt: 20 }
},
columns: [
{ type: 'selection', title: '' },
{ field: 'area', title: '区域' },
{ field: 'province', title: '省份' },
{ field: 'city', title: '城市' }
]
}
}
},
methods: {
initQuery(value) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(this.allData)
}, 500)
})
},
remoteMethod(value) {
let filterData = this.allData.filter((item) => {
return item.city.includes(value)
})
return new Promise((resolve) => {
setTimeout(() => {
resolve(filterData)
}, 500)
})
}
}
}
</script>
<style lang="less" scoped>
#init-query {
width: 280px;
}
</style>

View File

@ -0,0 +1,46 @@
<template>
<div id="radio-bigdata">
<tiny-grid-select v-model="value" text-field="city" value-field="id" :grid-op="gridOp"></tiny-grid-select>
</div>
</template>
<script>
import { TinyGridSelect } from '@opentiny/vue'
export default {
components: {
TinyGridSelect
},
data() {
return {
value: '',
gridOp: {
height: 220,
data: [],
columns: [
{ type: 'radio', width: 50 },
{ field: 'area', title: '区域', width: 120 },
{ field: 'province', title: '省份' },
{ field: 'city', title: '城市' }
]
}
}
},
mounted() {
const data = Array.from({ length: 800 }, (item, index) => ({
id: `ID_${index}`,
area: `华南区 ${index}`,
province: '广东省',
city: `广州市 ${index}`
}))
this.gridOp.data = data
window.gridSelectRadioBigData = data.length
}
}
</script>
<style scoped>
#radio-bigdata {
width: 350px;
}
</style>

View File

@ -0,0 +1,90 @@
<template>
<div id="remote">
<p>场景 1单选</p>
<br />
<tiny-grid-select
v-model="valueSingle"
:grid-op="gridOpSingle"
filterable
remote
:remote-method="remoteMethod"
></tiny-grid-select>
<br /><br />
<p>场景 2多选</p>
<br />
<tiny-grid-select
v-model="valueMultiple"
:grid-op="gridOpMultiple"
multiple
filterable
remote
reserve-keyword
:remote-method="remoteMethod"
></tiny-grid-select>
</div>
</template>
<script>
import { TinyGridSelect } from '@opentiny/vue'
export default {
components: {
TinyGridSelect
},
data() {
return {
valueSingle: '',
valueMultiple: [],
gridOpSingle: {
data: [],
height: 300,
columns: [
{ type: 'radio', title: '' },
{ field: 'area', title: '区域', width: 90 },
{ field: 'province', title: '省份', width: 60 },
{ field: 'city', title: '城市', width: 60 }
]
},
gridOpMultiple: {
data: [],
height: 300,
columns: [
{ type: 'selection', title: '' },
{ field: 'area', title: '区域', width: 90 },
{ field: 'province', title: '省份', width: 60 },
{ field: 'city', title: '城市', width: 60 }
]
},
allData: Array.from({ length: 1000 }, (a, i) => {
return {
value: '00' + i,
province: '省份' + i,
city: '城市' + i,
area: '区域' + i,
label: `${i}-市${i}`
}
})
}
},
methods: {
filter(value) {
return this.allData.filter((item) => item.city.includes(value))
},
remoteMethod(value) {
const filterData = this.filter(value)
return new Promise((resolve) => {
setTimeout(() => {
resolve(filterData)
}, 500)
})
}
}
}
</script>
<style scoped>
#remote {
width: 280px;
}
</style>

View File

@ -0,0 +1,7 @@
---
title: GridSelect 下拉表格选择器
---
# GridSelect 下拉表格选择器
结合了 BaseSelect 和 Grid 组件的选择器,用于从一个下拉表格中选择一个或多个选项。

View File

@ -0,0 +1,8 @@
---
title: GridSelect
---
# GridSelect
A selector that combines the BaseSelect and Grid components to select one or more options from a drop-down table.

View File

@ -0,0 +1,92 @@
export default {
column: '2',
owner: '',
show: true,
cloud: true,
meta: {
experimental: '3.27.0'
},
demos: [
{
demoId: 'basic-usage',
name: {
'zh-CN': '基本下拉表格',
'en-US': 'Basic Usage'
},
desc: {
'zh-CN': '<p>通过 <code>grid-op</code> 设置表格列与数据,<code>v-model</code> 绑定选中值。</p>',
'en-US':
'<p>Configure the internal grid via <code>grid-op</code> and bind the selection with <code>v-model</code>.</p>'
},
codeFiles: ['basic-usage.vue']
},
{
demoId: 'config',
name: {
'zh-CN': '禁用选项',
'en-US': 'Disable option'
},
desc: {
'zh-CN':
'<p>通过 <code>radio-config</code> / <code>select-config</code> 的 <code>checkMethod</code> 控制某些行不可选,并支持 <code>trigger: row</code> 开启整行点击。</p>',
'en-US':
'<p>Use <code>radio-config</code> / <code>select-config</code> with <code>checkMethod</code> to disable rows and enable row-click selection.</p>'
},
codeFiles: ['config.vue']
},
{
demoId: 'remote',
name: {
'zh-CN': '远程搜索',
'en-US': 'Remote'
},
desc: {
'zh-CN':
'<p>配合 <code>remote</code>、<code>remote-method</code> 与 <code>reserve-keyword</code> 实现远程搜索,并分别展示单选与多选场景。</p>',
'en-US':
'<p>Demonstrates remote searching with <code>remote</code>, <code>remote-method</code> and keyword reservation for both single and multiple selection.</p>'
},
codeFiles: ['remote.vue']
},
{
demoId: 'init-query',
name: {
'zh-CN': '表格初始化查询',
'en-US': 'Init query'
},
desc: {
'zh-CN': '<p>利用 <code>init-query</code> 在远程模式下初始化表格数据,并展示单选与多选的默认值回显。</p>',
'en-US':
'<p>Loads remote data at startup via <code>init-query</code> and shows how default values are rendered for both modes.</p>'
},
codeFiles: ['init-query.vue']
},
{
demoId: 'extra-query-params',
name: {
'zh-CN': '表格初始化查询传参',
'en-US': 'Extra query params'
},
desc: {
'zh-CN':
'<p>通过 <code>extra-query-params</code> 将父级选择结果传递给子级下拉表格,实现级联查询与选项联动。</p>',
'en-US':
'<p>Shows how <code>extra-query-params</code> passes parent selections to a child dropdown to build cascading queries.</p>'
},
codeFiles: ['extra-query-params.vue']
},
{
demoId: 'radio-bigdata',
name: {
'zh-CN': '下拉表格大数据',
'en-US': 'Large dataset'
},
desc: {
'zh-CN': '<p>一次性加载数百条记录,结合 Grid 的虚拟滚动仍可保持顺畅的选择体验。</p>',
'en-US':
'<p>Loads hundreds of rows to illustrate how TinyGrids virtual scrolling keeps the dropdown responsive.</p>'
},
codeFiles: ['radio-bigdata.vue']
}
]
}

View File

@ -73,6 +73,19 @@ export const cmpMenus = [
{ name: 'Select', nameCn: '选择器', key: 'select' },
{ name: 'SelectMobile', nameCn: '面板选择器', key: 'select-mobile' },
{ name: 'SelectView', nameCn: '页面选择器', key: 'select-view' },
{
'name': 'BaseSelect',
'nameCn': '基础选择器',
'key': 'base-select'
},
{
name: 'GridSelect',
nameCn: '下拉表格选择器',
key: 'grid-select',
meta: {
experimental: '3.27.0'
}
},
{ name: 'Slider', nameCn: '滑块', key: 'slider' },
{ name: 'SliderButton', nameCn: '滑动按钮组', key: 'slider-button' },
{ name: 'Switch', nameCn: '开关', key: 'switch' },

View File

@ -1,5 +1,16 @@
<template>
<p>场景 1单选</p>
<tiny-grid-select v-model="value" :grid-op="gridOpSingle" value-field="id" text-field="city"></tiny-grid-select>
<br />
<br />
<p>场景 2多选</p>
<tiny-grid-select
v-model="value2"
multiple
:grid-op="gridOpMulti"
value-field="id"
text-field="city"
></tiny-grid-select>
</template>
<script setup>
@ -7,7 +18,7 @@ import { ref, reactive } from 'vue'
import { TinyGridSelect } from '@opentiny/vue'
const value = ref('')
const value2 = ref([])
const gridOpSingle = reactive({
data: [
{ id: '001', area: '华南区', province: '广东省', city: '广州市' },
@ -23,6 +34,21 @@ const gridOpSingle = reactive({
{ field: 'city', title: '城市', width: 60 }
]
})
const gridOpMulti = reactive({
data: [
{ id: '001', area: '华南区', province: '广东省', city: '广州市' },
{ id: '002', area: '华南区', province: '广东省', city: '深圳市' },
{ id: '003', area: '华南区', province: '广东省', city: '珠海市' },
{ id: '004', area: '华南区', province: '广东省', city: '佛山市' },
{ id: '005', area: '华南区', province: '广东省', city: '中山市' }
],
columns: [
{ type: 'selection', title: '' },
{ field: 'area', title: '区域', width: 90 },
{ field: 'province', title: '省份', width: 60 },
{ field: 'city', title: '城市', width: 60 }
]
})
</script>
<style scoped>

View File

@ -1,6 +1,17 @@
<template>
<div id="basic-usage">
<p>场景 1单选</p>
<tiny-grid-select v-model="value" :grid-op="gridOpSingle" value-field="id" text-field="city"></tiny-grid-select>
<br />
<br />
<p>场景 2多选</p>
<tiny-grid-select
v-model="value2"
multiple
:grid-op="gridOpMulti"
value-field="id"
text-field="city"
></tiny-grid-select>
</div>
</template>
@ -14,6 +25,7 @@ export default {
data() {
return {
value: '',
value2: [],
gridOpSingle: {
data: [
{ id: '001', area: '华南区', province: '广东省', city: '广州市' },
@ -28,6 +40,21 @@ export default {
{ field: 'province', title: '省份', width: 60 },
{ field: 'city', title: '城市', width: 60 }
]
},
gridOpMulti: {
data: [
{ id: '001', area: '华南区', province: '广东省', city: '广州市' },
{ id: '002', area: '华南区', province: '广东省', city: '深圳市' },
{ id: '003', area: '华南区', province: '广东省', city: '珠海市' },
{ id: '004', area: '华南区', province: '广东省', city: '佛山市' },
{ id: '005', area: '华南区', province: '广东省', city: '中山市' }
],
columns: [
{ type: 'selection', title: '' },
{ field: 'area', title: '区域', width: 90 },
{ field: 'province', title: '省份', width: 60 },
{ field: 'city', title: '城市', width: 60 }
]
}
}
}