vue.js - 如何在 VueJS 中合并 2 个第三方组件
问题描述
我正在使用表单标签组件bootstrap-vue框架。我想使用带有表单标签的 vue-simple-suggest 组件(来自 npm)来建议与用户查询相关的单词。用户可以从建议中选择多个单词,所选单词将作为药丸保存在表单标签中,如下图所示。
我不知道如何将两个组件合并为一个组件(或更好的方法),以便我可以使用引导程序的 UI 功能和第三方模块的自动建议功能。
我正在学习VueJs,我不知道我应该学习什么来做到这一点?
这是我的代码:
<template>
<div>
<vue-simple-suggest
v-model="chosen"
mode="select"
:list="simpleSuggestionsList"
:filter-by-query="true"
:destyled="false"
>
<b-form-tags
placeholder="Enter Keyword"
size="lg"
tag-variant="success"
tag-pills
remove-on-delete
separator=","
class="my-3"
@input="updateValue"
></b-form-tags>
</vue-simple-suggest>
</div>
</template>
<script>
import VueSimpleSuggest from 'vue-simple-suggest'
import 'vue-simple-suggest/dist/styles.css'
export default {
name: "SeedWordsSuggestions",
data() {
return {
chosen: '',
seedWords: []
}
},
components: {
VueSimpleSuggest
},
methods: {
simpleSuggestionsList() {
return [
'Angular',
'ReactJs',
'VueJs'
]
},
addSelectedWord(e) {
console.log(`addSelectedWord`, e)
},
updateValue(value) {
const pos = value.length
this.seedWords.push(value[pos - 1])
console.log(this.seedWords)
}
}
}
</script>
<style scoped>
</style>
解决方案
以下解决方案将这两个组件组合在一起,以创建一个带有标签药丸的可编辑组合框。
根据 的警告文档vue-simple-suggest
,它的自定义输入组件必须发出input
,focus
和blur
事件,以及有一个value
道具。此外,组件还需要一些未记录的事件:click
、keydown
和keyup
。
b-form-tags
有一个value
道具,但缺少几个必需的事件。但是,您可以访问其内部input
元素以附加您自己的事件处理程序来转发$emit
事件:
export default {
async mounted() {
// wait a couple ticks to ensure the inner contents
// of b-form-tags are fully rendered
await this.$nextTick()
await this.$nextTick()
// <b-form-tags ref="tags">
const input = this.$refs.tags.getInput()
const events = [
'focus',
'blur',
'input',
'click',
'keydown',
'keyup'
]
events.forEach(event =>
input.addEventListener(event, e => this.$refs.tags.$emit(event, e))
)
},
}
仅上述更改将导致vue-simple-suggest
键入时正确出现/消失。但是,在与自动建议交互时,它不会添加/删除标签。该行为可以通过以下功能实现:
- ENTER或TABkeypress 导致悬停的自动建议被添加为标签。如果没有悬停,按键会将第一个自动建议添加为标签。
- 单击自动建议会将自动建议添加为标签。
- BACKSPACE在自动建议标签上删除它。
功能 1 实现:
- 将
ref
s 添加到vue-simple-suggest
andb-form-tags
以便我们以后可以在 JavaScript 中访问组件:
<vue-simple-suggest ref="suggest">
<b-form-tags ref="tags" />
</vue-simple-suggest>
keydown
在 的内部输入上添加一个处理程序b-form-tags
:
export default {
mounted() {
//...
// <b-form-tags ref="tags">
const input = this.$refs.tags.getInput()
input.addEventListener('keydown', e => this.onKeyDown(e))
},
}
- 实现处理程序如下:
export default {
methods: {
async onKeyDown(e) {
if (e.key === 'Enter' || e.key === 'Tab') {
// prevent default so that the auto-suggestion isn't also
// added as plaintext in b-form-tags
e.preventDefault()
// <vue-simple-suggest ref="suggest">
if (this.$refs.suggest.hovered) {
this.$refs.tags.addTag(this.$refs.suggest.hovered)
} else {
const suggestions = await this.$refs.suggest.getSuggestions(e.target.value)
if (suggestions.length > 0) {
this.$refs.tags.addTag(suggestions[0])
} else {
// no match, so clear chosen
this.chosen = ''
}
}
}
}
}
}
- 为防止与我们的处理程序发生冲突,请通过添加prop禁用
b-form-tag
的自动添加标签:ENTERno-add-on-enter
<b-form-tags no-add-on-enter />
功能 2 实现:
- 绑定
suggestion-click
-event 处理程序:
<vue-simple-suggest @suggestion-click="onSuggestionClick">
- 实现处理程序如下:
export default {
methods: {
onSuggestionClick(suggestion) {
this.$refs.tags.addTag(suggestion);
},
}
}
功能 3 实现:
- 将
remove-on-delete
道具添加到b-form-tags
:
<b-form-tags remove-on-delete />
顺便说一句,使用 Vuetify 可能会更好v-combobox
,它支持您尝试合并的两个组件的组合,但我将把它留给您探索:)
推荐阅读
- java - Java 接口实现 - 自动初始化器
- flask - 如何返回 2 个服务器响应,一个是在打开 URL 之后,另一个是在使用烧瓶中的 Restplus 执行 URL 中的请求之后?
- excel - 使用vba过滤excel时如何修复“运行时错误'5'
- angular - 如何在角度材料选择列表中设置默认选择值?
- python-3.x - tkinter 不同的条目具有相同的值
- python-3.x - 如何让 Chrome v74 保存自动下载的 *.cfg 文件而没有保留/丢弃警告?
- angular - 在包含 ngx-bootstrap 手风琴时面临模板解析错误
- mercurial - Does Mercurial push all local branches or only the working branch?
- oracle - 从 FieldA 取值,发送到 db 函数,返回值到 FieldB
- wordpress - How do I get the user_id after login wordpress/woocommerce