3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

looking back this year for my techAdvent Calendar 2019

Day 16

Vue-multiselect デフォルトラベルを共通で変更する方法

Last updated at Posted at 2019-12-15

概要

Vue.jsで開発するときによく使わせていただいている Vue-multiselect というセレクトボックスのライブラリがあるのですが、
デフォルトのままで使うと
vue-multiselect_1.png
のように、プレースホルダーなどが英語で標準的に設定されてしまっている。
propsnに値を設定すると変えられるので問題はないのですが、複数箇所で使うとその設定を全部にするのが面倒。そして時々忘れてしまう。。。
そこで、ライブラリの表示などを初期設定したコンポーネントを作ればいいと思い、
実際に実装したときのメモ。

環境

  • Vue.js 2.6.10
  • Vue-multiselect 2.1.4

ライブラリ導入

以下のコマンドでインストールできる

npm install vue-multiselect --save

使い方はこんな感じ

<template>
  <div id="app">
    <h1>Vue-multiselect</h1>
    <multiselect v-model="value" :options="options"></multiselect>
  </div>
</template>

<script>
import Multiselect from "vue-multiselect";
import "vue-multiselect/dist/vue-multiselect.min.css";

export default {
  name: "app",
  components: {
    Multiselect
  },
  data() {
    return {
      value: undefined,
      options: ["data1", "data2", "data3"]
    };
  }
};
</script>

<style>
</style>

このままだと、最初の画像のようにプレースホルダーやらが英語のまま出てきてしまう。
Propsで変更できるのだが、使うところ全部で設定するのは面倒。。。

ラベル設定共通化(コンポーネント化)

以下のようなコンポーネントを作って、そのコンポーネントをアプリ内で使うようにすればよい。

customSelect.vue
<template>
  <div>
    <multiselect
      :options="options"
      v-model="selected"
      :multiple="multiple"
      :disabled="disabled"
      :placeholder="_settings.placeholder"
      :selectLabel="_settings.selectLabel"
      :deselectLabel="_settings.deselectLabel"
      :selectedLabel="_settings.selectedLabel"
      @select="select"
      @remove="remove"
    >
      <template slot="noResult">
        <span>{{ _settings.noDataLabel }}</span>
      </template>
      <template slot="noOptions">
        <span>{{ _settings.noDataLabel }}</span>
      </template>
    </multiselect>
  </div>
</template>

<script>
// Library import
import multiselect from "vue-multiselect";
import "vue-multiselect/dist/vue-multiselect.min.css";
const defaultSettings = {
  placeholder: "",
  selectLabel: "",
  deselectLabel: "",
  selectedLabel: "",
  noDataLabel: "対象データがありません"
};

export default {
  props: {
    value: {
      type: null
    },
    options: {
      type: Array,
      default: () => []
    },
    multiple: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean,
      default: false
    },
    settings: {
      type: Object,
      default: undefined
    }
  },
  components: {
    multiselect
  },
  data() {
    return {
      _settings: undefined
    };
  },
  created() {
    this._settings = Object.assign({}, defaultSettings, this.settings);
  },
  computed: {
    selected: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit("input", val);
      }
    }
  },
  methods: {
    select(selectedOption, id) {
      this.$emit("select", selectedOption, id);
    },
    remove(selectedOption, id) {
      this.$emit("remove", selectedOption, id);
    }
  }
};
</script>

<style>
</style>

上記のコンポーネントを呼び出すようにすると、
vue-multiselect_2.png
プレースホルダーのラベルなどがコンポーネントの設定になっている。

このようにしておくと、propsで設定を渡すことで、
呼び出す箇所によってプレースホルダーのラベルを変えられたりなどもできる。

まとめ

部品をコンポーネント化して使うっていうのは、Vue.jsの実装でわりと基本的なことかもしれないが、
必ず使う場面が出てくると思うので、覚えておいて損はないと思う。

あと、このライブラリ( Vue-multiselect )は使いやすく機能も豊富なので、おすすめです。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?