借助@riophae/vue-treeselect实现可手动输入的标签多选框
需要实现既可以选择,也可以手动输入作为新标签的功能。(尝试用iView的Select的allow-create=true,但是在首次进入且无下拉项时,会出现选不中的情况,所以自己学习研究了一下)效果图:vue-treeselect是一个多选组件,功能强大界面美观,支持模糊匹配异步加载等,方便封装。官网地址:https://www.vue-treeselect.cn/<template>
·
需要实现既可以选择,也可以手动输入作为新标签的功能,且手动输入的新标签区别展示。
(ps:尝试用iView的Select控件,将allow-create=true后基本能实现,只是在无下拉项数据时,会出现选不中的情况,所以自己学习研究了一下)
效果图是这样的:
采用的组件vue-treeselect, 是一个多选组件,功能强大界面美观,支持模糊匹配异步加载等,方便封装。具体介绍和用法参见官:https://www.vue-treeselect.cn/
需要采用异步搜索模式来加载,设置
- async --设置为异步搜索模式
- load-options --异步搜索事件,用于将结果数据回传到组件中
-
default-options --异步搜索模式中,初始化进入组件时,默认加载搜索字符串为空的搜索条件(如果不设置会出现刚进组件没有输入查询字符串时,下拉选项里无数据)
另外需要修改
-
clear-on-select --在选择下拉项后,清空编辑框中的搜索字符串
-
select --在选择下拉选项后clear-on-select不能清空搜索字符串,手动在选择事件后清空
贴一下代码:
<!--组件部分 (vue文件)-->
<template>
<TreeSelect
ref="tagSelectRef"
v-model="valueSelf"
placeholder="请输入或选择标签"
multiple
async
:default-options="true"
:load-options="loadTagsOptions"
:clear-on-select="clearOnSelect"
@select="selectItem">
<label slot="option-label" slot-scope="{ node }">
<b v-if="node.isNew">{{ node.label }}{{' (新标签)'}}</b>
<span v-else>{{ node.label }}</span>
</label>
</TreeSelect>
</template>
<script>
import TreeSelect, { ASYNC_SEARCH } from "@riophae/vue-treeselect"
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
export default {
name: 'tag-select',
components:{
TreeSelect
},
model:{
prop: 'value',
event: 'change'
},
props: {
//选择的数据项
value:{
type: Array,
default: []
},
//已有的数据项
allTags:{
type: Array,
default: []
},
// 选择后是否清除搜索文字
clearOnSelect:{
type: Boolean,
default: true
},
// 新标签是否区别颜色
isNewTagDifference:{
type: Boolean,
default: true
}
},
data() {
return {
valueSelf: this.value, //自身展示的value
}
},
watch:{
valueSelf(newValue, oldVaule){
if(newValue !== this.value){
this.$emit('change', newValue)
}
}
},
methods:{
//异步加载标签
loadTagsOptions({ action, searchQuery, callback }){
//输入时异步加载
if(action === ASYNC_SEARCH){
let options = []
// 1. 搜索空字符串,则展示全部已有标签
if(searchQuery.trim()===""){
this.allTags.forEach(x=>{
options.push({
id: x,
label: x
})
})
}
//2. 不为空,则生成新标签 + 过滤已有标签
else{
//2.1 过滤已有标签
this.allTags.forEach(x=>{
if(x.indexOf(searchQuery) > -1){
options.push({
id: x,
label: x,
})
}
})
//2.2 新增标签(如果没有完全匹配,则新增)
if(!this.allTags.find(x=>x === searchQuery))
options.push({
id: searchQuery,
label: searchQuery,
isNew: this.isNewTagDifference
})
}
//3. 回传
callback(null, options)
}
},
//选择菜单项后强行清空搜索字符串
selectItem(){
if(this.clearOnSelect)
this.$refs.tagSelectRef.resetSearchQuery();
}
}
}
</script>
在使用时:
<!--引用部分(vue文件)-->
<tag-select
v-model="value"
:allTags="allTags"
/>
另外,在下拉框中始终展示已经选中的自定义项,暂时还没实现。
更多推荐
已为社区贡献1条内容
所有评论(0)