vue.js - 如何在 VueJS 中合并 2 个第三方组件

标签 vue.js vuejs2 vue-component

我正在使用 Form Tags组件 bootstrap-vue框架。我想使用 vue-simple-suggest
带有表单标签的组件(来自 npm),用于建议与用户查询相关的单词。用户可以从建议中选择多个单词,所选单词将保存在表单标签中为如下图所示。

enter image description here

我不知道如何将两个组件合并为一个组件(或更好的方法),以便我可以使用 Bootstrap 的 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>

最佳答案

以下解决方案将这两个组件组合在一起,以创建一个带有标签药丸的可编辑组合框。

根据caveat docs of vue-simple-suggest ,其自定义输入组件必须发出 input , focusblur事件,还有一个 value支柱。此外,组件还需要一些未记录的事件:click , keydown , 和 keyup .
b-form-tags有一个 value Prop ,但缺少几个必需的事件。但是,您可以访问其内部 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 或 TAB 键会导致将悬停的自动建议添加为标签。如果没有悬停,按键会将第一个自动建议添加为标签。
  • 单击自动建议会将自动建议添加为标签。
  • 自动建议标签上的 BACKSPACE 将其删除。

  • 功能 1 实现:
  • 添加 ref转至 vue-simple-suggestb-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 = ''
              }
            }
          }
        }
      }
    }
    
  • 为防止与我们的处理程序发生冲突,请禁用 b-form-tag通过添加 no-add-on-enter 在 ENTER 时自动添加标签 Prop :

  • <b-form-tags no-add-on-enter />
    

    功能 2 实现:
  • 绑定(bind)suggestion-click -事件处理程序:

  • <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 />
    

    full demo

    顺便说一句,使用 Vuetify 的 v-combobox 可能会更好。 ,它支持您尝试合并的两个组件的组合,但我将把它留给您探索:)

    关于vue.js - 如何在 VueJS 中合并 2 个第三方组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60450873/

    相关文章:

    javascript - 如何在VUE中正确使用父组件中的子组件方法?

    javascript - VueJS - 绑定(bind)自定义 Prop 不适用于 b-form 组件

    javascript - Vue.js 中的符号 ' 不适用于我的模板

    authentication - 如何使用 Nuxt.js 将数据存储到本地存储

    javascript - 有没有办法在 vuetify-jsonschema-form vue js 中添加自定义验证?

    javascript - 使用 vue.js 将 `id` 绑定(bind)到 img src url

    vue.js - Vue &lt;input type ="file"> 中@input 和@change 有什么区别?

    vue.js - 将函数作为属性传递给 Vue 组件

    vue.js - Nuxt 生成 fatal error : Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

    vuejs2 - 是否有推荐的方法在使用 VueJS 时为 SEO 目的预加载所有 HTML,而不使用 SSR?