How do you use buefy's b-taginput in a custom component so that it works like v-model, It is only working one way binding?

929 views Asked by At

I'm new to vue and decided to try out buefy for some useful components.

To try and keep my code organized I'm trying to make a custom component using the b-taginput. I have it so that the component loads with the tags in someArrayofTags, but when I'm typing into the b-taginput, it does not add new tags into someArrayofTags. Hence I lose the two-way binding / updating. I would like to know where I am going wrong and how I could adjust this.

I'm not too well versed to understand how they have implemented it, but i do see that it is composed of autocomplete and b-tags https://github.com/buefy/buefy/blob/dev/src/components/taginput/Taginput.vue

I'm trying to use the custom component as such <mytaglist v-model="someArrayofTags"></mytaglist>

I know v-model is just v-bind on value and @input events. My code is below.

<template>
  <b-field label="tag inputs">
    <b-taginput
      :value="value"
      @input=someMethod($event.target.value)
      size="is-small"
      ref="ti"
    >
      <template slot="selected" slot-scope="value">
        <b-tag
          v-for="(tag, index) in value.tags"
          :key="index"
          :type="getType(tag)"
          rounded
          :tabstop="false"
          ellipsis
          closable
          @close="$refs.ti.removeTag(index, $event)"
        >
          {{ tag }}
        </b-tag>
      </template>
    </b-taginput></b-field
  >
</template>

<script>
export default {
  props: ['value'],
  data() {
    return {
        normal: ["wnl","clear"]
    };
  },
  methods: {
    someMethod(tags) {
        alert(tags)
        this.$emit("input", tags)
    },
    getType(tag) {
      if (this.normal.includes(tag)) {
        return "is-danger";
      } else {
        return "is-success";
      }
    },
  },
};
</script>

Thanks

1

There are 1 answers

0
eyedev On

After going through the source for buefy, I found that I could watch and update the values based on a v-model within the new component.

The code below works for me, but if anyone could provide a better solution I will leave it open.

<template>
  <b-field label="tag inputs">
    <b-taginput
      v-model="newValue"
      size="is-large"
      ref="ti"
    >
      <template slot="selected" slot-scope="value">
        <b-tag
          v-for="(tag, index) in value.tags"
          :key="index"
          :type="getType(tag)"
          rounded
          :tabstop="false"
          ellipsis
          closable
          @close="$refs.ti.removeTag(index, $event)"
        >
          {{ tag }}
        </b-tag>
      </template>
    </b-taginput></b-field
  >
</template>

<script>
export default {
  props: ['value'],
  data() {
    return {
        normal: ["wnl","clear","deep & quiet"],
        newValue: this.value
    };
  },
  methods: {
    getType(tag) {
      if (this.normal.includes(tag)) {
        return "is-danger";
      } else {
        return "is-success";
      }
    },
  },
  watch: {
      newValue(value) {
          this.$emit('input', value)
      },
      value(value) {
          this.newValue = value
      }
  }
};
</script>

<style>
</style>